Build System

Build System is designed to build distributions of different operating systems for a set of target devices.

300 Commits   6 Branches   24 Tags   |
Index: build-system-1.2.3/build-config.mk.template
===================================================================
--- build-system-1.2.3/build-config.mk.template	(nonexistent)
+++ build-system-1.2.3/build-config.mk.template	(revision 231)
@@ -0,0 +1,64 @@
+#
+# ENABLE NOARCH, and HOST: {x86_64|i686}-pc-linux-gnu: is always true.
+#
+
+# TARGET: i686-radix-linux-gnu:
+ENABLE_PC32        = true
+
+# TARGET: x86_64-radix-linux-gnu:
+ENABLE_PC64        = true
+
+# TARGET: i686-radix-linux-gnu:
+ENABLE_PC32M       = true
+
+# TARGET: x86_64-radix-linux-gnu:
+ENABLE_PC64M       = true
+
+# TARGET: arm-a1x-eabi:
+ENABLE_CB1N        = true
+
+# TARGET: arm-a2x-eabi:
+ENABLE_CB2N        = true
+ENABLE_CB3N        = true
+
+# TARGET: arm-a1x-linux-gnueabihf:
+ENABLE_CB1X        = true
+
+# TARGET: arm-a2x-linux-gnueabihf:
+ENABLE_CB2X        = true
+ENABLE_CB3X        = true
+
+# TARGET: arm-rk328x-linux-gnueabihf:
+ENABLE_FFRK3288    = true
+
+# TARGET: arm-s8xx-linux-gnueabihf:
+ENABLE_M201        = true
+ENABLE_MXV         = true
+
+# TARGET: aarch64-s9xx-linux-gnu:
+ENABLE_P201        = false
+ENABLE_NEXBOX_A95X = true
+ENABLE_ODROID_C2   = true
+ENABLE_P212        = false
+ENABLE_KHADAS_VIM  = true
+ENABLE_Q201        = false
+ENABLE_ENYBOX_X2   = true
+
+# TARGET: arm-at91sam7s-elf-newlib:
+ENABLE_AT91S       = true
+
+# TARGET: arm-lpc17xx-uclinuxeabi:
+ENABLE_L17UC       = true
+
+# TARGET: arm-imx6-linux-gnueabihf:
+ENABLE_NIT6Q       = true
+
+# TARGETS: arm-omap543x-linux-gnueabihf:
+ENABLE_OMAP5UEVM   = true
+ENABLE_DRA7XXEVM   = true
+
+# TARGETS: mipsel-jz47xx-linux-gnu:
+ENABLE_CI20        = true
+
+# TARGETS: mipsel-p5600-linux-gnu:
+ENABLE_BT1         = true
Index: build-system-1.2.3/constants.mk
===================================================================
--- build-system-1.2.3/constants.mk	(nonexistent)
+++ build-system-1.2.3/constants.mk	(revision 231)
@@ -0,0 +1,689 @@
+# include once
+ifndef CONSTANTS_MK
+
+#######
+####### Constants:
+#######
+
+SYSTEM_VERSION       = 1.2.3
+
+#
+# Distribution:
+#
+DISTRO_NAME          = radix
+
+DISTRO_CAPTION       = Radix
+
+DISTRO_VERSION       = 1.1
+
+BUG_URL              = http://www.radix.pro
+
+
+#
+# Download Sources:
+#
+DOWNLOAD_SERVER      = ftp://ftp.radix.pro
+
+WGET_OPTIONS         = -q -N
+
+TOOLCHAINS_FTP_BASE  = toolchains/x86_64
+TARBALL_SUFFIX       = tar.gz
+
+
+
+CACHED_CC_OUTPUT     = /opt/extra/ccache
+
+TOOLCHAINS_BASE_PATH = /opt/toolchain
+
+
+
+################################################################
+#######
+####### Target Package suffixes & functions:
+#######
+
+# pkgtool/make-package script creates three files:
+#  - package tarball,
+#  - package signature,
+#  - package description.
+# extensions of these files are depend on pkgtool.
+
+pkg_arch_suffix = txz
+pkg_sign_suffix = sha256
+pkg_desc_suffix = txt
+
+#
+# functions:
+#
+sign-name = $(subst .$(pkg_arch_suffix),.$(pkg_sign_suffix),$1)
+desc-name = $(subst .$(pkg_arch_suffix),.$(pkg_desc_suffix),$1)
+pkg-files = $1 $(call sign-name,$1) $(call desc-name,$1)
+
+#
+# usage:
+#
+#   pkg_archive     = $(TARGET_BUILD_DIR)/$(PKG_GROUP)/$(pkg_basename).$(pkg_arch_suffix)
+#   pkg_signature   = $(call sign-name,$(pkg_archive))
+#   pkg_description = $(call desc-name,$(pkg_archive))
+#   products        = $(call pkg-files,$(pkg_archive))
+#
+#   PRODUCT_TARGETS = $(products)
+#   ROOTFS_TARGETS  = $(pkg_archive)
+#
+#   $(pkg_signature)   : $(pkg_archive) ;
+#   $(pkg_description) : $(pkg_archive) ;
+#
+#   $(pkg_archive): '''dependencies'''
+#   	```package creation procedure'''
+
+#######
+####### End of Target Package suffixes & functions.
+#######
+################################################################
+
+
+#
+# NOTE:
+# ====
+#   Hardware names defined by 'HARDWARE_...' variables.
+#   Hardware IDs variable names such as ..._ID_STD should have prefix
+#   which is equal to $(HARDWARE_...) in upper case letters and symbol '-' should be replaced with '_'.
+#   In other words the PREFIX is equal to PREFIX = $(shell echo $(HARDWARE_...) | tr '[a-z-]' '[A-Z_]').
+#
+
+#######
+####### Hardware names and specific attributes:
+#######
+
+####### noarch:
+HARDWARE_NOARCH     = none
+####### Host Build:
+HARDWARE_BUILD      = build
+
+#
+# NOTE:
+# ====
+#   $(HARDWARE)_USE_BUILT_GCC_LIBS - defines that the system is based on GCC Runtime Libraries
+#                                    which built in the platform instead of Libraries which
+#                                    are taken from TOOLCHAIN.
+#
+#   These variables give their values to the global variable named as __USE_BUILT_GCC_LIBS__
+#   and defined in the target-setup.mk file. Variable __USE_BUILT_GCC_LIBS__ can be used in
+#   user's Makefile to deside do we need to wait gcc built or we can to set dependencies from
+#   GNU Libc which based on GCC Runtime Libs taken from toolchain.
+#
+#   [see: app/inputattach/1.4.7/Makefile, for example].
+#
+
+####### x86 Personal Computer:
+HARDWARE_PC32                  = pc32
+###                             |---HW-spec-handy-ruler-----------------------|
+PC32_SPEC                      = Intel x86_32 generic Linux machine
+PC32_USE_BUILT_GCC_LIBS        = yes
+
+####### {x86|x86_64} Personal Computer:
+HARDWARE_PC64                  = pc64
+###                             |---HW-spec-handy-ruler-----------------------|
+PC64_SPEC                      = Intel x86_64 generic Linux machine
+PC64_USE_BUILT_GCC_LIBS        = yes
+
+####### x86 micro Linux:
+HARDWARE_PC32M                 = pc32m
+###                             |---HW-spec-handy-ruler-----------------------|
+PC32M_SPEC                     = x86_32 micro Linux
+PC32M_USE_BUILT_GCC_LIBS       = no
+
+####### x86_64 micro Linux:
+HARDWARE_PC64M                 = pc64m
+###                             |---HW-spec-handy-ruler-----------------------|
+PC64M_SPEC                     = x86_64 micro Linux
+PC64M_USE_BUILT_GCC_LIBS       = no
+
+
+####### A1N newlib devices (cubieboard 1):
+HARDWARE_CB1N                  = cb1n
+###                             |---HW-spec-handy-ruler-----------------------|
+CB1N_SPEC                      = Cubieboard A10 \(Newlib based\)
+CB1N_USE_BUILT_GCC_LIBS        = no
+
+####### A1X devices (cubieboard 1 glibc):
+HARDWARE_CB1X                  = cb1x
+###                             |---HW-spec-handy-ruler-----------------------|
+CB1X_SPEC                      = Cubieboard A10 \(Linux, GNU Libc based\)
+CB1X_USE_BUILT_GCC_LIBS        = yes
+
+####### A2N newlib devices (cubieboard 2):
+HARDWARE_CB2N                  = cb2n
+###                             |---HW-spec-handy-ruler-----------------------|
+CB2N_SPEC                      = Cubieboard A20 \(Newlib based\)
+CB2N_USE_BUILT_GCC_LIBS        = no
+
+####### A2X devices (cubieboard 2 glibc):
+HARDWARE_CB2X                  = cb2x
+###                             |---HW-spec-handy-ruler-----------------------|
+CB2X_SPEC                      = Cubieboard A20 \(Linux, GNU Libc based\)
+CB2X_USE_BUILT_GCC_LIBS        = yes
+
+####### A3N newlib devices (cubieboard 3):
+HARDWARE_CB3N                  = cb3n
+###                             |---HW-spec-handy-ruler-----------------------|
+CB3N_SPEC                      = Cubietrack A20 \(Newlib based\)
+CB3N_USE_BUILT_GCC_LIBS        = no
+
+####### A3X devices (cubieboard 3 glibc):
+HARDWARE_CB3X                  = cb3x
+###                             |---HW-spec-handy-ruler-----------------------|
+CB3X_SPEC                      = Cubietrack A20 \(Linux, GNU Libc based\)
+CB3X_USE_BUILT_GCC_LIBS        = yes
+
+####### AT91SAM7S devices:
+HARDWARE_AT91S                 = at91s
+###                             |---HW-spec-handy-ruler-----------------------|
+AT91S_SPEC                     = Atmel at91sam7s \(Newlib based\)
+AT91S_USE_BUILT_GCC_LIBS       = no
+
+####### LPC17XX devices:
+HARDWARE_L17UC                 = l17uc
+###                             |---HW-spec-handy-ruler-----------------------|
+L17UC_SPEC                     = NXP lpc17xx \(uCLibc based\)
+L17UC_USE_BUILT_GCC_LIBS       = no
+
+####### i.MX6 devices:
+####### -------------
+####### Nitrogen6X [https://boundarydevices.com/product/nitrogen6x-board-imx6-arm-cortex-a9-sbc]:
+HARDWARE_NIT6Q                 = nit6q
+###                             |---HW-spec-handy-ruler-----------------------|
+NIT6Q_SPEC                     = Nitrogen6X Nit6Q \(Linux, GNU Libc based\)
+NIT6Q_USE_BUILT_GCC_LIBS       = yes
+
+####### OMAP543X devices:
+HARDWARE_OMAP5UEVM             = omap5uevm
+###                             |---HW-spec-handy-ruler-----------------------|
+OMAP5UEVM_SPEC                 = Texas OMAP5 uEVM \(Linux, GNU Libc based\)
+OMAP5UEVM_USE_BUILT_GCC_LIBS   = yes
+
+HARDWARE_DRA7XXEVM             = dra7xxevm
+###                             |---HW-spec-handy-ruler-----------------------|
+DRA7XXEVM_SPEC                 = Texas DRA7xx EVM \(Linux, GNU Libc based\)
+DRA7XXEVM_USE_BUILT_GCC_LIBS   = yes
+
+####### JZ47XX devices:
+####### --------------
+####### MIPS Creator CI20 [http://www.elinux.org/MIPS_Creator_CI20]:
+HARDWARE_CI20                  = ci20
+###                             |---HW-spec-handy-ruler-----------------------|
+CI20_SPEC                      = MIPS Creator CI20 \(Linux, GNU Libc based\)
+CI20_USE_BUILT_GCC_LIBS        = yes
+
+####### MIPS Warrior P-class P5600 devices:
+####### ----------------------------------
+####### Baikal T1 based boards [http://baikalelectronics.com/products/168]:
+HARDWARE_BT1                   = bt1
+###                             |---HW-spec-handy-ruler-----------------------|
+BT1_SPEC                       = MIPS Baikal T1 \(Linux, GNU Libc based\)
+BT1_USE_BUILT_GCC_LIBS         = yes
+
+####### RK328X devices:
+####### --------------
+####### Firefly-RK3288 [http://en.t-firefly.com/en/firenow/firefly_rk3288]:
+HARDWARE_FFRK3288              = ffrk3288
+###                             |---HW-spec-handy-ruler-----------------------|
+FFRK3288_SPEC                  = Firefly RK3288 \(Linux, GNU Libc based\)
+FFRK3288_USE_BUILT_GCC_LIBS    = yes
+
+
+####### S8XX devices:
+####### ------------
+
+####### Amlogic S805 meson8b m201:
+HARDWARE_M201                  = m201
+###                             |---HW-spec-handy-ruler-----------------------|
+M201_SPEC                      = Amlogic M201 S805 \(Linux, GNU Libc based\)
+M201_USE_BUILT_GCC_LIBS        = yes
+
+HARDWARE_MXV                   = mxv
+###                             |---HW-spec-handy-ruler-----------------------|
+MXV_SPEC                       = MXV OTT Box S805 \(Linux, GNU Libc based\)
+MXV_USE_BUILT_GCC_LIBS         = yes
+
+
+####### S9XX devices:
+####### ------------
+
+####### Amlogic S905 meson-gxbb p201:
+HARDWARE_P201                  = p201
+###                             |---HW-spec-handy-ruler-----------------------|
+P201_SPEC                      = Amlogic P201 S905 \(Linux, GNU Libc based\)
+P201_USE_BUILT_GCC_LIBS        = yes
+
+HARDWARE_NEXBOX_A95X           = nexbox-a95x
+###                             |---HW-spec-handy-ruler-----------------------|
+NEXBOX_A95X_SPEC               = NEXBOX A95X S905 \(Linux, GNU Libc based\)
+NEXBOX_A95X_USE_BUILT_GCC_LIBS = yes
+
+HARDWARE_ODROID_C2             = odroid-c2
+###                             |---HW-spec-handy-ruler-----------------------|
+ODROID_C2_SPEC                 = ODROID C2 S905 \(Linux, GNU Libc based\)
+ODROID_C2_USE_BUILT_GCC_LIBS   = yes
+
+####### Amlogic S905X meson-gxl p212:
+HARDWARE_P212                  = p212
+###                             |---HW-spec-handy-ruler-----------------------|
+P212_SPEC                      = Amlogic P212 S905X \(Linux, GNU Libc based\)
+P212_USE_BUILT_GCC_LIBS        = yes
+
+HARDWARE_KHADAS_VIM            = khadas-vim
+###                             |---HW-spec-handy-ruler-----------------------|
+KHADAS_VIM_SPEC                = Khadas Vim S905X \(Linux, GNU Libc based\)
+KHADAS_VIM_USE_BUILT_GCC_LIBS  = yes
+
+####### Amlogic S912 meson-gxm q201:
+HARDWARE_Q201                  = q201
+###                             |---HW-spec-handy-ruler-----------------------|
+Q201_SPEC                      = Amlogic Q201 S912 \(Linux, GNU Libc based\)
+Q201_USE_BUILT_GCC_LIBS        = yes
+
+HARDWARE_ENYBOX_X2             = enybox-x2
+###                             |---HW-spec-handy-ruler-----------------------|
+ENYBOX_X2_SPEC                 = Enybox X2 S912 \(Linux, GNU Libc based\)
+ENYBOX_X2_USE_BUILT_GCC_LIBS   = yes
+
+
+
+HW_SPEC                = $(shell echo $($(shell echo $(HARDWARE) | tr '[a-z-]' '[A-Z_]')_SPEC) | sed "s, (.*),,")
+__USE_BUILT_GCC_LIBS__ = $(strip $(shell echo $($(shell echo $(HARDWARE) | tr '[a-z-]' '[A-Z_]')_USE_BUILT_GCC_LIBS)))
+
+
+#######
+####### Hardware IDs:
+#######
+        PC32_ID_STD = 01
+        PC64_ID_STD = 02
+       PC32M_ID_STD = 04
+       PC64M_ID_STD = 08
+        CB1N_ID_STD = 10
+        CB1X_ID_STD = 11
+        CB2N_ID_STD = 20
+        CB2X_ID_STD = 21
+        CB3N_ID_STD = 30
+        CB3X_ID_STD = 31
+       AT91S_ID_STD = 40
+       L17UC_ID_STD = 50
+       NIT6Q_ID_STD = 61
+   OMAP5UEVM_ID_STD = 81
+   DRA7XXEVM_ID_STD = 82
+        CI20_ID_STD = 91
+         BT1_ID_STD = A1
+    FFRK3288_ID_STD = B1
+        M201_ID_STD = C1
+         MXV_ID_STD = C2
+        P201_ID_STD = D1
+ NEXBOX_A95X_ID_STD = D2
+   ODROID_C2_ID_STD = D4
+        P212_ID_STD = E1
+  KHADAS_VIM_ID_STD = E2
+        Q201_ID_STD = F1
+   ENYBOX_X2_ID_STD = F2
+
+
+
+#######
+####### Available Toolchains:
+#######
+
+#
+# NOTE:
+# ====
+#   Toolchain names defined by 'TOOLCHAIN_...' variables.
+#   Configuration variable names such as ..._ARCH, ..._DIR, ..._PATH should have prefix
+#   which is equal to $(TOOLCHAIN_...) in upper case letters and symbol '-' should be replaced with '_'.
+#   In other words the PREFIX is equal to PREFIX = $(shell echo $(TOOLCHAIN_...) | tr '[a-z-]' '[A-Z_]').
+#
+
+#   if variable ..._DEST_SYSROOT equal to "yes" then the switch --sysroot=$(TARGET_DEST_DIR)
+#   is used to say that cross compiler have to usre $(TARGET_DEST_DIR) as system root instead
+#   of compiler default sysroot $(TOOLCHAIN_PATH)/$(TARGET)/sys-root
+#   The '...' as usually shoul be equal to suffix of some 'TOOLCHAIN_...' name.
+
+
+
+# NOARCH
+TOOLCHAIN_NOARCH  = noarch
+
+NOARCH_ARCH       = noarch
+NOARCH_VERSION    =
+NOARCH_DIR        =
+NOARCH_PATH       =
+NOARCH_TARBALL    =
+
+NOARCH_HARDWARE_VARIANTS := $(HARDWARE_NOARCH)
+
+
+# BUILD machine
+TOOLCHAIN_BUILD_MACHINE      = build-machine
+
+BUILD_MACHINE_ARCH           = $(shell $(BUILDSYSTEM)/canonical-build)
+BUILD_MACHINE_VERSION        =
+BUILD_MACHINE_DIR            =
+BUILD_MACHINE_PATH           = /usr
+BUILD_MACHINE_TARBALL        =
+
+BUILD_MACHINE_HARDWARE_VARIANTS := $(HARDWARE_BUILD)
+
+
+
+# ======= I686-GLIBC =========================================================
+
+TOOLCHAIN_I686_GLIBC         = i686-glibc
+
+I686_GLIBC_ARCH              = i686-radix-linux-gnu
+I686_GLIBC_VERSION           = 1.1.4
+I686_GLIBC_DIR               = i686-PC-linux-glibc
+I686_GLIBC_PATH              = $(TOOLCHAINS_BASE_PATH)/$(I686_GLIBC_DIR)
+I686_GLIBC_TARBALL           = $(TOOLCHAINS_FTP_BASE)/$(I686_GLIBC_VERSION)/$(I686_GLIBC_DIR)-$(I686_GLIBC_VERSION).$(TARBALL_SUFFIX)
+
+I686_GLIBC_ARCH_DEFS         = -D__I686_GLIBC__=1
+I686_GLIBC_ARCH_FLAGS        = -m32 -march=i686 -mtune=i686
+
+I686_GLIBC_SYSROOT           = sys-root
+I686_GLIBC_DEST_SYSROOT      = yes
+
+I686_GLIBC_HAS_CHRPATH       = yes
+
+I686_GLIBC_HARDWARE_VARIANTS := $(HARDWARE_PC32) $(HARDWARE_PC32M)
+
+
+
+# ======= X86_64-GLIBC =======================================================
+
+TOOLCHAIN_X86_64_GLIBC       = x86_64-glibc
+
+X86_64_GLIBC_ARCH            = x86_64-radix-linux-gnu
+X86_64_GLIBC_VERSION         = 1.1.4
+X86_64_GLIBC_DIR             = x86_64-PC-linux-glibc
+X86_64_GLIBC_PATH            = $(TOOLCHAINS_BASE_PATH)/$(X86_64_GLIBC_DIR)
+X86_64_GLIBC_TARBALL         = $(TOOLCHAINS_FTP_BASE)/$(X86_64_GLIBC_VERSION)/$(X86_64_GLIBC_DIR)-$(X86_64_GLIBC_VERSION).$(TARBALL_SUFFIX)
+
+X86_64_GLIBC_ARCH_DEFS       = -D__X86_64_GLIBC__=1
+
+X86_64_GLIBC_SYSROOT         = sys-root
+X86_64_GLIBC_DEST_SYSROOT    = yes
+
+X86_64_GLIBC_HAS_CHRPATH     = yes
+
+X86_64_GLIBC_HARDWARE_VARIANTS := $(HARDWARE_PC64) $(HARDWARE_PC64M)
+
+
+
+# ======= A1X-NEWLIB =========================================================
+
+TOOLCHAIN_A1X_NEWLIB         = a1x-newlib
+
+A1X_NEWLIB_ARCH              = arm-a1x-eabi
+A1X_NEWLIB_VERSION           = 1.1.4
+A1X_NEWLIB_DIR               = arm-A1X-eabi-newlib
+A1X_NEWLIB_PATH              = $(TOOLCHAINS_BASE_PATH)/$(A1X_NEWLIB_DIR)
+A1X_NEWLIB_TARBALL           = $(TOOLCHAINS_FTP_BASE)/$(A1X_NEWLIB_VERSION)/$(A1X_NEWLIB_DIR)-$(A1X_NEWLIB_VERSION).$(TARBALL_SUFFIX)
+
+A1X_NEWLIB_ARCH_DEFS         = -D__ALLWINNER_1N__=1
+
+A1X_NEWLIB_HARDWARE_VARIANTS := $(HARDWARE_CB1N)
+
+
+
+# ======= A1X-GLIBC ==========================================================
+
+TOOLCHAIN_A1X_GLIBC          = a1x-glibc
+
+A1X_GLIBC_ARCH               = arm-a1x-linux-gnueabihf
+A1X_GLIBC_VERSION            = 1.1.4
+A1X_GLIBC_DIR                = arm-A1X-linux-glibc
+A1X_GLIBC_PATH               = $(TOOLCHAINS_BASE_PATH)/$(A1X_GLIBC_DIR)
+A1X_GLIBC_TARBALL            = $(TOOLCHAINS_FTP_BASE)/$(A1X_GLIBC_VERSION)/$(A1X_GLIBC_DIR)-$(A1X_GLIBC_VERSION).$(TARBALL_SUFFIX)
+
+A1X_GLIBC_ARCH_DEFS          = -D__ALLWINNER_1X_GLIBC__=1
+A1X_GLIBC_ARCH_FLAGS         = -march=armv7-a -mtune=cortex-a8 -mfloat-abi=hard -mfpu=neon -mabi=aapcs-linux -fomit-frame-pointer
+
+A1X_GLIBC_SYSROOT            = sys-root
+A1X_GLIBC_DEST_SYSROOT       = yes
+
+A1X_GLIBC_HAS_CHRPATH        = yes
+
+A1X_GLIBC_HARDWARE_VARIANTS := $(HARDWARE_CB1X)
+
+
+
+# ======= A2X-NEWLIB =========================================================
+
+TOOLCHAIN_A2X_NEWLIB         = a2x-newlib
+
+A2X_NEWLIB_ARCH              = arm-a2x-eabi
+A2X_NEWLIB_VERSION           = 1.1.4
+A2X_NEWLIB_DIR               = arm-A2X-eabi-newlib
+A2X_NEWLIB_PATH              = $(TOOLCHAINS_BASE_PATH)/$(A2X_NEWLIB_DIR)
+A2X_NEWLIB_TARBALL           = $(TOOLCHAINS_FTP_BASE)/$(A2X_NEWLIB_VERSION)/$(A2X_NEWLIB_DIR)-$(A2X_NEWLIB_VERSION).$(TARBALL_SUFFIX)
+
+A2X_NEWLIB_ARCH_DEFS         = -D__ALLWINNER_2N__=1
+
+A2X_NEWLIB_HARDWARE_VARIANTS := $(HARDWARE_CB2N) $(HARDWARE_CB3N)
+
+
+
+# ======= A2X-GLIBC =========================================================
+
+TOOLCHAIN_A2X_GLIBC          = a2x-glibc
+
+A2X_GLIBC_ARCH               = arm-a2x-linux-gnueabihf
+A2X_GLIBC_VERSION            = 1.1.4
+A2X_GLIBC_DIR                = arm-A2X-linux-glibc
+A2X_GLIBC_PATH               = $(TOOLCHAINS_BASE_PATH)/$(A2X_GLIBC_DIR)
+A2X_GLIBC_TARBALL            = $(TOOLCHAINS_FTP_BASE)/$(A2X_GLIBC_VERSION)/$(A2X_GLIBC_DIR)-$(A2X_GLIBC_VERSION).$(TARBALL_SUFFIX)
+
+A2X_GLIBC_ARCH_DEFS          = -D__ALLWINNER_2X_GLIBC__=1
+A2X_GLIBC_ARCH_FLAGS         = -march=armv7ve -mtune=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 -mabi=aapcs-linux -fomit-frame-pointer
+
+A2X_GLIBC_SYSROOT            = sys-root
+A2X_GLIBC_DEST_SYSROOT       = yes
+
+A2X_GLIBC_HAS_CHRPATH        = yes
+
+A2X_GLIBC_HARDWARE_VARIANTS := $(HARDWARE_CB2X) $(HARDWARE_CB3X)
+
+
+
+# ======= RK328X-GLIBC ======================================================
+
+TOOLCHAIN_RK328X_GLIBC       = rk328x-glibc
+
+RK328X_GLIBC_ARCH            = arm-rk328x-linux-gnueabihf
+RK328X_GLIBC_VERSION         = 1.1.4
+RK328X_GLIBC_DIR             = arm-RK328X-linux-glibc
+RK328X_GLIBC_PATH            = $(TOOLCHAINS_BASE_PATH)/$(RK328X_GLIBC_DIR)
+RK328X_GLIBC_TARBALL         = $(TOOLCHAINS_FTP_BASE)/$(RK328X_GLIBC_VERSION)/$(RK328X_GLIBC_DIR)-$(RK328X_GLIBC_VERSION).$(TARBALL_SUFFIX)
+
+RK328X_GLIBC_ARCH_DEFS       = -D__RK328X_GLIBC__=1
+RK328X_GLIBC_ARCH_FLAGS      = -march=armv7ve -mtune=cortex-a17 -mfloat-abi=hard -mfpu=neon-vfpv4 -mabi=aapcs-linux -fomit-frame-pointer
+
+RK328X_GLIBC_SYSROOT         = sys-root
+RK328X_GLIBC_DEST_SYSROOT    = yes
+
+RK328X_GLIBC_HAS_CHRPATH     = yes
+
+RK328X_GLIBC_HARDWARE_VARIANTS := $(HARDWARE_FFRK3288)
+
+
+
+# ======= S8XX-GLIBC =========================================================
+
+TOOLCHAIN_S8XX_GLIBC         = s8xx-glibc
+
+S8XX_GLIBC_ARCH              = arm-s8xx-linux-gnueabihf
+S8XX_GLIBC_VERSION           = 1.1.4
+S8XX_GLIBC_DIR               = arm-S8XX-linux-glibc
+S8XX_GLIBC_PATH              = $(TOOLCHAINS_BASE_PATH)/$(S8XX_GLIBC_DIR)
+S8XX_GLIBC_TARBALL           = $(TOOLCHAINS_FTP_BASE)/$(S8XX_GLIBC_VERSION)/$(S8XX_GLIBC_DIR)-$(S8XX_GLIBC_VERSION).$(TARBALL_SUFFIX)
+
+S8XX_GLIBC_ARCH_DEFS         = -D__AMLOGIC_S8XX_GLIBC__=1
+S8XX_GLIBC_ARCH_FLAGS        = -march=armv7-a -mtune=cortex-a5 -mfloat-abi=hard -mfpu=neon -mabi=aapcs-linux -fomit-frame-pointer
+
+S8XX_GLIBC_SYSROOT           = sys-root
+S8XX_GLIBC_DEST_SYSROOT      = yes
+
+S8XX_GLIBC_HAS_CHRPATH       = yes
+
+S8XX_GLIBC_HARDWARE_VARIANTS := $(HARDWARE_M201) $(HARDWARE_MXV)
+
+
+
+# ======= S9XX-GLIBC =========================================================
+
+TOOLCHAIN_S9XX_GLIBC         = s9xx-glibc
+
+S9XX_GLIBC_ARCH              = aarch64-s9xx-linux-gnu
+S9XX_GLIBC_VERSION           = 1.1.4
+S9XX_GLIBC_DIR               = aarch64-S9XX-linux-glibc
+S9XX_GLIBC_PATH              = $(TOOLCHAINS_BASE_PATH)/$(S9XX_GLIBC_DIR)
+S9XX_GLIBC_TARBALL           = $(TOOLCHAINS_FTP_BASE)/$(S9XX_GLIBC_VERSION)/$(S9XX_GLIBC_DIR)-$(S9XX_GLIBC_VERSION).$(TARBALL_SUFFIX)
+
+S9XX_GLIBC_ARCH_DEFS         = -D__AMLOGIC_S9XX_GLIBC__=1
+S9XX_GLIBC_ARCH_FLAGS        = -march=armv8-a -mcpu=cortex-a53 -mabi=lp64 -fomit-frame-pointer
+
+S9XX_GLIBC_SYSROOT           = sys-root
+S9XX_GLIBC_DEST_SYSROOT      = yes
+
+S9XX_GLIBC_HAS_CHRPATH       = yes
+
+S9XX_GLIBC_HARDWARE_VARIANTS := $(HARDWARE_P201) $(HARDWARE_NEXBOX_A95X) \
+                                                 $(HARDWARE_ODROID_C2)   \
+                                $(HARDWARE_P212) $(HARDWARE_KHADAS_VIM)  \
+                                $(HARDWARE_Q201) $(HARDWARE_ENYBOX_X2)
+
+
+
+# ======= AT91SAM7S-NEWLIB ===================================================
+
+TOOLCHAIN_AT91SAM7S_NEWLIB   = at91sam7s-newlib
+
+AT91SAM7S_NEWLIB_ARCH        = arm-at91sam7s-eabi
+AT91SAM7S_NEWLIB_VERSION     = 1.1.4
+AT91SAM7S_NEWLIB_DIR         = arm-AT91SAM7S-eabi-newlib
+AT91SAM7S_NEWLIB_PATH        = $(TOOLCHAINS_BASE_PATH)/$(AT91SAM7S_NEWLIB_DIR)
+AT91SAM7S_NEWLIB_TARBALL     = $(TOOLCHAINS_FTP_BASE)/$(AT91SAM7S_NEWLIB_VERSION)/$(AT91SAM7S_NEWLIB_DIR)-$(AT91SAM7S_NEWLIB_VERSION).$(TARBALL_SUFFIX)
+
+AT91SAM7S_NEWLIB_ARCH_DEFS   = -D__AT91SAM7S__=1
+
+AT91SAM7S_NEWLIB_HARDWARE_VARIANTS := $(HARDWARE_AT91S)
+
+
+
+# ======= LPC17XX-UCLIBC =====================================================
+
+TOOLCHAIN_LPC17XX_UCLIBC     = lpc17xx-uclibc
+
+LPC17XX_UCLIBC_ARCH          = arm-lpc17xx-uclinuxeabi
+LPC17XX_UCLIBC_VERSION       = 1.1.4
+LPC17XX_UCLIBC_DIR           = arm-LPC17XX-uclinuxeabi
+LPC17XX_UCLIBC_PATH          = $(TOOLCHAINS_BASE_PATH)/$(LPC17XX_UCLIBC_DIR)
+LPC17XX_UCLIBC_TARBALL       = $(TOOLCHAINS_FTP_BASE)/$(LPC17XX_UCLIBC_VERSION)/$(LPC17XX_UCLIBC_DIR)-$(LPC17XX_UCLIBC_VERSION).$(TARBALL_SUFFIX)
+
+LPC17XX_UCLIBC_ARCH_DEFS     = -D__LPC17XX__=1
+
+LPC17XX_UCLIBC_SYSROOT       = sys-root
+
+LPC17XX_UCLIBC_HARDWARE_VARIANTS := $(HARDWARE_L17UC)
+
+
+
+# ======= IMX6-GLIBC ======================================================
+
+TOOLCHAIN_IMX6_GLIBC         = imx6-glibc
+
+IMX6_GLIBC_ARCH              = arm-imx6-linux-gnueabihf
+IMX6_GLIBC_VERSION           = 1.1.4
+IMX6_GLIBC_DIR               = arm-IMX6-linux-glibc
+IMX6_GLIBC_PATH              = $(TOOLCHAINS_BASE_PATH)/$(IMX6_GLIBC_DIR)
+IMX6_GLIBC_TARBALL           = $(TOOLCHAINS_FTP_BASE)/$(IMX6_GLIBC_VERSION)/$(IMX6_GLIBC_DIR)-$(IMX6_GLIBC_VERSION).$(TARBALL_SUFFIX)
+
+IMX6_GLIBC_ARCH_DEFS         = -D__IMX6_GLIBC__=1
+IMX6_GLIBC_ARCH_FLAGS        = -march=armv7-a -mtune=cortex-a9 -mfloat-abi=hard -mfpu=vfpv3 -mabi=aapcs-linux -fomit-frame-pointer
+
+IMX6_GLIBC_SYSROOT           = sys-root
+IMX6_GLIBC_DEST_SYSROOT      = yes
+
+IMX6_GLIBC_HAS_CHRPATH       = yes
+
+IMX6_GLIBC_HARDWARE_VARIANTS := $(HARDWARE_NIT6Q)
+
+
+
+# ======= OMAP543X-GLIBC =====================================================
+
+TOOLCHAIN_OMAP543X_GLIBC     = omap543x-glibc
+
+OMAP543X_GLIBC_ARCH          = arm-omap543x-linux-gnueabihf
+OMAP543X_GLIBC_VERSION       = 1.1.4
+OMAP543X_GLIBC_DIR           = arm-OMAP543X-linux-glibc
+OMAP543X_GLIBC_PATH          = $(TOOLCHAINS_BASE_PATH)/$(OMAP543X_GLIBC_DIR)
+OMAP543X_GLIBC_TARBALL       = $(TOOLCHAINS_FTP_BASE)/$(OMAP543X_GLIBC_VERSION)/$(OMAP543X_GLIBC_DIR)-$(OMAP543X_GLIBC_VERSION).$(TARBALL_SUFFIX)
+
+OMAP543X_GLIBC_ARCH_DEFS     = -D__OMAP543X_GLIBC__=1
+OMAP543X_GLIBC_ARCH_FLAGS    = -march=armv7-a -mtune=cortex-a15 -mfloat-abi=hard -mfpu=neon-vfpv4 -mabi=aapcs-linux -fomit-frame-pointer
+
+OMAP543X_GLIBC_SYSROOT       = sys-root
+OMAP543X_GLIBC_DEST_SYSROOT  = yes
+
+OMAP543X_GLIBC_HAS_CHRPATH   = yes
+
+OMAP543X_GLIBC_HARDWARE_VARIANTS := $(HARDWARE_OMAP5UEVM) $(HARDWARE_DRA7XXEVM)
+
+
+
+# ======= JZ47XX-GLIBC =======================================================
+
+TOOLCHAIN_JZ47XX_GLIBC       = jz47xx-glibc
+
+JZ47XX_GLIBC_ARCH            = mipsel-jz47xx-linux-gnu
+JZ47XX_GLIBC_VERSION         = 1.1.4
+JZ47XX_GLIBC_DIR             = mipsel-JZ47XX-linux-glibc
+JZ47XX_GLIBC_PATH            = $(TOOLCHAINS_BASE_PATH)/$(JZ47XX_GLIBC_DIR)
+JZ47XX_GLIBC_TARBALL         = $(TOOLCHAINS_FTP_BASE)/$(JZ47XX_GLIBC_VERSION)/$(JZ47XX_GLIBC_DIR)-$(JZ47XX_GLIBC_VERSION).$(TARBALL_SUFFIX)
+
+JZ47XX_GLIBC_ARCH_DEFS       = -D__JZ47XX_GLIBC__=1
+JZ47XX_GLIBC_ARCH_FLAGS      = -march=mips32r2 -mhard-float
+JZ47XX_GLIBC_OPTIMIZATION    = -O2
+
+JZ47XX_GLIBC_SYSROOT         = sys-root
+JZ47XX_GLIBC_DEST_SYSROOT    = yes
+
+JZ47XX_GLIBC_HAS_CHRPATH     = yes
+
+JZ47XX_GLIBC_HARDWARE_VARIANTS := $(HARDWARE_CI20)
+
+
+
+# ======= P5600-GLIBC =======================================================
+
+TOOLCHAIN_P5600_GLIBC        = p5600-glibc
+
+P5600_GLIBC_ARCH             = mipsel-p5600-linux-gnu
+P5600_GLIBC_VERSION          = 1.1.4
+P5600_GLIBC_DIR              = mipsel-P5600-linux-glibc
+P5600_GLIBC_PATH             = $(TOOLCHAINS_BASE_PATH)/$(P5600_GLIBC_DIR)
+P5600_GLIBC_TARBALL          = $(TOOLCHAINS_FTP_BASE)/$(P5600_GLIBC_VERSION)/$(P5600_GLIBC_DIR)-$(P5600_GLIBC_VERSION).$(TARBALL_SUFFIX)
+
+P5600_GLIBC_ARCH_DEFS        = -D__P5600_GLIBC__=1
+P5600_GLIBC_ARCH_FLAGS       = -march=mips32r5 -mtune=p5600 -mhard-float
+P5600_GLIBC_OPTIMIZATION     = -O2
+
+P5600_GLIBC_SYSROOT          = sys-root
+P5600_GLIBC_DEST_SYSROOT     = yes
+
+P5600_GLIBC_HAS_CHRPATH      = yes
+
+P5600_GLIBC_HARDWARE_VARIANTS := $(HARDWARE_BT1)
+
+
+
+
+CONSTANTS_MK=1
+endif
Index: build-system-1.2.3/target-setup.mk
===================================================================
--- build-system-1.2.3/target-setup.mk	(nonexistent)
+++ build-system-1.2.3/target-setup.mk	(revision 231)
@@ -0,0 +1,484 @@
+# include once
+ifndef TARGET_SETUP_MK
+
+
+include $(BUILDSYSTEM)/constants.mk
+
+
+
+################################################################
+# Get hw_id & hw_name by HARDWARE functions:
+#
+# hw_id(), hw_name()
+#
+hw_id = $($(strip $(foreach v, $(filter-out HARDWARE_NAMES HARDWARE_ALL,$(filter HARDWARE_%, $(.VARIABLES))),  \
+                    $(if $(filter $1, $($(v))),                      \
+                      $(addsuffix _ID_STD,$(subst HARDWARE_,,$(v))), \
+                     ))))
+
+
+hw_name = $(strip $(foreach v, $(filter-out HARDWARE_NAMES HARDWARE_ALL,$(filter HARDWARE_%, $(.VARIABLES))), \
+                    $(if $(filter $1, $($(v))),$(subst HARDWARE_,,$(v)),)))
+
+# usage:
+#   HW_ID = $(call hw_id,$(HARDWARE))
+#
+# Get hw_id & hw_name by HARDWARE function.
+################################################################
+
+
+HW_DEFS = $(strip                                                                       \
+            $(foreach v,                                                                \
+              $(filter-out  HARDWARE_ALL HARDWARE_NAMES HARDWARE_NOARCH HARDWARE_BUILD, \
+                $(filter HARDWARE_%, $(.VARIABLES))),                                   \
+                  -D$(subst HARDWARE_,,$(v))=$($(strip $(addsuffix _ID_STD,$(subst HARDWARE_,,$(v)))))))
+
+
+################################################################
+# Is the switch --sysroot=$(TARGET_DEST_DIR) should be used.
+#
+sysroot = $($(strip                                          \
+              $(foreach v, $(filter TOOLCHAIN_%,             \
+                             $(filter-out TOOLCHAIN_ALL      \
+                                          TOOLCHAIN_NAMES    \
+                                          TOOLCHAIN_DIR      \
+                                          TOOLCHAIN_PATH     \
+                                          TOOLCHAIN_VERSION  \
+                                          TOOLCHAIN_INCPATH, \
+                                          $(.VARIABLES))),   \
+                $(if $(filter $1, $($(v))),                  \
+                  $(addsuffix _DEST_SYSROOT,$(subst TOOLCHAIN_,,$(v))), \
+                 ))))
+
+# usage:
+#   enable_sysroot = $(call sysroot,$(TOOLCHAIN))
+#
+# Is the switch --sysroot=$(TARGET_DEST_DIR) should be used.
+################################################################
+
+
+################################################################
+# The name of toolchain sysroot directory (default 'sys-root').
+#
+
+# This is a last directory name in the absolute toolchain
+# sysroot path. If this name is 'sys-root' then absolute
+# toolchain system root is placed in
+#
+#   $(TOOLCHAIN_PATH)/$(TARGET)/sys-root
+#
+# directory. If this function returns "", then toolchain
+# has been built without '--with-sysroot=DIR' switch.
+
+toolchain-sysroot = $($(strip                                          \
+                        $(foreach v, $(filter TOOLCHAIN_%,             \
+                                       $(filter-out TOOLCHAIN_ALL      \
+                                                    TOOLCHAIN_NAMES    \
+                                                    TOOLCHAIN_DIR      \
+                                                    TOOLCHAIN_PATH     \
+                                                    TOOLCHAIN_VERSION  \
+                                                    TOOLCHAIN_INCPATH, \
+                                                    $(.VARIABLES))),   \
+                          $(if $(filter $1, $($(v))),                  \
+                            $(addsuffix _SYSROOT,$(subst TOOLCHAIN_,,$(v))), \
+                           ))))
+
+# usage:
+#   toolchain_sysroot = $(call toolchain-sysroot,$(TOOLCHAIN))
+#
+# The name of toolchain sysroot directory.
+################################################################
+
+
+################################################################
+# Is there 'chrpath' utility in the toolchain.
+#
+has-chrpath = $($(strip                                          \
+                  $(foreach v, $(filter TOOLCHAIN_%,             \
+                                 $(filter-out TOOLCHAIN_ALL      \
+                                              TOOLCHAIN_NAMES    \
+                                              TOOLCHAIN_DIR      \
+                                              TOOLCHAIN_PATH     \
+                                              TOOLCHAIN_VERSION  \
+                                              TOOLCHAIN_INCPATH, \
+                                              $(.VARIABLES))),   \
+                    $(if $(filter $1, $($(v))),                  \
+                      $(addsuffix _HAS_CHRPATH,$(subst TOOLCHAIN_,,$(v))), \
+                     ))))
+
+# usage:
+#   enable_chrpath = $(call has-chrpath,$(TOOLCHAIN))
+#
+# Is there 'chrpath' utility in the toolchain.
+################################################################
+
+
+#######
+####### Setup ccache:
+#######
+
+ifeq ($(NO_CCACHE),)
+CCACHE = /usr/bin/ccache$(space)
+
+ifeq ($(wildcard $(CCACHE)),)
+$(info )
+$(info #######)
+$(info ####### Please install 'ccache' package)
+$(info ####### or disable ccache with "NO_CCACHE=1 make ...")
+$(info #######)
+$(info )
+$(error Error: ccache not found)
+endif
+
+ifeq ($(wildcard $(CACHED_CC_OUTPUT)),)
+$(info )
+$(info #######)
+$(info ####### Please create directory $(CACHED_CC_OUTPUT) for cached compiler output)
+$(info ####### or disable ccache with "NO_CCACHE=1 make ...")
+$(info #######)
+$(info )
+$(error Error: cached compiler output directory doesn't exist)
+endif
+
+export CCACHE_BASEDIR = $(TOP_BUILD_DIR_ABS)
+export CCACHE_DIR     = $(CACHED_CC_OUTPUT)
+export CCACHE_UMASK   = 000
+
+unexport CCACHE_PREFIX
+else
+CCACHE =
+endif
+
+
+
+#######
+####### Setup current toolchain variables:
+#######
+
+ifeq ($(TOOLCHAIN),$(TOOLCHAIN_BUILD_MACHINE))
+TOOLCHAIN_PATH     = $($(shell echo $(TOOLCHAIN) | tr '[a-z-]' '[A-Z_]')_PATH)
+else
+TOOLCHAIN_PATH     = $($(shell echo $(TOOLCHAIN) | tr '[a-z-]' '[A-Z_]')_PATH)/$(TOOLCHAIN_VERSION)
+endif
+
+TOOLCHAIN_TARBALL  = $($(shell echo $(TOOLCHAIN) | tr '[a-z-]' '[A-Z_]')_TARBALL)
+TOOLCHAIN_VERSION  = $($(shell echo $(TOOLCHAIN) | tr '[a-z-]' '[A-Z_]')_VERSION)
+TOOLCHAIN_DIR      = $($(shell echo $(TOOLCHAIN) | tr '[a-z-]' '[A-Z_]')_DIR)
+TARGET             = $($(shell echo $(TOOLCHAIN) | tr '[a-z-]' '[A-Z_]')_ARCH)
+
+ARCH_DEFS         ?= $($(shell echo $(TOOLCHAIN) | tr '[a-z-]' '[A-Z_]')_ARCH_DEFS)
+ARCH_FLAGS        ?= $($(shell echo $(TOOLCHAIN) | tr '[a-z-]' '[A-Z_]')_ARCH_FLAGS)
+ARCH_OPTIMIZATION ?= $($(shell echo $(TOOLCHAIN) | tr '[a-z-]' '[A-Z_]')_OPTIMIZATION)
+
+ifeq ($(filter $(TOOLCHAIN),$(TOOLCHAIN_NOARCH) $(TOOLCHAIN_BUILD_MACHINE)),)
+HW_FLAGS           = -D__HARDWARE__=$(call hw_id,$(HARDWARE)) $(HW_DEFS)
+endif
+
+
+ifeq ($(filter $(TOOLCHAIN), $(TOOLCHAIN_NOARCH) $(TOOLCHAIN_BUILD_MACHINE)),)
+CC                 = $(CCACHE)$(TOOLCHAIN_PATH)/bin/$(TARGET)-gcc
+CXX                = $(CCACHE)$(TOOLCHAIN_PATH)/bin/$(TARGET)-g++
+AS                 = $(TOOLCHAIN_PATH)/bin/$(TARGET)-as
+AR                 = $(TOOLCHAIN_PATH)/bin/$(TARGET)-ar
+LD                 = $(TOOLCHAIN_PATH)/bin/$(TARGET)-ld
+RANLIB             = $(TOOLCHAIN_PATH)/bin/$(TARGET)-ranlib
+SIZE               = $(TOOLCHAIN_PATH)/bin/$(TARGET)-size
+STRIP              = $(TOOLCHAIN_PATH)/bin/$(TARGET)-strip
+OBJCOPY            = $(TOOLCHAIN_PATH)/bin/$(TARGET)-objcopy
+OBJDUMP            = $(TOOLCHAIN_PATH)/bin/$(TARGET)-objdump
+NM                 = $(TOOLCHAIN_PATH)/bin/$(TARGET)-nm
+CROSS_PREFIX       = $(TOOLCHAIN_PATH)/bin/$(TARGET)-
+CHRPATH            = $(strip                                                \
+                       $(if $(filter yes,$(call has-chrpath,$(TOOLCHAIN))), \
+                         $(TOOLCHAIN_PATH)/bin/$(TARGET)-chrpath,           \
+                        ))
+else
+ifeq ($(TOOLCHAIN),$(TOOLCHAIN_BUILD_MACHINE))
+CC                 = $(TOOLCHAIN_PATH)/bin/gcc
+CXX                = $(TOOLCHAIN_PATH)/bin/g++
+AS                 = $(TOOLCHAIN_PATH)/bin/as
+AR                 = $(TOOLCHAIN_PATH)/bin/ar
+LD                 = $(TOOLCHAIN_PATH)/bin/ld
+RANLIB             = $(TOOLCHAIN_PATH)/bin/ranlib
+SIZE               = $(TOOLCHAIN_PATH)/bin/size
+STRIP              = $(TOOLCHAIN_PATH)/bin/strip
+OBJCOPY            = $(TOOLCHAIN_PATH)/bin/objcopy
+OBJDUMP            = $(TOOLCHAIN_PATH)/bin/objdump
+NM                 = $(TOOLCHAIN_PATH)/bin/nm
+CHRPATH            = $(strip                                                \
+                       $(if $(filter yes,$(call has-chrpath,$(TOOLCHAIN))), \
+                         $(TOOLCHAIN_PATH)/bin/chrpath,                     \
+                        ))
+else
+# TOOLCHAIN_NOARCH doesn't need these variables but:
+CC                 = gcc
+CXX                = g++
+AS                 = as
+AR                 = ar
+LD                 = ld
+RANLIB             = ranlib
+SIZE               = size
+STRIP              = strip
+OBJCOPY            = objcopy
+OBJDUMP            = objdump
+NM                 = nm
+endif
+endif
+
+
+#
+# The user may reject the sysroot usage. For this the user have to declare
+# the USE_TARGET_DEST_DIR_SYSROOT variable with value 'no':
+#
+#   USE_TARGET_DEST_DIR_SYSROOT = no
+#
+ifneq ($(USE_TARGET_DEST_DIR_SYSROOT),no)
+USE_TARGET_DEST_DIR_SYSROOT := yes
+endif
+
+
+#######
+####### Build machine triplet:
+#######
+
+ifeq ($(shell echo $(shell ${BUILDSYSTEM}/canonical-build 2> /dev/null)),)
+BUILD = unknown-unknown-unknown-unknown
+$(error Errorr: Unknown BUILD System '${BUILD}')
+else
+BUILD = $(shell echo $(shell ${BUILDSYSTEM}/canonical-build 2> /dev/null))
+endif
+
+
+
+
+
+################################################################
+#######
+####### Include Directories setup Section:
+#######
+
+INCPATH += -I.
+
+TARGET_INCPATH += -I$(TARGET_DEST_DIR)/usr/include
+
+ROOTFS_INCPATH += -I$(ROOTFS_DEST_DIR)/usr/include
+
+#
+# Toolchain include path:
+#
+ifneq ($(call toolchain-sysroot,$(TOOLCHAIN)),)
+TOOLCHAIN_INCPATH += -I$(TOOLCHAIN_PATH)/$(TARGET)/$(call toolchain-sysroot,$(TOOLCHAIN))/usr/include
+endif
+
+#######
+####### End of Include Directories setup Section.
+#######
+################################################################
+
+
+################################################################
+#######
+####### Library directory suffixes for BUILD MACHINE.
+#######
+
+#
+# NOTE: LIBSUFFIX=64 is valid for Slackware64 distro where native libraries are placed in /usr/lib64 directory
+#       for example ubuntu has /usr/lib for x86_64 libraries and /usr/lib32 for x86_32 libraries as well as
+#       our X86_64-glibc toolchain.
+# TODO: Create the canonical-distro script such as $(BULDSYSTEM)/canonical-build we have.
+#
+ifeq ($(TOOLCHAIN),$(TOOLCHAIN_BUILD_MACHINE))
+LIBSUFFIX ?= 64
+endif
+
+#
+# BUILD_CC lib SUFFIX
+#
+BUILD_MULTILIB_X86_32_SUFFIX = $(shell echo $(shell gcc -m32 -print-multi-os-directory) | sed -e 's/\(^.*lib\)\([0-9]*\)/\2/')
+BUILD_MULTILIB_SUFFIX = $(shell echo $(shell gcc -print-multi-os-directory) | sed -e 's/\(^.*lib\)\([0-9]*\)/\2/')
+
+#######
+####### End of Library directory suffixes for BUILD MACHINE.
+#######
+################################################################
+
+
+
+
+
+
+# NOTE:
+# ====
+#
+#   Default optimization is -O3 and defined by 'OPTIMIZATION_FLAGS' variable
+#   in the target-setup.mk. The 'OPTIMIZATION_FLAGS' variable can be overriden
+#   in user Makefile by following definition.
+#
+#   OPTIMIZATION_FLAGS = -O2
+#
+#   However some HW requires specific optimization which should't be overriden
+#   by user. In this case we define toolchain depended variable *_OPTIMIZATION
+#   within constants.mk file. This variable is used to assign a value to the
+#   ARCH_OPTIMIZATION variable, which, in turn, sets the actual (depending on
+#   the current HW) optimization.
+#
+#   This way allow us prioritize the HW specific optimisation. If user
+#   want  to override HW specific optimization then hi can override the
+#   ARCH_OPTIMISATION variable. In this case user have to be sure that
+#   this redefinition doesn't affect other HW:
+#
+#   ifeq ($(HARDWARE),$(HARDWARE_CI20))
+#   ARCH_OPTIMIZATION = -O2
+#   endif
+#
+#   Resume:
+#   ------
+#    - OPTIMIZATION_FLAGS can be overriden only if ARCH_OPTIMIZATION is not set.
+#    - ARCH_OPTIMIZATION can be overriden always and ARCH_OPTIMIZATION has highest priority.
+#    - default optimization is -O3
+#    - the condition (OPTIMIZATION_FLAGS == ARCH_OPTIMIZATION) is always true.
+#
+ifneq ($(ARCH_OPTIMIZATION),)
+OPTIMIZATION_FLAGS         = $(ARCH_OPTIMIZATION)
+else
+OPTIMIZATION_FLAGS        ?= -O3
+ARCH_OPTIMIZATION          = $(OPTIMIZATION_FLAGS)
+endif
+
+
+################################################################
+#######
+####### Common Compiler & Linker flags:
+#######
+
+ifeq ($(USE_TARGET_DEST_DIR_SYSROOT),yes)
+LDFLAGS += -L$(TARGET_DEST_DIR)/lib$(LIBSUFFIX) -L$(TARGET_DEST_DIR)/usr/lib$(LIBSUFFIX)
+endif
+
+# Common CPP/C/C++ flags
+COMMON_FLAGS  = $(INCPATH)
+ifeq ($(USE_TARGET_DEST_DIR_SYSROOT),yes)
+COMMON_FLAGS += $(TARGET_INCPATH)
+endif
+COMMON_FLAGS += -g $(OPTIMIZATION_FLAGS) $(ARCH_FLAGS) $(ARCH_DEFS) $(HW_FLAGS)
+
+
+CFLAGS    += $(COMMON_FLAGS)
+CXXFLAGS  += $(COMMON_FLAGS)
+
+#######
+####### End of Common Compiler & Linker flags.
+#######
+################################################################
+
+
+################################################################
+#######
+####### Default Linkers:
+#######
+
+ifeq ($(call sysroot,$(TOOLCHAIN))_$(USE_TARGET_DEST_DIR_SYSROOT),yes_yes)
+CC_LINKER  = $(CC) --sysroot=$(TARGET_DEST_DIR)
+CXX_LINKER = $(CXX) --sysroot=$(TARGET_DEST_DIR)
+else
+CC_LINKER  = $(CC)
+CXX_LINKER = $(CXX)
+endif
+
+#######
+####### Default Linkers.
+#######
+################################################################
+
+
+
+
+################################################################
+#######
+####### Development environment:
+#######
+
+
+BUILD_ENVIRONMENT  = PATH=$(PATH):$(TOOLCHAIN_PATH)/bin
+
+ifeq ($(call sysroot,$(TOOLCHAIN))_$(USE_TARGET_DEST_DIR_SYSROOT),yes_yes)
+BUILD_ENVIRONMENT += CC="$(CC) --sysroot=$(TARGET_DEST_DIR)"
+BUILD_ENVIRONMENT += CXX="$(CXX) --sysroot=$(TARGET_DEST_DIR)"
+BUILD_ENVIRONMENT += LD="$(LD) --sysroot=$(TARGET_DEST_DIR)"
+else
+BUILD_ENVIRONMENT += CC="$(CC)" CXX="$(CXX)" LD="$(LD)"
+endif
+
+BUILD_ENVIRONMENT += AS="$(AS)" AR="$(AR)" RANLIB="$(RANLIB)" SIZE="$(SIZE)" STRIP="$(STRIP)" OBJCOPY="$(OBJCOPY)" NM="$(NM)"
+BUILD_ENVIRONMENT += BUILD_CC="$(BUILD_CC)" BUILD_CXX="$(BUILD_CXX)" BUILD_AS="$(BUILD_AS)" BUILD_AR="$(BUILD_AR)" BUILD_LD="$(BUILD_LD)" BUILD_RANLIB="$(BUILD_RANLIB)" BUILD_SIZE="$(BUILD_SIZE)" BUILD_STRIP="$(BUILD_STRIP)" BUILD_OBJCOPY="$(BUILD_OBJCOPY)" BUILD_NM="$(BUILD_NM)"
+BUILD_ENVIRONMENT += CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" CPPFLAGS="$(CPPFLAGS)"
+BUILD_ENVIRONMENT += LDFLAGS="$(LDFLAGS)"
+
+#
+#  PKG_CONFIG_PATH - directories to add to pkg-config's search path
+#
+PKG_CONFIG_PATH    = $(TARGET_DEST_DIR)/usr/lib$(LIBSUFFIX)/pkgconfig:$(TARGET_DEST_DIR)/usr/share/pkgconfig
+PKG_CONFIG_LIBDIR  = $(TARGET_DEST_DIR)/usr/lib$(LIBSUFFIX)/pkgconfig:$(TARGET_DEST_DIR)/usr/share/pkgconfig
+
+BUILD_ENVIRONMENT += PKG_CONFIG_PATH="$(PKG_CONFIG_PATH)"
+BUILD_ENVIRONMENT += PKG_CONFIG_LIBDIR="$(PKG_CONFIG_LIBDIR)"
+
+#######
+####### Development environment.
+#######
+################################################################
+
+
+
+################################################################
+#######
+####### Multilib Support:
+#######
+
+
+#######
+####### x86_32:
+#######
+
+####### Multilib directory suffixes for TARGETs:
+
+ifeq ($(TOOLCHAIN),$(TOOLCHAIN_X86_64_GLIBC))
+MULTILIB_X86_32_SUFFIX ?= 32
+endif
+
+ifeq ($(HARDWARE),$(HARDWARE_PC64))
+ifeq ($(CREATE_X86_32_PACKAGE),true)
+
+CC               += -m32
+CXX              += -m32
+
+ifeq ($(USE_TARGET_DEST_DIR_SYSROOT),yes)
+LDFLAGS           = -L$(TARGET_DEST_DIR)/lib$(MULTILIB_X86_32_SUFFIX)
+LDFLAGS          += -L$(TARGET_DEST_DIR)/usr/lib$(MULTILIB_X86_32_SUFFIX)
+endif
+
+PKG_CONFIG_PATH   = $(TARGET_DEST_DIR)/usr/lib$(MULTILIB_X86_32_SUFFIX)/pkgconfig:$(TARGET_DEST_DIR)/usr/share/pkgconfig
+PKG_CONFIG_LIBDIR = $(TARGET_DEST_DIR)/usr/lib$(MULTILIB_X86_32_SUFFIX)/pkgconfig:$(TARGET_DEST_DIR)/usr/share/pkgconfig
+
+ARCH_FLAGS        = -m32 -march=i686 -mtune=i686
+
+TARGET32          = $(shell echo $(TARGET) | sed 's/x86_64/i686/')
+
+endif
+endif
+
+
+
+
+#######
+####### End of Multilib Support.
+#######
+################################################################
+
+
+
+
+
+
+TARGET_SETUP_MK=1
+endif
Index: build-system-1.2.3/3pp/dialog/1.2-20140112/Makefile
===================================================================
--- build-system-1.2.3/3pp/dialog/1.2-20140112/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/dialog/1.2-20140112/Makefile	(revision 231)
@@ -0,0 +1,53 @@
+
+COMPONENT_TARGETS = $(HARDWARE_BUILD)
+
+include ../../../../build-system/constants.mk
+
+SOURCE_REQUIRES = build-system/3pp/sources/packages/dialog
+
+
+# ======= __END_OF_REQUIRES__ =======
+
+
+tar_gz_archive  = $(BUILDSYSTEM)/3pp/sources/packages/dialog/dialog-1.2-20140112.tgz
+src_dir         = dialog-1.2-20140112
+build_dir       = $(TARGET_BUILD_DIR)/built
+
+src_done        = $(TARGET_BUILD_DIR)/.source-done
+SRC_DIR         = $(TARGET_BUILD_DIR)/dialog-1.2-20140112
+SRC_ARCHIVE     = $(tar_gz_archive)
+
+PATCHES = PATCHES
+
+build_target    = $(TARGET_BUILD_DIR)/.built
+install_target  = $(TARGET_BUILD_DIR)/.installed
+
+environment     =
+extra_configure_switches  = --libdir=/usr/lib
+extra_configure_switches += --mandir=/usr/share/man
+extra_configure_switches += --without-shared
+extra_configure_switches += --with-ncursesw
+
+BUILD_TARGETS = $(install_target)
+
+include ../../../../build-system/core.mk
+
+$(src_done): $(SRC_ARCHIVE) $(PATCHES_DEP)
+	$(UNPACK_SRC_ARCHIVE)
+	$(APPLY_PATCHES)
+	@touch $@
+
+$(build_target): $(src_done)
+	@mkdir -p $(build_dir)
+	@cd $(build_dir) && $(environment) ../$(src_dir)/configure \
+	  --prefix=/ \
+	  $(extra_configure_switches)
+	@$(environment) $(MAKE) -C $(build_dir) all
+	@touch $@
+
+$(install_target): $(build_target)
+	@echo -e "\n======= Installing DIALOG binary =======\n"
+	@mkdir -p $(BUILDSYSTEM)/sbin && \
+	  cp -a $(build_dir)/dialog $(BUILDSYSTEM)/sbin && \
+	  echo "DIALOG := $(BUILDSYSTEM)/sbin/dialog" >> $(BUILDSYSTEM)/sbin/.config
+	@touch $@
Index: build-system-1.2.3/3pp/dialog/1.2-20140112/PATCHES
===================================================================
--- build-system-1.2.3/3pp/dialog/1.2-20140112/PATCHES	(nonexistent)
+++ build-system-1.2.3/3pp/dialog/1.2-20140112/PATCHES	(revision 231)
@@ -0,0 +1,2 @@
+
+../../sources/packages/dialog/patches/dialog-1.2-20140112.patch -p0
Index: build-system-1.2.3/3pp/jsmin/0.0.1/Makefile
===================================================================
--- build-system-1.2.3/3pp/jsmin/0.0.1/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/jsmin/0.0.1/Makefile	(revision 231)
@@ -0,0 +1,49 @@
+
+COMPONENT_TARGETS = $(HARDWARE_BUILD)
+
+include ../../../../build-system/constants.mk
+
+SOURCE_REQUIRES = build-system/3pp/sources/packages/jsmin
+
+
+# ======= __END_OF_REQUIRES__ =======
+
+
+tar_gz_archive  = $(BUILDSYSTEM)/3pp/sources/packages/jsmin/jsmin-0.0.1.tar.gz
+src_dir         = jsmin-0.0.1
+build_dir       = $(TARGET_BUILD_DIR)/built
+
+src_done        = $(TARGET_BUILD_DIR)/.source-done
+SRC_DIR         = $(TARGET_BUILD_DIR)/jsmin-0.0.1
+SRC_ARCHIVE     = $(tar_gz_archive)
+
+build_target    = $(TARGET_BUILD_DIR)/.built
+install_target  = $(TARGET_BUILD_DIR)/.installed
+
+environment     =
+
+extra_configure_switches  = --program-prefix=''
+extra_configure_switches += --program-suffix=''
+
+BUILD_TARGETS = $(install_target)
+
+include ../../../../build-system/core.mk
+
+$(src_done): $(SRC_ARCHIVE) $(PATCHES_DEP)
+	$(UNPACK_SRC_ARCHIVE)
+	@touch $@
+
+$(build_target): $(src_done)
+	@mkdir -p $(build_dir)
+	@cd $(build_dir) && $(environment) ../$(src_dir)/configure \
+	  --prefix=/usr \
+	  $(extra_configure_switches)
+	@$(environment) $(MAKE) -C $(build_dir) all
+	@touch $@
+
+$(install_target): $(build_target)
+	@echo -e "\n======= Installing JSMIN binary =======\n"
+	@mkdir -p $(BUILDSYSTEM)/sbin && \
+	  cp -a $(build_dir)/src/jsmin     $(BUILDSYSTEM)/sbin && \
+	  echo "JSMIN := $(BUILDSYSTEM)/sbin/jsmin" >> $(BUILDSYSTEM)/sbin/.config
+	@touch $@
Index: build-system-1.2.3/3pp/pseudo/1.8.1/Makefile
===================================================================
--- build-system-1.2.3/3pp/pseudo/1.8.1/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/pseudo/1.8.1/Makefile	(revision 231)
@@ -0,0 +1,69 @@
+
+COMPONENT_TARGETS = $(HARDWARE_BUILD)
+
+include ../../../../build-system/constants.mk
+
+SOURCE_REQUIRES = build-system/3pp/sources/packages/pseudo
+
+REQUIRES        = build-system/3pp/sqlite/3.12.2.0
+
+# ======= __END_OF_REQUIRES__ =======
+
+version         = 1.8.1
+tar_xz_archive  = $(BUILDSYSTEM)/3pp/sources/packages/pseudo/pseudo-$(version).tar.xz
+SRC_ARCHIVE     = $(tar_xz_archive)
+SRC_DIR         = $(TARGET_BUILD_DIR)/pseudo-$(version)
+
+src_done        = $(TARGET_BUILD_DIR)/.source-done
+src_dir_name    = pseudo-$(version)
+build_dir       = $(TARGET_BUILD_DIR)/built
+
+PATCHES = PATCHES
+
+build_target    = $(TARGET_BUILD_DIR)/.built
+install_target  = $(TARGET_BUILD_DIR)/.installed
+
+pseudo_wrapper    = $(CURDIR)/scripts/pseudo.pl
+pseudolog_wrapper = $(CURDIR)/scripts/pseudolog
+
+environment     =
+extra_configure_switches += --libdir=/usr/lib
+extra_configure_switches += --with-sqlite=$(BUILDSYSTEM)/usr
+extra_configure_switches += --bits=64
+extra_configure_switches += --enable-memory-db
+extra_configure_switches += --without-rpath
+extra_configure_switches += --cflags='-m64'
+
+
+BUILD_TARGETS = $(install_target)
+
+include ../../../../build-system/core.mk
+
+$(src_done): $(SRC_ARCHIVE) $(PATCHES_DEP)
+	$(UNPACK_SRC_ARCHIVE)
+	$(APPLY_PATCHES)
+	@touch $@
+
+$(build_target): $(src_done)
+	@( cd $(SRC_DIR) ; \
+	   $(environment) ./configure --prefix=/usr $(extra_configure_switches) ; \
+	   $(environment) $(MAKE) LOCALSTATE=../var/pseudo ; \
+	 )
+	@touch $@
+
+$(install_target): $(build_target)
+	@echo -e "\n======= Installing PSEUDO binary =======\n"
+	@( cd $(SRC_DIR) ; \
+	   $(MAKE) install LOCALSTATE=../var/pseudo DESTDIR=$(BUILDSYSTEM) ; \
+	   mkdir -p $(BUILDSYSTEM)/usr/share/man/man1 ; \
+	   cp pseudo.1 pseudolog.1 $(BUILDSYSTEM)/usr/share/man/man1 ; \
+	 )
+	@echo -e "\n======= Installing PSEUDO and PSEUDOLOG wrappers =======\n"
+	@mkdir -p $(BUILDSYSTEM)/sbin && \
+	  cp -a $(pseudo_wrapper) $(BUILDSYSTEM)/sbin/pseudo && \
+	  chmod a+x $(BUILDSYSTEM)/sbin/pseudo               && \
+	  echo "PSEUDO := $(BUILDSYSTEM)/sbin/pseudo" >> $(BUILDSYSTEM)/sbin/.config
+	@cp -a $(pseudolog_wrapper) $(BUILDSYSTEM)/sbin/pseudolog && \
+	 chmod a+x $(BUILDSYSTEM)/sbin/pseudolog                  && \
+	 echo "PSEUDOLOG := $(BUILDSYSTEM)/sbin/pseudolog" >> $(BUILDSYSTEM)/sbin/.config
+	@touch $@
Index: build-system-1.2.3/3pp/pseudo/1.8.1/scripts/pseudo.pl
===================================================================
--- build-system-1.2.3/3pp/pseudo/1.8.1/scripts/pseudo.pl	(nonexistent)
+++ build-system-1.2.3/3pp/pseudo/1.8.1/scripts/pseudo.pl	(revision 231)
@@ -0,0 +1,85 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings FATAL => 'all';
+
+use File::Basename;
+use File::Spec;
+
+my $program = basename( $0 );
+my ($pseudo_prefix, $enable_op_logging, $shell, @options, $opts, $commands, $cmd);
+
+sub usage
+{
+  print <<EOF;
+
+Usage: $program <shell> <shell_options> <command_string>
+Where:
+          shell - command intepreter {sh,/bin/sh,/bin/bash};
+  shell_options - shell options list,  last should be '-c' ;
+ command_string - command string to be interpreted by shell.
+
+EOF
+  exit 1;
+}
+
+
+my $path = File::Spec->rel2abs(dirname( __FILE__ ));
+my $enable_pseudo_logging = $ENV{'ENABLE_PSEUDO_LOGGING'};
+
+$pseudo_prefix = $path . "/../usr" ;
+$enable_op_logging = "";
+
+if( defined( $enable_pseudo_logging ) && $enable_pseudo_logging eq "yes" )
+{
+  $enable_op_logging = "-l";
+}
+
+
+# Parse the command line options:
+#
+$shell = shift;
+foreach ( @ARGV )
+{
+  if( /--help/ ) { usage; }
+  else           { push @options, $_; }
+}
+$commands = pop @options;
+
+# Check options:
+#
+if( !defined($shell) || !defined($commands) ) { usage; }
+
+$opts = "";
+if( @options )
+{
+  foreach ( @options )
+  {
+    if( substr( $_, 0, 1) ne "-" ) { usage; }
+    $opts = $opts . " $_";
+  }
+}
+else
+{
+  usage;
+}
+
+
+# add backslash before each '"':
+#
+$commands =~ s/([\"])/\\$1/xg;
+
+# remove extra horizontal spaces:
+#
+$commands =~ s/\h+/ /g;
+
+$cmd  = $pseudo_prefix . "/bin/pseudo";
+$cmd .=    " " . $enable_op_logging;
+$cmd .= " -P " . $pseudo_prefix ;
+$cmd .=    " " . $shell . $opts ;
+$cmd .=   ' "' . $commands . '"';
+
+system( $cmd );
+
+if( $? == 0 ) { exit 0; }
+else          { exit 1; }
Index: build-system-1.2.3/3pp/pseudo/1.8.1/scripts/pseudo.sh
===================================================================
--- build-system-1.2.3/3pp/pseudo/1.8.1/scripts/pseudo.sh	(nonexistent)
+++ build-system-1.2.3/3pp/pseudo/1.8.1/scripts/pseudo.sh	(revision 231)
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+program=$0
+pseudo_prefix=$(cd $(dirname $program)/.. ; pwd -P)/usr
+
+shell=$1 ; shift ; option=$1 ; shift
+
+enable_op_logging=
+if [ "$ENABLE_PSEUDO_LOGGING" == "yes" ] ; then
+  enable_op_logging=-l
+fi
+
+#
+# remove extra spaces
+#
+args=`echo "${@}" | sed 's/ \{1,\}/ /g'`
+
+${pseudo_prefix}/bin/pseudo ${enable_op_logging} -P ${pseudo_prefix} $shell $option "$args"
Index: build-system-1.2.3/3pp/pseudo/1.8.1/scripts/pseudolog
===================================================================
--- build-system-1.2.3/3pp/pseudo/1.8.1/scripts/pseudolog	(nonexistent)
+++ build-system-1.2.3/3pp/pseudo/1.8.1/scripts/pseudolog	(revision 231)
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+program=$0
+pseudo_prefix=$(cd $(dirname $program)/.. ; pwd -P)/usr
+
+args=""
+for arg in "$@" ; do
+  if [ "`echo "$arg" | wc -w`" -gt "1" ] ; then
+    args="$args \"$arg\""
+  else
+    args="$args $arg"
+  fi
+done
+
+PSEUDO_PREFIX=${pseudo_prefix} ${pseudo_prefix}/bin/pseudolog -P ${pseudo_prefix} $args
Index: build-system-1.2.3/3pp/pseudo/1.8.1/PATCHES
===================================================================
Index: build-system-1.2.3/3pp/pseudo/1.7.4/Makefile
===================================================================
--- build-system-1.2.3/3pp/pseudo/1.7.4/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/pseudo/1.7.4/Makefile	(revision 231)
@@ -0,0 +1,69 @@
+
+COMPONENT_TARGETS = $(HARDWARE_BUILD)
+
+include ../../../../build-system/constants.mk
+
+SOURCE_REQUIRES = build-system/3pp/sources/packages/pseudo
+
+REQUIRES        = build-system/3pp/sqlite/3.12.2.0
+
+# ======= __END_OF_REQUIRES__ =======
+
+version         = 1.7.4
+tar_xz_archive  = $(BUILDSYSTEM)/3pp/sources/packages/pseudo/pseudo-$(version).tar.xz
+SRC_ARCHIVE     = $(tar_xz_archive)
+SRC_DIR         = $(TARGET_BUILD_DIR)/pseudo-$(version)
+
+src_done        = $(TARGET_BUILD_DIR)/.source-done
+src_dir_name    = pseudo-$(version)
+build_dir       = $(TARGET_BUILD_DIR)/built
+
+PATCHES = PATCHES
+
+build_target    = $(TARGET_BUILD_DIR)/.built
+install_target  = $(TARGET_BUILD_DIR)/.installed
+
+pseudo_wrapper    = $(CURDIR)/scripts/pseudo
+pseudolog_wrapper = $(CURDIR)/scripts/pseudolog
+
+environment     =
+extra_configure_switches += --libdir=/usr/lib
+extra_configure_switches += --with-sqlite=$(BUILDSYSTEM)/usr
+extra_configure_switches += --bits=64
+extra_configure_switches += --enable-memory-db
+extra_configure_switches += --without-rpath
+extra_configure_switches += --cflags='-m64'
+
+
+BUILD_TARGETS = $(install_target)
+
+include ../../../../build-system/core.mk
+
+$(src_done): $(SRC_ARCHIVE) $(PATCHES_DEP)
+	$(UNPACK_SRC_ARCHIVE)
+	$(APPLY_PATCHES)
+	@touch $@
+
+$(build_target): $(src_done)
+	@( cd $(SRC_DIR) ; \
+	   $(environment) ./configure --prefix=/usr $(extra_configure_switches) ; \
+	   $(environment) $(MAKE) LOCALSTATE=../var/pseudo ; \
+	 )
+	@touch $@
+
+$(install_target): $(build_target)
+	@echo -e "\n======= Installing PSEUDO binary =======\n"
+	@( cd $(SRC_DIR) ; \
+	   $(MAKE) install LOCALSTATE=../var/pseudo DESTDIR=$(BUILDSYSTEM) ; \
+	   mkdir -p $(BUILDSYSTEM)/usr/share/man/man1 ; \
+	   cp pseudo.1 pseudolog.1 $(BUILDSYSTEM)/usr/share/man/man1 ; \
+	 )
+	@echo -e "\n======= Installing PSEUDO and PSEUDOLOG wrappers =======\n"
+	@mkdir -p $(BUILDSYSTEM)/sbin && \
+	  cp -a $(pseudo_wrapper) $(BUILDSYSTEM)/sbin/pseudo && \
+	  chmod a+x $(BUILDSYSTEM)/sbin/pseudo               && \
+	  echo "PSEUDO := $(BUILDSYSTEM)/sbin/pseudo" >> $(BUILDSYSTEM)/sbin/.config
+	@cp -a $(pseudolog_wrapper) $(BUILDSYSTEM)/sbin/pseudolog && \
+	 chmod a+x $(BUILDSYSTEM)/sbin/pseudolog                  && \
+	 echo "PSEUDOLOG := $(BUILDSYSTEM)/sbin/pseudolog" >> $(BUILDSYSTEM)/sbin/.config
+	@touch $@
Index: build-system-1.2.3/3pp/pseudo/1.7.4/PATCHES
===================================================================
Index: build-system-1.2.3/3pp/pseudo/1.7.4/scripts/pseudo
===================================================================
--- build-system-1.2.3/3pp/pseudo/1.7.4/scripts/pseudo	(nonexistent)
+++ build-system-1.2.3/3pp/pseudo/1.7.4/scripts/pseudo	(revision 231)
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+program=$0
+pseudo_prefix=$(cd $(dirname $program)/.. ; pwd -P)/usr
+
+shell=$1 ; shift ; option=$1 ; shift
+
+enable_op_logging=
+if [ "$ENABLE_PSEUDO_LOGGING" == "yes" ] ; then
+  enable_op_logging=-l
+fi
+
+${pseudo_prefix}/bin/pseudo -P ${pseudo_prefix} ${enable_op_logging} $shell $option "$*"
Index: build-system-1.2.3/3pp/pseudo/1.7.4/scripts/pseudolog
===================================================================
--- build-system-1.2.3/3pp/pseudo/1.7.4/scripts/pseudolog	(nonexistent)
+++ build-system-1.2.3/3pp/pseudo/1.7.4/scripts/pseudolog	(revision 231)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+program=$0
+pseudo_prefix=$(cd $(dirname $program)/.. ; pwd -P)/usr
+
+args=""
+for arg in "$@" ; do
+  if [ "`echo "$arg" | wc -w`" -gt "1" ] ; then
+    args="$args \"$arg\""
+  else
+    args="$args $arg"
+  fi
+done
+
+PSEUDO_PREFIX=${pseudo_prefix} ${pseudo_prefix}/bin/pseudolog -P ${pseudo_prefix} $args
Index: build-system-1.2.3/3pp/sources/packages/pseudo/Makefile
===================================================================
--- build-system-1.2.3/3pp/sources/packages/pseudo/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/pseudo/Makefile	(revision 231)
@@ -0,0 +1,48 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/packages/a/pseudo
+
+
+versions    = 1.8.1
+pkgname     = pseudo
+suffix      = tar.xz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s)
+
+
+include ../../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======\n" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s)
Index: build-system-1.2.3/3pp/sources/packages/python2/Makefile
===================================================================
--- build-system-1.2.3/3pp/sources/packages/python2/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/python2/Makefile	(revision 231)
@@ -0,0 +1,48 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/packages/d/python2
+
+
+versions    = 2.7.11
+pkgname     = Python
+suffix      = tar.xz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s)
+
+
+include ../../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======\n" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s)
Index: build-system-1.2.3/3pp/sources/packages/python3/Makefile
===================================================================
--- build-system-1.2.3/3pp/sources/packages/python3/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/python3/Makefile	(revision 231)
@@ -0,0 +1,48 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/packages/d/python3
+
+
+versions    = 3.5.1
+pkgname     = Python
+suffix      = tar.xz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s)
+
+
+include ../../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======\n" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s)
Index: build-system-1.2.3/3pp/sources/packages/sqlite/Makefile
===================================================================
--- build-system-1.2.3/3pp/sources/packages/sqlite/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/sqlite/Makefile	(revision 231)
@@ -0,0 +1,48 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/packages/b/sqlite/2016
+
+
+versions    = 3.12.2.0
+pkgname     = sqlite
+suffix      = tar.gz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s)
+
+
+include ../../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======\n" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s)
Index: build-system-1.2.3/3pp/sources/packages/dialog/patches/README
===================================================================
--- build-system-1.2.3/3pp/sources/packages/dialog/patches/README	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/dialog/patches/README	(revision 231)
@@ -0,0 +1,6 @@
+
+/* begin *
+
+   dialog-1.2-20140112.patch   - Some enhance the appearance of dialogs.
+
+ * end */
Index: build-system-1.2.3/3pp/sources/packages/dialog/Makefile
===================================================================
--- build-system-1.2.3/3pp/sources/packages/dialog/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/dialog/Makefile	(revision 231)
@@ -0,0 +1,56 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/packages/a/dialog
+
+versions    = 1.2-20140112
+pkgname     = dialog
+suffix      = tgz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+patches     = $(CURDIR)/patches/dialog-1.2-20140112.patch
+
+.NOTPARALLEL: $(patches)
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s) $(patches)
+
+
+include ../../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+$(patches): $(sha1s)
+	@echo -e "\n======= Create Patches =======\n" ; \
+	 ( cd create-1.2-20140112-patch ; ./create.patch.sh ) ; \
+	 echo -e "\n"
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s) $(patches)
Index: build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/create.patch.sh
===================================================================
--- build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/create.patch.sh	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/create.patch.sh	(revision 231)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=1.2-20140112
+
+tar --files-from=file.list -xzvf ../dialog-$VERSION.tgz
+mv dialog-$VERSION dialog-$VERSION-orig
+
+cp -rf ./dialog-$VERSION-new ./dialog-$VERSION
+
+diff -b --unified -Nr  dialog-$VERSION-orig  dialog-$VERSION > dialog-$VERSION.patch
+
+mv dialog-$VERSION.patch ../patches
+
+rm -rf ./dialog-$VERSION
+rm -rf ./dialog-$VERSION-orig

Property changes on: build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/dialog-1.2-20140112-new/fselect.c
===================================================================
--- build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/dialog-1.2-20140112-new/fselect.c	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/dialog-1.2-20140112-new/fselect.c	(revision 231)
@@ -0,0 +1,928 @@
+/*
+ *  $Id: fselect.c,v 1.93 2012/12/30 20:52:25 tom Exp $
+ *
+ *  fselect.c -- implements the file-selector box
+ *
+ *  Copyright 2000-2011,2012	Thomas E. Dickey
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License, version 2.1
+ *  as published by the Free Software Foundation.
+ *
+ *  This program 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 this program; if not, write to
+ *	Free Software Foundation, Inc.
+ *	51 Franklin St., Fifth Floor
+ *	Boston, MA 02110, USA.
+ */
+
+#include <dialog.h>
+#include <dlg_keys.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+#endif
+
+# if defined(_FILE_OFFSET_BITS) && defined(HAVE_STRUCT_DIRENT64)
+#  if !defined(_LP64) && (_FILE_OFFSET_BITS == 64)
+#   define      DIRENT  struct dirent64
+#  else
+#   define      DIRENT  struct dirent
+#  endif
+# else
+#  define       DIRENT  struct dirent
+# endif
+
+#define EXT_WIDE 1
+#define HDR_HIGH 1
+#define BTN_HIGH (1 + 2 * MARGIN)	/* Ok/Cancel, also input-box */
+#define MIN_HIGH (HDR_HIGH - MARGIN + (BTN_HIGH * 2) + 4 * MARGIN)
+#define MIN_WIDE (2 * MAX(dlg_count_columns(d_label), dlg_count_columns(f_label)) + 6 * MARGIN + 2 * EXT_WIDE)
+
+#define MOUSE_D (KEY_MAX + 0)
+#define MOUSE_F (KEY_MAX + 10000)
+#define MOUSE_T (KEY_MAX + 20000)
+
+typedef enum {
+    sDIRS = -3
+    ,sFILES = -2
+    ,sTEXT = -1
+} STATES;
+
+typedef struct {
+    WINDOW *par;		/* parent window */
+    WINDOW *win;		/* this window */
+    int length;			/* length of the data[] array */
+    int offset;			/* index of first item on screen */
+    int choice;			/* index of the selection */
+    int mousex;			/* base of mouse-code return-values */
+    unsigned allocd;
+    char **data;
+} LIST;
+
+typedef struct {
+    int length;
+    char **data;
+} MATCH;
+
+static void
+init_list(LIST * list, WINDOW *par, WINDOW *win, int mousex)
+{
+    list->par = par;
+    list->win = win;
+    list->length = 0;
+    list->offset = 0;
+    list->choice = 0;
+    list->mousex = mousex;
+    list->allocd = 0;
+    list->data = 0;
+    dlg_mouse_mkbigregion(getbegy(win), getbegx(win),
+			  getmaxy(win), getmaxx(win),
+			  mousex, 1, 1, 1 /* by lines */ );
+}
+
+static char *
+leaf_of(char *path)
+{
+    char *leaf = strrchr(path, '/');
+    if (leaf != 0)
+	leaf++;
+    else
+	leaf = path;
+    return leaf;
+}
+
+static char *
+data_of(LIST * list)
+{
+    if (list != 0
+	&& list->data != 0)
+	return list->data[list->choice];
+    return 0;
+}
+
+static void
+free_list(LIST * list, int reinit)
+{
+    int n;
+
+    if (list->data != 0) {
+	for (n = 0; list->data[n] != 0; n++)
+	    free(list->data[n]);
+	free(list->data);
+	list->data = 0;
+    }
+    if (reinit)
+	init_list(list, list->par, list->win, list->mousex);
+}
+
+static void
+add_to_list(LIST * list, char *text)
+{
+    unsigned need;
+
+    need = (unsigned) (list->length + 1);
+    if (need + 1 > list->allocd) {
+	list->allocd = 2 * (need + 1);
+	if (list->data == 0) {
+	    list->data = dlg_malloc(char *, list->allocd);
+	} else {
+	    list->data = dlg_realloc(char *, list->allocd, list->data);
+	}
+	assert_ptr(list->data, "add_to_list");
+    }
+    list->data[list->length++] = dlg_strclone(text);
+    list->data[list->length] = 0;
+}
+
+static void
+keep_visible(LIST * list)
+{
+    int high = getmaxy(list->win);
+
+    if (list->choice < list->offset) {
+	list->offset = list->choice;
+    }
+    if (list->choice - list->offset >= high)
+	list->offset = list->choice - high + 1;
+}
+
+#define Value(c) (int)((c) & 0xff)
+
+static int
+find_choice(char *target, LIST * list)
+{
+    int n;
+    int choice = list->choice;
+    int len_1, len_2, cmp_1, cmp_2;
+
+    if (*target == 0) {
+	list->choice = 0;
+    } else {
+	/* find the match with the longest length.  If more than one has the
+	 * same length, choose the one with the closest match of the final
+	 * character.
+	 */
+	len_1 = 0;
+	cmp_1 = 256;
+	for (n = 0; n < list->length; n++) {
+	    char *a = target;
+	    char *b = list->data[n];
+
+	    len_2 = 0;
+	    while ((*a != 0) && (*b != 0) && (*a == *b)) {
+		a++;
+		b++;
+		len_2++;
+	    }
+	    cmp_2 = Value(*a) - Value(*b);
+	    if (cmp_2 < 0)
+		cmp_2 = -cmp_2;
+	    if ((len_2 > len_1)
+		|| (len_1 == len_2 && cmp_2 < cmp_1)) {
+		len_1 = len_2;
+		cmp_1 = cmp_2;
+		list->choice = n;
+	    }
+	}
+    }
+    if (choice != list->choice) {
+	keep_visible(list);
+    }
+    return (choice != list->choice);
+}
+
+static void
+display_list(LIST * list)
+{
+    int n;
+    int x;
+    int y;
+    int top;
+    int bottom;
+
+    if (list->win != 0) {
+	dlg_attr_clear(list->win, getmaxy(list->win), getmaxx(list->win), item_attr);
+	for (n = list->offset; n < list->length && list->data[n]; n++) {
+	    y = n - list->offset;
+	    if (y >= getmaxy(list->win))
+		break;
+	    (void) wmove(list->win, y, 0);
+	    if (n == list->choice)
+		(void) wattrset(list->win, item_selected_attr);
+	    (void) waddstr(list->win, list->data[n]);
+	    (void) wattrset(list->win, item_attr);
+	}
+	(void) wattrset(list->win, item_attr);
+
+	getparyx(list->win, y, x);
+
+	top = y - 1;
+	bottom = y + getmaxy(list->win);
+	dlg_draw_scrollbar(list->par,
+			   (long) list->offset,
+			   (long) list->offset,
+			   (long) (list->offset + getmaxy(list->win)),
+			   (long) (list->length),
+			   x + 1,
+			   x + getmaxx(list->win),
+			   top,
+			   bottom,
+			   menubox_border2_attr,
+			   menubox_border_attr);
+
+	(void) wmove(list->win, list->choice - list->offset, 0);
+	(void) wnoutrefresh(list->win);
+    }
+}
+
+/* FIXME: see arrows.c
+ * This workaround is used to allow two lists to have scroll-tabs at the same
+ * time, by reassigning their return-values to be different.  Just for
+ * readability, we use the names of keys with similar connotations, though all
+ * that is really required is that they're distinct, so we can put them in a
+ * switch statement.
+ */
+static void
+fix_arrows(LIST * list)
+{
+    int x;
+    int y;
+    int top;
+    int right;
+    int bottom;
+
+    if (list->win != 0) {
+	getparyx(list->win, y, x);
+	top = y - 1;
+	right = getmaxx(list->win);
+	bottom = y + getmaxy(list->win);
+
+	mouse_mkbutton(top, x, right,
+		       ((list->mousex == MOUSE_D)
+			? KEY_PREVIOUS
+			: KEY_PPAGE));
+	mouse_mkbutton(bottom, x, right,
+		       ((list->mousex == MOUSE_D)
+			? KEY_NEXT
+			: KEY_NPAGE));
+    }
+}
+
+static int
+show_list(char *target, LIST * list, int keep)
+{
+    int changed = keep || find_choice(target, list);
+    display_list(list);
+    return changed;
+}
+
+/*
+ * Highlight the closest match to 'target' in the given list, setting offset
+ * to match.
+ */
+static int
+show_both_lists(char *input, LIST * d_list, LIST * f_list, int keep)
+{
+    char *leaf = leaf_of(input);
+
+    return show_list(leaf, d_list, keep) | show_list(leaf, f_list, keep);
+}
+
+/*
+ * Move up/down in the given list
+ */
+static bool
+change_list(int choice, LIST * list)
+{
+    if (data_of(list) != 0) {
+	int last = list->length - 1;
+
+	choice += list->choice;
+	if (choice < 0)
+	    choice = 0;
+	if (choice > last)
+	    choice = last;
+	list->choice = choice;
+	keep_visible(list);
+	display_list(list);
+	return TRUE;
+    }
+    return FALSE;
+}
+
+static void
+scroll_list(int direction, LIST * list)
+{
+    if (data_of(list) != 0) {
+	int length = getmaxy(list->win);
+	if (change_list(direction * length, list))
+	    return;
+    }
+    beep();
+}
+
+static int
+compar(const void *a, const void *b)
+{
+    return strcmp(*(const char *const *) a, *(const char *const *) b);
+}
+
+static void
+match(char *name, LIST * d_list, LIST * f_list, MATCH * match_list)
+{
+    char *test = leaf_of(name);
+    size_t test_len = strlen(test);
+    char **matches = dlg_malloc(char *, (size_t) (d_list->length + f_list->length));
+    size_t data_len = 0;
+    int i;
+    for (i = 2; i < d_list->length; i++) {
+	if (strncmp(test, d_list->data[i], test_len) == 0) {
+	    matches[data_len++] = d_list->data[i];
+	}
+    }
+    for (i = 0; i < f_list->length; i++) {
+	if (strncmp(test, f_list->data[i], test_len) == 0) {
+	    matches[data_len++] = f_list->data[i];
+	}
+    }
+    matches = dlg_realloc(char *, data_len + 1, matches);
+    match_list->data = matches;
+    match_list->length = (int) data_len;
+}
+
+static void
+free_match(MATCH * match_list)
+{
+    free(match_list->data);
+    match_list->length = 0;
+}
+
+static int
+complete(char *name, LIST * d_list, LIST * f_list, char **buff_ptr)
+{
+    MATCH match_list;
+    char *test;
+    size_t test_len;
+    size_t i;
+    int j;
+    char *buff;
+
+    match(name, d_list, f_list, &match_list);
+    if (match_list.length == 0) {
+	*buff_ptr = NULL;
+	return 0;
+    }
+
+    test = match_list.data[0];
+    test_len = strlen(test);
+    buff = dlg_malloc(char, test_len + 2);
+    if (match_list.length == 1) {
+	strcpy(buff, test);
+	i = test_len;
+	if (test == data_of(d_list)) {
+	    buff[test_len] = '/';
+	    i++;
+	}
+    } else {
+	for (i = 0; i < test_len; i++) {
+	    char test_char = test[i];
+	    if (test_char == '\0')
+		break;
+	    for (j = 0; j < match_list.length; j++) {
+		if (match_list.data[j][i] != test_char) {
+		    break;
+		}
+	    }
+	    if (j == match_list.length) {
+		(buff)[i] = test_char;
+	    } else
+		break;
+	}
+	buff = dlg_realloc(char, i + 1, buff);
+    }
+    free_match(&match_list);
+    buff[i] = '\0';
+    *buff_ptr = buff;
+    return (i != 0);
+}
+
+static bool
+fill_lists(char *current, char *input, LIST * d_list, LIST * f_list, int keep)
+{
+    bool result = TRUE;
+    bool rescan = FALSE;
+    DIR *dp;
+    DIRENT *de;
+    struct stat sb;
+    int n;
+    char path[MAX_LEN + 1];
+    char *leaf;
+
+    /* check if we've updated the lists */
+    for (n = 0; current[n] && input[n]; n++) {
+	if (current[n] != input[n])
+	    break;
+    }
+
+    if (current[n] == input[n]) {
+	result = FALSE;
+	rescan = (n == 0 && d_list->length == 0);
+    } else if (strchr(current + n, '/') == 0
+	       && strchr(input + n, '/') == 0) {
+	result = show_both_lists(input, d_list, f_list, keep);
+    } else {
+	rescan = TRUE;
+    }
+
+    if (rescan) {
+	size_t have = strlen(input);
+
+	if (have > MAX_LEN)
+	    have = MAX_LEN;
+	memcpy(current, input, have);
+	current[have] = '\0';
+
+	/* refill the lists */
+	free_list(d_list, TRUE);
+	free_list(f_list, TRUE);
+	memcpy(path, current, have);
+	path[have] = '\0';
+	if ((leaf = strrchr(path, '/')) != 0) {
+	    *++leaf = 0;
+	} else {
+	    strcpy(path, "./");
+	    leaf = path + strlen(path);
+	}
+	dlg_trace_msg("opendir '%s'\n", path);
+	if ((dp = opendir(path)) != 0) {
+	    while ((de = readdir(dp)) != 0) {
+		strncpy(leaf, de->d_name, NAMLEN(de))[NAMLEN(de)] = 0;
+		if (stat(path, &sb) == 0) {
+		    if ((sb.st_mode & S_IFMT) == S_IFDIR)
+			add_to_list(d_list, leaf);
+		    else if (f_list->win)
+			add_to_list(f_list, leaf);
+		}
+	    }
+	    (void) closedir(dp);
+	    /* sort the lists */
+	    if (d_list->data != 0 && d_list->length > 1) {
+		qsort(d_list->data,
+		      (size_t) d_list->length,
+		      sizeof(d_list->data[0]),
+		      compar);
+	    }
+	    if (f_list->data != 0 && f_list->length > 1) {
+		qsort(f_list->data,
+		      (size_t) f_list->length,
+		      sizeof(f_list->data[0]),
+		      compar);
+	    }
+	}
+
+	(void) show_both_lists(input, d_list, f_list, FALSE);
+	d_list->offset = d_list->choice;
+	f_list->offset = f_list->choice;
+	result = TRUE;
+    }
+    return result;
+}
+
+static bool
+usable_state(int state, LIST * dirs, LIST * files)
+{
+    bool result;
+
+    switch (state) {
+    case sDIRS:
+	result = (dirs->win != 0) && (data_of(dirs) != 0);
+	break;
+    case sFILES:
+	result = (files->win != 0) && (data_of(files) != 0);
+	break;
+    default:
+	result = TRUE;
+	break;
+    }
+    return result;
+}
+
+#define which_list() ((state == sFILES) \
+			? &f_list \
+			: ((state == sDIRS) \
+			  ? &d_list \
+			  : 0))
+#define NAVIGATE_BINDINGS \
+	DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ), \
+	DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), \
+	DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), \
+	DLG_KEYS_DATA( DLGK_ITEM_NEXT,  KEY_DOWN ), \
+	DLG_KEYS_DATA( DLGK_ITEM_NEXT,  CHR_NEXT ), \
+	DLG_KEYS_DATA( DLGK_ITEM_NEXT,  KEY_NEXT ), \
+	DLG_KEYS_DATA( DLGK_ITEM_PREV,  CHR_PREVIOUS ), \
+	DLG_KEYS_DATA( DLGK_ITEM_PREV,  KEY_UP ), \
+	DLG_KEYS_DATA( DLGK_PAGE_NEXT,  KEY_NPAGE ), \
+	DLG_KEYS_DATA( DLGK_PAGE_PREV,  KEY_PPAGE )
+
+/*
+ * Display a dialog box for entering a filename
+ */
+static int
+dlg_fselect(const char *title, const char *path, int height, int width, int dselect)
+{
+    /* *INDENT-OFF* */
+    static DLG_KEYS_BINDING binding[] = {
+	HELPKEY_BINDINGS,
+	ENTERKEY_BINDINGS,
+	NAVIGATE_BINDINGS,
+	END_KEYS_BINDING
+    };
+    static DLG_KEYS_BINDING binding2[] = {
+	INPUTSTR_BINDINGS,
+	HELPKEY_BINDINGS,
+	ENTERKEY_BINDINGS,
+	NAVIGATE_BINDINGS,
+	END_KEYS_BINDING
+    };
+    /* *INDENT-ON* */
+
+#ifdef KEY_RESIZE
+    int old_height = height;
+    int old_width = width;
+    bool resized = FALSE;
+#endif
+    int tbox_y, tbox_x, tbox_width, tbox_height;
+    int dbox_y, dbox_x, dbox_width, dbox_height;
+    int fbox_y, fbox_x, fbox_width, fbox_height;
+    int show_buttons = TRUE;
+    int offset = 0;
+    int key = 0;
+    int fkey = FALSE;
+    int code;
+    int result = DLG_EXIT_UNKNOWN;
+    int state = dialog_vars.default_button >= 0 ? dlg_default_button() : sTEXT;
+    int button;
+    int first = (state == sTEXT);
+    int first_trace = TRUE;
+    char *input;
+    char *completed;
+    char current[MAX_LEN + 1];
+    WINDOW *dialog = 0;
+    WINDOW *w_text = 0;
+    WINDOW *w_work = 0;
+    const char **buttons = dlg_ok_labels();
+    const char *d_label = _("Directories");
+    const char *f_label = _("Files");
+    char *partial = 0;
+    int min_wide = MIN_WIDE;
+    int min_items = height ? 0 : 4;
+    LIST d_list, f_list;
+
+    dlg_does_output();
+
+    /* Set up the initial value */
+    input = dlg_set_result(path);
+    offset = (int) strlen(input);
+    *current = 0;
+
+    dlg_button_layout(buttons, &min_wide);
+
+#ifdef KEY_RESIZE
+  retry:
+#endif
+    dlg_auto_size(title, (char *) 0, &height, &width, 6, 25);
+    height += MIN_HIGH + min_items;
+    if (width < min_wide)
+	width = min_wide;
+    dlg_print_size(height, width);
+    dlg_ctl_size(height, width);
+
+    dialog = dlg_new_window(height + 1, width,
+			    dlg_box_y_ordinate(height),
+			    dlg_box_x_ordinate(width));
+    dlg_register_window(dialog, "fselect", binding);
+    dlg_register_buttons(dialog, "fselect", buttons);
+
+    dlg_mouse_setbase(0, 0);
+
+    dlg_draw_box2(dialog, 0, 0, height + 1, width, dialog_attr, border_attr, border2_attr);
+    dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
+    dlg_draw_title(dialog, title);
+
+    (void) wattrset(dialog, dialog_attr);
+
+    /* Draw the input field box */
+    tbox_height = 1;
+    tbox_width = width - (4 * MARGIN + 2);
+    tbox_y = height - (BTN_HIGH * 2) + MARGIN + 1;
+    tbox_x = (width - tbox_width) / 2;
+
+    w_text = derwin(dialog, tbox_height, tbox_width, tbox_y, tbox_x);
+    if (w_text == 0) {
+	result = DLG_EXIT_ERROR;
+	goto finish;
+    }
+
+    (void) keypad(w_text, TRUE);
+    dlg_draw_box(dialog, tbox_y - MARGIN, tbox_x - MARGIN,
+		 (2 * MARGIN + 1), tbox_width + (MARGIN + EXT_WIDE),
+		 menubox_border_attr, menubox_border2_attr);
+    dlg_mouse_mkbigregion(getbegy(dialog) + tbox_y - MARGIN,
+			  getbegx(dialog) + tbox_x - MARGIN,
+			  1 + (2 * MARGIN),
+			  tbox_width + (MARGIN + EXT_WIDE),
+			  MOUSE_T, 1, 1, 3 /* doesn't matter */ );
+
+    dlg_register_window(w_text, "fselect2", binding2);
+
+    /* Draw the directory listing box */
+    if (dselect)
+	dbox_width = (width - (6 * MARGIN));
+    else
+	dbox_width = (width - (6 * MARGIN + 2 * EXT_WIDE)) / 2;
+    dbox_height = height - MIN_HIGH;
+    dbox_y = (2 * MARGIN + 2);
+    dbox_x = tbox_x;
+
+    w_work = derwin(dialog, dbox_height, dbox_width, dbox_y, dbox_x);
+    if (w_work == 0) {
+	result = DLG_EXIT_ERROR;
+	goto finish;
+    }
+
+    (void) keypad(w_work, TRUE);
+    (void) mvwaddstr(dialog, dbox_y - (MARGIN + 1), dbox_x - MARGIN, d_label);
+    dlg_draw_box(dialog,
+		 dbox_y - MARGIN, dbox_x - MARGIN,
+		 dbox_height + (MARGIN + 1), dbox_width + (MARGIN + 1),
+		 menubox_border_attr, menubox_border2_attr);
+    init_list(&d_list, dialog, w_work, MOUSE_D);
+
+    if (!dselect) {
+	/* Draw the filename listing box */
+	fbox_height = dbox_height;
+	fbox_width = dbox_width;
+	fbox_y = dbox_y;
+	fbox_x = tbox_x + dbox_width + (2 * MARGIN);
+
+	w_work = derwin(dialog, fbox_height, fbox_width, fbox_y, fbox_x);
+	if (w_work == 0) {
+	    result = DLG_EXIT_ERROR;
+	    goto finish;
+	}
+
+	(void) keypad(w_work, TRUE);
+	(void) mvwaddstr(dialog, fbox_y - (MARGIN + 1), fbox_x - MARGIN, f_label);
+	dlg_draw_box(dialog,
+		     fbox_y - MARGIN, fbox_x - MARGIN,
+		     fbox_height + (MARGIN + 1), fbox_width + (MARGIN + 1),
+		     menubox_border_attr, menubox_border2_attr);
+	init_list(&f_list, dialog, w_work, MOUSE_F);
+    } else {
+	memset(&f_list, 0, sizeof(f_list));
+    }
+
+    while (result == DLG_EXIT_UNKNOWN) {
+
+	if (fill_lists(current, input, &d_list, &f_list, state < sTEXT))
+	    show_buttons = TRUE;
+
+#ifdef KEY_RESIZE
+	if (resized) {
+	    resized = FALSE;
+	    dlg_show_string(w_text, input, offset, inputbox_attr,
+			    0, 0, tbox_width, (bool) 0, (bool) first);
+	}
+#endif
+
+	/*
+	 * The last field drawn determines where the cursor is shown:
+	 */
+	if (show_buttons) {
+	    show_buttons = FALSE;
+	    button = (state < 0) ? 0 : state;
+	    dlg_draw_buttons(dialog, height - 1, 0, buttons, button, FALSE, width);
+	}
+
+	if (first_trace) {
+	    first_trace = FALSE;
+	    dlg_trace_win(dialog);
+	}
+
+	if (state < 0) {
+	    switch (state) {
+	    case sTEXT:
+		dlg_set_focus(dialog, w_text);
+		break;
+	    case sFILES:
+		dlg_set_focus(dialog, f_list.win);
+		break;
+	    case sDIRS:
+		dlg_set_focus(dialog, d_list.win);
+		break;
+	    }
+	}
+
+	if (first) {
+	    (void) wrefresh(dialog);
+	} else {
+	    fix_arrows(&d_list);
+	    fix_arrows(&f_list);
+	    key = dlg_mouse_wgetch((state == sTEXT) ? w_text : dialog, &fkey);
+	    if (dlg_result_key(key, fkey, &result))
+		break;
+	}
+
+	if (!fkey && key == ' ') {
+	    key = DLGK_SELECT;
+	    fkey = TRUE;
+	}
+
+	if (fkey) {
+	    switch (key) {
+	    case DLGK_MOUSE(KEY_PREVIOUS):
+		state = sDIRS;
+		scroll_list(-1, which_list());
+		continue;
+	    case DLGK_MOUSE(KEY_NEXT):
+		state = sDIRS;
+		scroll_list(1, which_list());
+		continue;
+	    case DLGK_MOUSE(KEY_PPAGE):
+		state = sFILES;
+		scroll_list(-1, which_list());
+		continue;
+	    case DLGK_MOUSE(KEY_NPAGE):
+		state = sFILES;
+		scroll_list(1, which_list());
+		continue;
+	    case DLGK_PAGE_PREV:
+		scroll_list(-1, which_list());
+		continue;
+	    case DLGK_PAGE_NEXT:
+		scroll_list(1, which_list());
+		continue;
+	    case DLGK_ITEM_PREV:
+		if (change_list(-1, which_list()))
+		    continue;
+		/* FALLTHRU */
+	    case DLGK_FIELD_PREV:
+		show_buttons = TRUE;
+		do {
+		    state = dlg_prev_ok_buttonindex(state, sDIRS);
+		} while (!usable_state(state, &d_list, &f_list));
+		continue;
+	    case DLGK_ITEM_NEXT:
+		if (change_list(1, which_list()))
+		    continue;
+		/* FALLTHRU */
+	    case DLGK_FIELD_NEXT:
+		show_buttons = TRUE;
+		do {
+		    state = dlg_next_ok_buttonindex(state, sDIRS);
+		} while (!usable_state(state, &d_list, &f_list));
+		continue;
+	    case DLGK_SELECT:
+		completed = 0;
+		if (partial != 0) {
+		    free(partial);
+		    partial = 0;
+		}
+		if (state == sFILES && !dselect) {
+		    completed = data_of(&f_list);
+		} else if (state == sDIRS) {
+		    completed = data_of(&d_list);
+		} else {
+		    if (complete(input, &d_list, &f_list, &partial)) {
+			completed = partial;
+		    }
+		}
+		if (completed != 0) {
+		    state = sTEXT;
+		    show_buttons = TRUE;
+		    strcpy(leaf_of(input), completed);
+		    offset = (int) strlen(input);
+		    dlg_show_string(w_text, input, offset, inputbox_attr,
+				    0, 0, tbox_width, 0, first);
+		    if (partial != NULL) {
+			free(partial);
+			partial = 0;
+		    }
+		    continue;
+		} else {	/* if (state < sTEXT) */
+		    (void) beep();
+		    continue;
+		}
+		/* FALLTHRU */
+	    case DLGK_ENTER:
+		result = (state > 0) ? dlg_enter_buttoncode(state) : DLG_EXIT_OK;
+		continue;
+#ifdef KEY_RESIZE
+	    case KEY_RESIZE:
+		/* reset data */
+		height = old_height;
+		width = old_width;
+		show_buttons = TRUE;
+		*current = 0;
+		resized = TRUE;
+		/* repaint */
+		dlg_clear();
+		dlg_del_window(dialog);
+		refresh();
+		dlg_mouse_free_regions();
+		goto retry;
+#endif
+	    default:
+		if (key >= DLGK_MOUSE(MOUSE_T)) {
+		    state = sTEXT;
+		    continue;
+		} else if (key >= DLGK_MOUSE(MOUSE_F)) {
+		    if (f_list.win != 0) {
+			state = sFILES;
+			f_list.choice = (key - DLGK_MOUSE(MOUSE_F)) + f_list.offset;
+			display_list(&f_list);
+		    }
+		    continue;
+		} else if (key >= DLGK_MOUSE(MOUSE_D)) {
+		    if (d_list.win != 0) {
+			state = sDIRS;
+			d_list.choice = (key - DLGK_MOUSE(MOUSE_D)) + d_list.offset;
+			display_list(&d_list);
+		    }
+		    continue;
+		} else if (is_DLGK_MOUSE(key)
+			   && (code = dlg_ok_buttoncode(key - M_EVENT)) >= 0) {
+		    result = code;
+		    continue;
+		}
+		break;
+	    }
+	}
+
+	if (state < 0) {	/* Input box selected if we're editing */
+	    int edit = dlg_edit_string(input, &offset, key, fkey, first);
+
+	    if (edit) {
+		dlg_show_string(w_text, input, offset, inputbox_attr,
+				0, 0, tbox_width, 0, first);
+		first = FALSE;
+		state = sTEXT;
+	    }
+	} else if (state >= 0 &&
+		   (code = dlg_char_to_button(key, buttons)) >= 0) {
+	    result = dlg_ok_buttoncode(code);
+	    break;
+	}
+    }
+
+    dlg_unregister_window(w_text);
+    dlg_del_window(dialog);
+    dlg_mouse_free_regions();
+    free_list(&d_list, FALSE);
+    free_list(&f_list, FALSE);
+
+  finish:
+    if (partial != 0)
+	free(partial);
+    return result;
+}
+
+/*
+ * Display a dialog box for entering a filename
+ */
+int
+dialog_fselect(const char *title, const char *path, int height, int width)
+{
+    return dlg_fselect(title, path, height, width, FALSE);
+}
+
+/*
+ * Display a dialog box for entering a directory
+ */
+int
+dialog_dselect(const char *title, const char *path, int height, int width)
+{
+    return dlg_fselect(title, path, height, width, TRUE);
+}
Index: build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/dialog-1.2-20140112-new/checklist.c
===================================================================
--- build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/dialog-1.2-20140112-new/checklist.c	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/dialog-1.2-20140112-new/checklist.c	(revision 231)
@@ -0,0 +1,680 @@
+/*
+ *  $Id: checklist.c,v 1.153 2013/09/02 17:01:02 tom Exp $
+ *
+ *  checklist.c -- implements the checklist box
+ *
+ *  Copyright 2000-2012,2013	Thomas E. Dickey
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License, version 2.1
+ *  as published by the Free Software Foundation.
+ *
+ *  This program 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 this program; if not, write to
+ *	Free Software Foundation, Inc.
+ *	51 Franklin St., Fifth Floor
+ *	Boston, MA 02110, USA.
+ *
+ *  An earlier version of this program lists as authors:
+ *	Savio Lam (lam836@cs.cuhk.hk)
+ *	Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
+ *	Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
+ */
+
+#include <dialog.h>
+#include <dlg_keys.h>
+
+#define MIN_HIGH  4
+
+typedef struct {
+    /* the outer-window */
+    WINDOW *dialog;
+    int box_y;
+    int box_x;
+    int check_x;
+    int item_x;
+    int checkflag;
+    int use_height;
+    int use_width;
+    /* the inner-window */
+    WINDOW *list;
+    DIALOG_LISTITEM *items;
+    int item_no;
+    const char *states;
+} ALL_DATA;
+
+/*
+ * Print list item.  The 'selected' parameter is true if 'choice' is the
+ * current item.  That one is colored differently from the other items.
+ */
+static void
+print_item(ALL_DATA * data,
+	   WINDOW *win,
+	   DIALOG_LISTITEM * item,
+	   const char *states,
+	   int choice,
+	   int selected)
+{
+    chtype save = dlg_get_attrs(win);
+    int i;
+    bool both = (!dialog_vars.no_tags && !dialog_vars.no_items);
+    bool first = TRUE;
+    int climit = (getmaxx(win) - data->check_x + 1);
+    const char *show = (dialog_vars.no_items
+			? item->name
+			: item->text);
+
+    /* Clear 'residue' of last item */
+    (void) wattrset(win, menubox_attr);
+    (void) wmove(win, choice, 0);
+    for (i = 0; i < data->use_width; i++)
+	(void) waddch(win, ' ');
+
+    (void) wmove(win, choice, data->check_x);
+    (void) wattrset(win, selected ? check_selected_attr : check_attr);
+    (void) wprintw(win,
+		   (data->checkflag == FLAG_CHECK) ? "[%c]" : "(%c)",
+		   states[item->state]);
+    (void) wattrset(win, menubox_attr);
+    (void) waddch(win, ' ');
+
+    if (both) {
+	dlg_print_listitem(win, item->name, climit, first, selected);
+	first = FALSE;
+    }
+
+    (void) wmove(win, choice, data->item_x);
+    dlg_print_listitem(win, show, climit, first, selected);
+
+    if (selected) {
+	dlg_item_help(item->help);
+    }
+    (void) wattrset(win, save);
+}
+
+static void
+print_list(ALL_DATA * data, int choice, int scrollamt, int max_choice)
+{
+    int i;
+    int cur_y, cur_x;
+
+    getyx(data->dialog, cur_y, cur_x);
+    for (i = 0; i < max_choice; i++) {
+	print_item(data,
+		   data->list,
+		   &data->items[i + scrollamt],
+		   data->states,
+		   i, i == choice);
+    }
+    (void) wnoutrefresh(data->list);
+
+    dlg_draw_scrollbar(data->dialog,
+		       (long) (scrollamt),
+		       (long) (scrollamt),
+		       (long) (scrollamt + max_choice),
+		       (long) (data->item_no),
+		       data->box_x + data->check_x,
+		       data->box_x + data->use_width,
+		       data->box_y,
+		       data->box_y + data->use_height + 1,
+		       menubox_border2_attr,
+		       menubox_border_attr);
+
+    (void) wmove(data->dialog, cur_y, cur_x);
+}
+
+static bool
+check_hotkey(DIALOG_LISTITEM * items, int choice)
+{
+    bool result = FALSE;
+
+    if (dlg_match_char(dlg_last_getc(),
+		       (dialog_vars.no_tags
+			? items[choice].text
+			: items[choice].name))) {
+	result = TRUE;
+    }
+    return result;
+}
+
+/*
+ * This is an alternate interface to 'checklist' which allows the application
+ * to read the list item states back directly without putting them in the
+ * output buffer.  It also provides for more than two states over which the
+ * check/radio box can display.
+ */
+int
+dlg_checklist(const char *title,
+	      const char *cprompt,
+	      int height,
+	      int width,
+	      int list_height,
+	      int item_no,
+	      DIALOG_LISTITEM * items,
+	      const char *states,
+	      int flag,
+	      int *current_item)
+{
+    /* *INDENT-OFF* */
+    static DLG_KEYS_BINDING binding[] = {
+	HELPKEY_BINDINGS,
+	ENTERKEY_BINDINGS,
+	DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
+	DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
+	DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
+	DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
+	DLG_KEYS_DATA( DLGK_ITEM_FIRST, KEY_HOME ),
+	DLG_KEYS_DATA( DLGK_ITEM_LAST,	KEY_END ),
+	DLG_KEYS_DATA( DLGK_ITEM_LAST,	KEY_LL ),
+	DLG_KEYS_DATA( DLGK_ITEM_NEXT,	'+' ),
+	DLG_KEYS_DATA( DLGK_ITEM_NEXT,	KEY_DOWN ),
+	DLG_KEYS_DATA( DLGK_ITEM_NEXT,  CHR_NEXT ),
+	DLG_KEYS_DATA( DLGK_ITEM_PREV,	'-' ),
+	DLG_KEYS_DATA( DLGK_ITEM_PREV,	KEY_UP ),
+	DLG_KEYS_DATA( DLGK_ITEM_PREV,  CHR_PREVIOUS ),
+	DLG_KEYS_DATA( DLGK_PAGE_NEXT,	KEY_NPAGE ),
+	DLG_KEYS_DATA( DLGK_PAGE_NEXT,	DLGK_MOUSE(KEY_NPAGE) ),
+	DLG_KEYS_DATA( DLGK_PAGE_PREV,	KEY_PPAGE ),
+	DLG_KEYS_DATA( DLGK_PAGE_PREV,	DLGK_MOUSE(KEY_PPAGE) ),
+	END_KEYS_BINDING
+    };
+    /* *INDENT-ON* */
+
+#ifdef KEY_RESIZE
+    int old_height = height;
+    int old_width = width;
+#endif
+    ALL_DATA all;
+    int i, j, key2, found, x, y, cur_x, cur_y;
+    int key = 0, fkey;
+    int button = dialog_state.visit_items ? -1 : dlg_default_button();
+    int choice = dlg_default_listitem(items);
+    int scrollamt = 0;
+    int max_choice;
+    int was_mouse;
+    int use_width, list_width, name_width, text_width;
+    int result = DLG_EXIT_UNKNOWN;
+    int num_states;
+    WINDOW *dialog;
+    char *prompt = dlg_strclone(cprompt);
+    const char **buttons = dlg_ok_labels();
+    const char *widget_name;
+
+    memset(&all, 0, sizeof(all));
+    all.items = items;
+    all.item_no = item_no;
+
+    dlg_does_output();
+    dlg_tab_correct_str(prompt);
+
+    /*
+     * If this is a radiobutton list, ensure that no more than one item is
+     * selected initially.  Allow none to be selected, since some users may
+     * wish to provide this flavor.
+     */
+    if (flag == FLAG_RADIO) {
+	bool first = TRUE;
+
+	for (i = 0; i < item_no; i++) {
+	    if (items[i].state) {
+		if (first) {
+		    first = FALSE;
+		} else {
+		    items[i].state = 0;
+		}
+	    }
+	}
+	widget_name = "radiolist";
+    } else {
+	widget_name = "checklist";
+    }
+#ifdef KEY_RESIZE
+  retry:
+#endif
+
+    all.use_height = list_height;
+    use_width = dlg_calc_list_width(item_no, items) + 10;
+    use_width = MAX(26, use_width);
+    if (all.use_height == 0) {
+	/* calculate height without items (4) */
+	dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, use_width);
+	dlg_calc_listh(&height, &all.use_height, item_no);
+    } else {
+	dlg_auto_size(title, prompt,
+		      &height, &width,
+		      MIN_HIGH + all.use_height, use_width);
+    }
+    dlg_button_layout(buttons, &width);
+    dlg_print_size(height, width);
+    dlg_ctl_size(height, width);
+
+    /* we need at least two states */
+    if (states == 0 || strlen(states) < 2)
+	states = " *";
+    num_states = (int) strlen(states);
+    all.states = states;
+
+    all.checkflag = flag;
+
+    x = dlg_box_x_ordinate(width);
+    y = dlg_box_y_ordinate(height);
+
+    dialog = dlg_new_window(height, width, y, x);
+    all.dialog = dialog;
+    dlg_register_window(dialog, widget_name, binding);
+    dlg_register_buttons(dialog, widget_name, buttons);
+
+    dlg_mouse_setbase(x, y);
+
+    dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
+    dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
+    dlg_draw_title(dialog, title);
+
+    (void) wattrset(dialog, dialog_attr);
+    dlg_print_autowrap(dialog, prompt, height, width);
+
+    all.use_width = width - 6;
+    getyx(dialog, cur_y, cur_x);
+    all.box_y = cur_y + 1;
+    all.box_x = (width - all.use_width) / 2 - 1;
+
+    /*
+     * After displaying the prompt, we know how much space we really have.
+     * Limit the list to avoid overwriting the ok-button.
+     */
+    if (all.use_height + MIN_HIGH > height - cur_y)
+	all.use_height = height - MIN_HIGH - cur_y;
+    if (all.use_height <= 0)
+	all.use_height = 1;
+
+    max_choice = MIN(all.use_height, item_no);
+    max_choice = MAX(max_choice, 1);
+
+    /* create new window for the list */
+    all.list = dlg_sub_window(dialog, all.use_height, all.use_width,
+			      y + all.box_y + 1, x + all.box_x + 1);
+
+    /* draw a box around the list items */
+    dlg_draw_box(dialog, all.box_y, all.box_x,
+		 all.use_height + 2 * MARGIN,
+		 all.use_width + 2 * MARGIN,
+		 menubox_border_attr, menubox_border2_attr);
+
+    text_width = 0;
+    name_width = 0;
+    /* Find length of longest item to center checklist */
+    for (i = 0; i < item_no; i++) {
+	text_width = MAX(text_width, dlg_count_columns(items[i].text));
+	name_width = MAX(name_width, dlg_count_columns(items[i].name));
+    }
+
+    /* If the name+text is wider than the list is allowed, then truncate
+     * one or both of them.  If the name is no wider than 1/4 of the list,
+     * leave it intact.
+     */
+    use_width = (all.use_width - 6);
+    if (dialog_vars.no_tags) {
+	list_width = MIN(all.use_width, text_width);
+    } else if (dialog_vars.no_items) {
+	list_width = MIN(all.use_width, name_width);
+    } else {
+	if (text_width >= 0
+	    && name_width >= 0
+	    && use_width > 0
+	    && text_width + name_width > use_width) {
+	    int need = (int) (0.25 * use_width);
+	    if (name_width > need) {
+		int want = (int) (use_width * ((double) name_width) /
+				  (text_width + name_width));
+		name_width = (want > need) ? want : need;
+	    }
+	    text_width = use_width - name_width;
+	}
+	list_width = (text_width + name_width);
+    }
+
+    all.check_x = (use_width - list_width) / 2;
+    all.item_x = ((dialog_vars.no_tags
+		   ? 0
+		   : (dialog_vars.no_items
+		      ? 0
+		      : (2 + name_width)))
+		  + all.check_x + 4);
+
+    /* ensure we are scrolled to show the current choice */
+    scrollamt = MIN(scrollamt, max_choice + item_no - 1);
+    if (choice >= (max_choice + scrollamt - 1)) {
+	scrollamt = MAX(0, choice - max_choice + 1);
+	choice = max_choice - 1;
+    }
+    print_list(&all, choice, scrollamt, max_choice);
+
+    /* register the new window, along with its borders */
+    dlg_mouse_mkbigregion(all.box_y + 1, all.box_x,
+			  all.use_height, all.use_width + 2,
+			  KEY_MAX, 1, 1, 1 /* by lines */ );
+
+    dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
+
+    dlg_trace_win(dialog);
+    while (result == DLG_EXIT_UNKNOWN) {
+	if (button < 0)		/* --visit-items */
+	    wmove(dialog, all.box_y + choice + 1, all.box_x + all.check_x + 2);
+
+	key = dlg_mouse_wgetch(dialog, &fkey);
+	if (dlg_result_key(key, fkey, &result))
+	    break;
+
+	was_mouse = (fkey && is_DLGK_MOUSE(key));
+	if (was_mouse)
+	    key -= M_EVENT;
+
+	if (was_mouse && (key >= KEY_MAX)) {
+	    getyx(dialog, cur_y, cur_x);
+	    i = (key - KEY_MAX);
+	    if (i < max_choice) {
+		choice = (key - KEY_MAX);
+		print_list(&all, choice, scrollamt, max_choice);
+
+		key = ' ';	/* force the selected item to toggle */
+	    } else {
+		beep();
+		continue;
+	    }
+	    fkey = FALSE;
+	} else if (was_mouse && key >= KEY_MIN) {
+	    key = dlg_lookup_key(dialog, key, &fkey);
+	}
+
+	/*
+	 * A space toggles the item status.  We handle either a checklist
+	 * (any number of items can be selected) or radio list (zero or one
+	 * items can be selected).
+	 */
+	if (key == ' ') {
+	    int current = scrollamt + choice;
+	    int next = items[current].state + 1;
+
+	    if (next >= num_states)
+		next = 0;
+
+	    if (flag == FLAG_CHECK) {	/* checklist? */
+		getyx(dialog, cur_y, cur_x);
+		items[current].state = next;
+		print_item(&all, all.list,
+			   &items[scrollamt + choice],
+			   states,
+			   choice, TRUE);
+		(void) wnoutrefresh(all.list);
+		(void) wmove(dialog, cur_y, cur_x);
+	    } else {		/* radiolist */
+		for (i = 0; i < item_no; i++) {
+		    if (i != current) {
+			items[i].state = 0;
+		    }
+		}
+		if (items[current].state) {
+		    getyx(dialog, cur_y, cur_x);
+		    items[current].state = next ? next : 1;
+		    print_item(&all, all.list,
+			       &items[current],
+			       states,
+			       choice, TRUE);
+		    (void) wnoutrefresh(all.list);
+		    (void) wmove(dialog, cur_y, cur_x);
+		} else {
+		    items[current].state = 1;
+		    print_list(&all, choice, scrollamt, max_choice);
+		}
+	    }
+	    continue;		/* wait for another key press */
+	}
+
+	/*
+	 * Check if key pressed matches first character of any item tag in
+	 * list.  If there is more than one match, we will cycle through
+	 * each one as the same key is pressed repeatedly.
+	 */
+	found = FALSE;
+	if (!fkey) {
+	    if (button < 0 || !dialog_state.visit_items) {
+		for (j = scrollamt + choice + 1; j < item_no; j++) {
+		    if (check_hotkey(items, j)) {
+			found = TRUE;
+			i = j - scrollamt;
+			break;
+		    }
+		}
+		if (!found) {
+		    for (j = 0; j <= scrollamt + choice; j++) {
+			if (check_hotkey(items, j)) {
+			    found = TRUE;
+			    i = j - scrollamt;
+			    break;
+			}
+		    }
+		}
+		if (found)
+		    dlg_flush_getc();
+	    } else if ((j = dlg_char_to_button(key, buttons)) >= 0) {
+		button = j;
+		ungetch('\n');
+		continue;
+	    }
+	}
+
+	/*
+	 * A single digit (1-9) positions the selection to that line in the
+	 * current screen.
+	 */
+	if (!found
+	    && (key <= '9')
+	    && (key > '0')
+	    && (key - '1' < max_choice)) {
+	    found = TRUE;
+	    i = key - '1';
+	}
+
+	if (!found) {
+	    if (fkey) {
+		found = TRUE;
+		switch (key) {
+		case DLGK_ITEM_FIRST:
+		    i = -scrollamt;
+		    break;
+		case DLGK_ITEM_LAST:
+		    i = item_no - 1 - scrollamt;
+		    break;
+		case DLGK_PAGE_PREV:
+		    if (choice)
+			i = 0;
+		    else if (scrollamt != 0)
+			i = -MIN(scrollamt, max_choice);
+		    else
+			continue;
+		    break;
+		case DLGK_PAGE_NEXT:
+		    i = MIN(choice + max_choice, item_no - scrollamt - 1);
+		    break;
+		case DLGK_ITEM_PREV:
+		    i = choice - 1;
+		    if (choice == 0 && scrollamt == 0)
+			continue;
+		    break;
+		case DLGK_ITEM_NEXT:
+		    i = choice + 1;
+		    if (scrollamt + choice >= item_no - 1)
+			continue;
+		    break;
+		default:
+		    found = FALSE;
+		    break;
+		}
+	    }
+	}
+
+	if (found) {
+	    if (i != choice) {
+		getyx(dialog, cur_y, cur_x);
+		if (i < 0 || i >= max_choice) {
+		    if (i < 0) {
+			scrollamt += i;
+			choice = 0;
+		    } else {
+			choice = max_choice - 1;
+			scrollamt += (i - max_choice + 1);
+		    }
+		    print_list(&all, choice, scrollamt, max_choice);
+		} else {
+		    choice = i;
+		    print_list(&all, choice, scrollamt, max_choice);
+		}
+	    }
+	    continue;		/* wait for another key press */
+	}
+
+	if (fkey) {
+	    switch (key) {
+	    case DLGK_ENTER:
+		result = dlg_enter_buttoncode(button);
+		break;
+	    case DLGK_FIELD_PREV:
+		button = dlg_prev_button(buttons, button);
+		dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+				 FALSE, width);
+		break;
+	    case DLGK_FIELD_NEXT:
+		button = dlg_next_button(buttons, button);
+		dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+				 FALSE, width);
+		break;
+#ifdef KEY_RESIZE
+	    case KEY_RESIZE:
+		/* reset data */
+		height = old_height;
+		width = old_width;
+		/* repaint */
+		dlg_clear();
+		dlg_del_window(dialog);
+		refresh();
+		dlg_mouse_free_regions();
+		goto retry;
+#endif
+	    default:
+		if (was_mouse) {
+		    if ((key2 = dlg_ok_buttoncode(key)) >= 0) {
+			result = key2;
+			break;
+		    }
+		    beep();
+		}
+	    }
+	} else {
+	    beep();
+	}
+    }
+
+    dlg_del_window(dialog);
+    dlg_mouse_free_regions();
+    free(prompt);
+    *current_item = (scrollamt + choice);
+    return result;
+}
+
+/*
+ * Display a dialog box with a list of options that can be turned on or off
+ * The `flag' parameter is used to select between radiolist and checklist.
+ */
+int
+dialog_checklist(const char *title,
+		 const char *cprompt,
+		 int height,
+		 int width,
+		 int list_height,
+		 int item_no,
+		 char **items,
+		 int flag)
+{
+    int result;
+    int i, j;
+    DIALOG_LISTITEM *listitems;
+    bool separate_output = ((flag == FLAG_CHECK)
+			    && (dialog_vars.separate_output));
+    bool show_status = FALSE;
+    int current = 0;
+    char *help_result;
+
+    listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
+    assert_ptr(listitems, "dialog_checklist");
+
+    for (i = j = 0; i < item_no; ++i) {
+	listitems[i].name = items[j++];
+	listitems[i].text = (dialog_vars.no_items
+			     ? dlg_strempty()
+			     : items[j++]);
+	listitems[i].state = !dlg_strcmp(items[j++], "on");
+	listitems[i].help = ((dialog_vars.item_help)
+			     ? items[j++]
+			     : dlg_strempty());
+    }
+    dlg_align_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
+
+    result = dlg_checklist(title,
+			   cprompt,
+			   height,
+			   width,
+			   list_height,
+			   item_no,
+			   listitems,
+			   NULL,
+			   flag,
+			   &current);
+
+    switch (result) {
+    case DLG_EXIT_OK:		/* FALLTHRU */
+    case DLG_EXIT_EXTRA:
+	show_status = TRUE;
+	break;
+    case DLG_EXIT_HELP:
+	dlg_add_help_listitem(&result, &help_result, &listitems[current]);
+	if ((show_status = dialog_vars.help_status)) {
+	    if (separate_output) {
+		dlg_add_string(help_result);
+		dlg_add_separator();
+	    } else {
+		dlg_add_quoted(help_result);
+	    }
+	} else {
+	    dlg_add_string(help_result);
+	}
+	break;
+    }
+
+    if (show_status) {
+	for (i = 0; i < item_no; i++) {
+	    if (listitems[i].state) {
+		if (separate_output) {
+		    dlg_add_string(listitems[i].name);
+		    dlg_add_separator();
+		} else {
+		    if (dlg_need_separator())
+			dlg_add_separator();
+		    if (flag == FLAG_CHECK)
+			dlg_add_quoted(listitems[i].name);
+		    else
+			dlg_add_string(listitems[i].name);
+		}
+	    }
+	}
+	dlg_add_last_key(separate_output);
+    }
+
+    dlg_free_columns(&listitems[0].text, (int) sizeof(DIALOG_LISTITEM), item_no);
+    free(listitems);
+    return result;
+}
Index: build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/dialog-1.2-20140112-new/menubox.c
===================================================================
--- build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/dialog-1.2-20140112-new/menubox.c	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/dialog-1.2-20140112-new/menubox.c	(revision 231)
@@ -0,0 +1,778 @@
+/*
+ *  $Id: menubox.c,v 1.148 2013/09/02 17:15:13 tom Exp $
+ *
+ *  menubox.c -- implements the menu box
+ *
+ *  Copyright 2000-2012,2013	Thomas E. Dickey
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public Licens, version 2.1e
+ *  as published by the Free Software Foundation.
+ *
+ *  This program 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 this program; if not, write to
+ *	Free Software Foundation, Inc.
+ *	51 Franklin St., Fifth Floor
+ *	Boston, MA 02110, USA.
+ *
+ *  An earlier version of this program lists as authors
+ *	Savio Lam (lam836@cs.cuhk.hk)
+ */
+
+#include <dialog.h>
+#include <dlg_keys.h>
+
+typedef enum {
+    Unselected = 0,
+    Selected,
+    Editing
+} Mode;
+
+typedef struct {
+    /* the outer-window */
+    WINDOW *dialog;
+    int box_y;
+    int box_x;
+    int tag_x;
+    int item_x;
+    int menu_height;
+    int menu_width;
+    /* the inner-window */
+    WINDOW *menu;
+    DIALOG_LISTITEM *items;
+    int item_no;
+} ALL_DATA;
+
+#define MIN_HIGH  4
+
+#define INPUT_ROWS     3	/* rows per inputmenu entry */
+
+#define RowHeight(i) (is_inputmenu ? ((i) * INPUT_ROWS) : ((i) * 1))
+#define ItemToRow(i) (is_inputmenu ? ((i) * INPUT_ROWS + 1) : (i))
+#define RowToItem(i) (is_inputmenu ? ((i) / INPUT_ROWS + 0) : (i))
+
+/*
+ * Print menu item
+ */
+static void
+print_item(ALL_DATA * data,
+	   WINDOW *win,
+	   DIALOG_LISTITEM * item,
+	   int choice,
+	   Mode selected,
+	   bool is_inputmenu)
+{
+    chtype save = dlg_get_attrs(win);
+    int n;
+    int climit = (data->item_x - data->tag_x - GUTTER);
+    int my_width = data->menu_width;
+    int my_x = data->item_x;
+    int my_y = ItemToRow(choice);
+    bool both = (!dialog_vars.no_tags && !dialog_vars.no_items);
+    bool first = TRUE;
+    chtype bordchar;
+    const char *show = (dialog_vars.no_items
+			? item->name
+			: item->text);
+
+    switch (selected) {
+    default:
+    case Unselected:
+	bordchar = item_attr;
+	break;
+    case Selected:
+	bordchar = item_selected_attr;
+	break;
+    case Editing:
+	bordchar = dialog_attr;
+	break;
+    }
+
+    /* Clear 'residue' of last item and mark current current item */
+    if (is_inputmenu) {
+	(void) wattrset(win, (selected != Unselected) ? item_selected_attr : item_attr);
+	for (n = my_y - 1; n < my_y + INPUT_ROWS - 1; n++) {
+	    wmove(win, n, 0);
+	    wprintw(win, "%*s", my_width, " ");
+	}
+    } else {
+	(void) wattrset(win, menubox_attr);
+	wmove(win, my_y, 0);
+	wprintw(win, "%*s", my_width, " ");
+    }
+
+    /* highlight first char of the tag to be special */
+    if (both) {
+	(void) wmove(win, my_y, data->tag_x);
+	dlg_print_listitem(win, item->name, climit, first, selected);
+	first = FALSE;
+    }
+
+    /* Draw the input field box (only for inputmenu) */
+    (void) wmove(win, my_y, my_x);
+    if (is_inputmenu) {
+	my_width -= 1;
+	dlg_draw_box(win, my_y - 1, my_x, INPUT_ROWS, my_width - my_x - data->tag_x,
+		     bordchar,
+		     bordchar);
+	my_width -= 1;
+	++my_x;
+    }
+
+    /* print actual item */
+    wmove(win, my_y, my_x);
+    dlg_print_listitem(win, show, my_width - my_x, first, selected);
+
+    if (selected) {
+	dlg_item_help(item->help);
+    }
+    (void) wattrset(win, save);
+}
+
+/*
+ * Allow the user to edit the text of a menu entry.
+ */
+static int
+input_menu_edit(ALL_DATA * data,
+		DIALOG_LISTITEM * items,
+		int choice,
+		char **resultp)
+{
+    chtype save = dlg_get_attrs(data->menu);
+    char *result;
+    int offset = 0;
+    int key = 0, fkey = 0;
+    int first = TRUE;
+    /* see above */
+    bool is_inputmenu = TRUE;
+    int y = ItemToRow(choice);
+    int code = TRUE;
+    int max_len = dlg_max_input(MAX((int) strlen(items->text) + 1, MAX_LEN));
+
+    result = dlg_malloc(char, (size_t) max_len);
+    assert_ptr(result, "input_menu_edit");
+
+    /* original item is used to initialize the input string. */
+    result[0] = '\0';
+    strcpy(result, items->text);
+
+    print_item(data, data->menu, items, choice, Editing, TRUE);
+
+    /* taken out of inputbox.c - but somewhat modified */
+    for (;;) {
+	if (!first)
+	    key = dlg_mouse_wgetch(data->menu, &fkey);
+	if (dlg_edit_string(result, &offset, key, fkey, first)) {
+	    dlg_show_string(data->menu, result, offset, inputbox_attr,
+			    y,
+			    data->item_x + 1,
+			    data->menu_width - data->item_x - 3,
+			    FALSE, first);
+	    first = FALSE;
+	} else if (key == ESC || key == TAB) {
+	    code = FALSE;
+	    break;
+	} else {
+	    break;
+	}
+    }
+    print_item(data, data->menu, items, choice, Selected, TRUE);
+    (void) wattrset(data->menu, save);
+
+    *resultp = result;
+    return code;
+}
+
+static int
+handle_button(int code, DIALOG_LISTITEM * items, int choice)
+{
+    char *help_result;
+
+    switch (code) {
+    case DLG_EXIT_OK:		/* FALLTHRU */
+    case DLG_EXIT_EXTRA:
+	dlg_add_string(items[choice].name);
+	break;
+    case DLG_EXIT_HELP:
+	dlg_add_help_listitem(&code, &help_result, &items[choice]);
+	dlg_add_string(help_result);
+	break;
+    }
+    return code;
+}
+
+int
+dlg_renamed_menutext(DIALOG_LISTITEM * items, int current, char *newtext)
+{
+    if (dialog_vars.input_result)
+	dialog_vars.input_result[0] = '\0';
+    dlg_add_result("RENAMED ");
+    dlg_add_string(items[current].name);
+    dlg_add_result(" ");
+    dlg_add_string(newtext);
+    return DLG_EXIT_EXTRA;
+}
+
+int
+dlg_dummy_menutext(DIALOG_LISTITEM * items, int current, char *newtext)
+{
+    (void) items;
+    (void) current;
+    (void) newtext;
+    return DLG_EXIT_ERROR;
+}
+
+static void
+print_menu(ALL_DATA * data, int choice, int scrollamt, int max_choice, bool is_inputmenu)
+{
+    int i;
+
+    for (i = 0; i < max_choice; i++) {
+	print_item(data,
+		   data->menu,
+		   &data->items[i + scrollamt],
+		   i,
+		   (i == choice) ? Selected : Unselected,
+		   is_inputmenu);
+    }
+
+    /* Clean bottom lines */
+    if (is_inputmenu) {
+	int spare_lines, x_count;
+	spare_lines = data->menu_height % INPUT_ROWS;
+	(void) wattrset(data->menu, menubox_attr);
+	for (; spare_lines; spare_lines--) {
+	    wmove(data->menu, data->menu_height - spare_lines, 0);
+	    for (x_count = 0; x_count < data->menu_width;
+		 x_count++) {
+		waddch(data->menu, ' ');
+	    }
+	}
+    }
+
+    (void) wnoutrefresh(data->menu);
+
+    dlg_draw_scrollbar(data->dialog,
+		       scrollamt,
+		       scrollamt,
+		       scrollamt + max_choice,
+		       data->item_no,
+		       data->box_x,
+		       data->box_x + data->menu_width,
+		       data->box_y,
+		       data->box_y + data->menu_height + 1,
+		       menubox_border2_attr,
+		       menubox_border_attr);
+}
+
+static bool
+check_hotkey(DIALOG_LISTITEM * items, int choice)
+{
+    bool result = FALSE;
+
+    if (dlg_match_char(dlg_last_getc(),
+		       (dialog_vars.no_tags
+			? items[choice].text
+			: items[choice].name))) {
+	result = TRUE;
+    }
+    return result;
+}
+
+/*
+ * This is an alternate interface to 'menu' which allows the application
+ * to read the list item states back directly without putting them in the
+ * output buffer.
+ */
+int
+dlg_menu(const char *title,
+	 const char *cprompt,
+	 int height,
+	 int width,
+	 int menu_height,
+	 int item_no,
+	 DIALOG_LISTITEM * items,
+	 int *current_item,
+	 DIALOG_INPUTMENU rename_menutext)
+{
+    /* *INDENT-OFF* */
+    static DLG_KEYS_BINDING binding[] = {
+	HELPKEY_BINDINGS,
+	ENTERKEY_BINDINGS,
+	DLG_KEYS_DATA( DLGK_FIELD_NEXT,	' ' ),
+	DLG_KEYS_DATA( DLGK_FIELD_NEXT,	KEY_RIGHT ),
+	DLG_KEYS_DATA( DLGK_FIELD_NEXT,	TAB ),
+	DLG_KEYS_DATA( DLGK_FIELD_PREV,	KEY_BTAB ),
+	DLG_KEYS_DATA( DLGK_FIELD_PREV,	KEY_LEFT ),
+	DLG_KEYS_DATA( DLGK_ITEM_NEXT,	'+' ),
+	DLG_KEYS_DATA( DLGK_ITEM_NEXT,	KEY_DOWN ),
+	DLG_KEYS_DATA( DLGK_ITEM_NEXT,  CHR_NEXT ),
+	DLG_KEYS_DATA( DLGK_ITEM_PREV,	'-' ),
+	DLG_KEYS_DATA( DLGK_ITEM_PREV,	KEY_UP ),
+	DLG_KEYS_DATA( DLGK_ITEM_PREV,  CHR_PREVIOUS ),
+	DLG_KEYS_DATA( DLGK_PAGE_FIRST,	KEY_HOME ),
+	DLG_KEYS_DATA( DLGK_PAGE_LAST,	KEY_END ),
+	DLG_KEYS_DATA( DLGK_PAGE_LAST,	KEY_LL ),
+	DLG_KEYS_DATA( DLGK_PAGE_NEXT,	KEY_NPAGE ),
+	DLG_KEYS_DATA( DLGK_PAGE_PREV,	KEY_PPAGE ),
+	END_KEYS_BINDING
+    };
+    static DLG_KEYS_BINDING binding2[] = {
+	INPUTSTR_BINDINGS,
+	HELPKEY_BINDINGS,
+	ENTERKEY_BINDINGS,
+	END_KEYS_BINDING
+    };
+    /* *INDENT-ON* */
+
+#ifdef KEY_RESIZE
+    int old_height = height;
+    int old_width = width;
+#endif
+    ALL_DATA all;
+    int i, j, x, y, cur_x, cur_y;
+    int key = 0, fkey;
+    int button = dialog_state.visit_items ? -1 : dlg_default_button();
+    int choice = dlg_default_listitem(items);
+    int result = DLG_EXIT_UNKNOWN;
+    int scrollamt = 0;
+    int max_choice;
+    int found;
+    int use_width, name_width, text_width, list_width;
+    WINDOW *dialog, *menu;
+    char *prompt = dlg_strclone(cprompt);
+    const char **buttons = dlg_ok_labels();
+    bool is_inputmenu = ((rename_menutext != 0)
+			 && (rename_menutext != dlg_dummy_menutext));
+
+    all.items = items;
+    all.item_no = item_no;
+
+    dlg_does_output();
+    dlg_tab_correct_str(prompt);
+
+#ifdef KEY_RESIZE
+  retry:
+#endif
+
+    all.menu_height = menu_height;
+    use_width = dlg_calc_list_width(item_no, items) + 10;
+    use_width = MAX(26, use_width);
+    if (all.menu_height == 0) {
+	/* calculate height without items (4) */
+	dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, use_width);
+	dlg_calc_listh(&height, &all.menu_height, item_no);
+    } else {
+	dlg_auto_size(title, prompt,
+		      &height, &width,
+		      MIN_HIGH + all.menu_height, use_width);
+    }
+    dlg_button_layout(buttons, &width);
+    dlg_print_size(height, width);
+    dlg_ctl_size(height, width);
+
+    x = dlg_box_x_ordinate(width);
+    y = dlg_box_y_ordinate(height);
+
+    dialog = dlg_new_window(height, width, y, x);
+    all.dialog = dialog;
+
+    dlg_register_window(dialog, "menubox", binding);
+    dlg_register_buttons(dialog, "menubox", buttons);
+
+    dlg_mouse_setbase(x, y);
+
+    dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr);
+    dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr);
+    dlg_draw_title(dialog, title);
+
+    (void) wattrset(dialog, dialog_attr);
+    dlg_print_autowrap(dialog, prompt, height, width);
+
+    all.menu_width = width - 6;
+    getyx(dialog, cur_y, cur_x);
+    all.box_y = cur_y + 1;
+    all.box_x = (width - all.menu_width) / 2 - 1;
+
+    /*
+     * After displaying the prompt, we know how much space we really have.
+     * Limit the list to avoid overwriting the ok-button.
+     */
+    if (all.menu_height + MIN_HIGH > height - cur_y)
+	all.menu_height = height - MIN_HIGH - cur_y;
+    if (all.menu_height <= 0)
+	all.menu_height = 1;
+
+    /* Find out maximal number of displayable items at once. */
+    max_choice = MIN(all.menu_height,
+		     RowHeight(item_no));
+    if (is_inputmenu)
+	max_choice /= INPUT_ROWS;
+
+    /* create new window for the menu */
+    menu = dlg_sub_window(dialog, all.menu_height, all.menu_width,
+			  y + all.box_y + 1,
+			  x + all.box_x + 1);
+    all.menu = menu;
+
+    dlg_register_window(menu, "menu", binding2);
+    dlg_register_buttons(menu, "menu", buttons);
+
+    /* draw a box around the menu items */
+    dlg_draw_box(dialog,
+		 all.box_y, all.box_x,
+		 all.menu_height + 2, all.menu_width + 2,
+		 menubox_border_attr, menubox_border2_attr);
+
+    name_width = 0;
+    text_width = 0;
+
+    /* Find length of longest item to center menu  *
+     * only if --menu was given, using --inputmenu *
+     * won't be centered.                         */
+    for (i = 0; i < item_no; i++) {
+	name_width = MAX(name_width, dlg_count_columns(items[i].name));
+	text_width = MAX(text_width, dlg_count_columns(items[i].text));
+    }
+
+    /* If the name+text is wider than the list is allowed, then truncate
+     * one or both of them.  If the name is no wider than 30% of the list,
+     * leave it intact.
+     *
+     * FIXME: the gutter width and name/list ratio should be configurable.
+     */
+    use_width = (all.menu_width - GUTTER);
+    if (dialog_vars.no_tags) {
+	list_width = MIN(use_width, text_width);
+    } else if (dialog_vars.no_items) {
+	list_width = MIN(use_width, name_width);
+    } else {
+	if (text_width >= 0
+	    && name_width >= 0
+	    && use_width > 0
+	    && text_width + name_width > use_width) {
+	    int need = (int) (0.30 * use_width);
+	    if (name_width > need) {
+		int want = (int) (use_width
+				  * ((double) name_width)
+				  / (text_width + name_width));
+		name_width = (want > need) ? want : need;
+	    }
+	    text_width = use_width - name_width;
+	}
+	list_width = (text_width + name_width);
+    }
+
+    all.tag_x = (is_inputmenu
+		 ? 0
+		 : (use_width - list_width) / 2);
+    all.item_x = ((dialog_vars.no_tags
+		   ? 0
+		   : (dialog_vars.no_items
+		      ? 0
+		      : (GUTTER + name_width)))
+		  + all.tag_x);
+
+    if (choice - scrollamt >= max_choice) {
+	scrollamt = choice - (max_choice - 1);
+	choice = max_choice - 1;
+    }
+
+    print_menu(&all, choice, scrollamt, max_choice, is_inputmenu);
+
+    /* register the new window, along with its borders */
+    dlg_mouse_mkbigregion(all.box_y + 1, all.box_x,
+			  all.menu_height + 2, all.menu_width + 2,
+			  KEY_MAX, 1, 1, 1 /* by lines */ );
+
+    dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width);
+
+    dlg_trace_win(dialog);
+    while (result == DLG_EXIT_UNKNOWN) {
+	if (button < 0)		/* --visit-items */
+	    wmove(dialog,
+		  all.box_y + ItemToRow(choice) + 1,
+		  all.box_x + all.tag_x + 1);
+
+	key = dlg_mouse_wgetch(dialog, &fkey);
+	if (dlg_result_key(key, fkey, &result))
+	    break;
+
+	found = FALSE;
+	if (fkey) {
+	    /*
+	     * Allow a mouse-click on a box to switch selection to that box.
+	     * Handling a button click is a little more complicated, since we
+	     * push a KEY_ENTER back onto the input stream so we'll put the
+	     * cursor at the right place before handling the "keypress".
+	     */
+	    if (key >= DLGK_MOUSE(KEY_MAX)) {
+		key -= DLGK_MOUSE(KEY_MAX);
+		i = RowToItem(key);
+		if (i < max_choice) {
+		    found = TRUE;
+		} else {
+		    beep();
+		    continue;
+		}
+	    } else if (is_DLGK_MOUSE(key)
+		       && dlg_ok_buttoncode(key - M_EVENT) >= 0) {
+		button = (key - M_EVENT);
+		ungetch('\n');
+		continue;
+	    }
+	} else {
+	    /*
+	     * Check if key pressed matches first character of any item tag in
+	     * list.  If there is more than one match, we will cycle through
+	     * each one as the same key is pressed repeatedly.
+	     */
+	    if (button < 0 || !dialog_state.visit_items) {
+		for (j = scrollamt + choice + 1; j < item_no; j++) {
+		    if (check_hotkey(items, j)) {
+			found = TRUE;
+			i = j - scrollamt;
+			break;
+		    }
+		}
+		if (!found) {
+		    for (j = 0; j <= scrollamt + choice; j++) {
+			if (check_hotkey(items, j)) {
+			    found = TRUE;
+			    i = j - scrollamt;
+			    break;
+			}
+		    }
+		}
+		if (found)
+		    dlg_flush_getc();
+	    } else if ((j = dlg_char_to_button(key, buttons)) >= 0) {
+		button = j;
+		ungetch('\n');
+		continue;
+	    }
+
+	    /*
+	     * A single digit (1-9) positions the selection to that line in the
+	     * current screen.
+	     */
+	    if (!found
+		&& (key <= '9')
+		&& (key > '0')
+		&& (key - '1' < max_choice)) {
+		found = TRUE;
+		i = key - '1';
+	    }
+	}
+
+	if (!found && fkey) {
+	    found = TRUE;
+	    switch (key) {
+	    case DLGK_PAGE_FIRST:
+		i = -scrollamt;
+		break;
+	    case DLGK_PAGE_LAST:
+		i = item_no - 1 - scrollamt;
+		break;
+	    case DLGK_MOUSE(KEY_PPAGE):
+	    case DLGK_PAGE_PREV:
+		if (choice)
+		    i = 0;
+		else if (scrollamt != 0)
+		    i = -MIN(scrollamt, max_choice);
+		else
+		    continue;
+		break;
+	    case DLGK_MOUSE(KEY_NPAGE):
+	    case DLGK_PAGE_NEXT:
+		i = MIN(choice + max_choice, item_no - scrollamt - 1);
+		break;
+	    case DLGK_ITEM_PREV:
+		i = choice - 1;
+		if (choice == 0 && scrollamt == 0)
+		    continue;
+		break;
+	    case DLGK_ITEM_NEXT:
+		i = choice + 1;
+		if (scrollamt + choice >= item_no - 1)
+		    continue;
+		break;
+	    default:
+		found = FALSE;
+		break;
+	    }
+	}
+
+	if (found) {
+	    if (i != choice) {
+		getyx(dialog, cur_y, cur_x);
+		if (i < 0 || i >= max_choice) {
+		    if (i < 0) {
+			scrollamt += i;
+			choice = 0;
+		    } else {
+			choice = max_choice - 1;
+			scrollamt += (i - max_choice + 1);
+		    }
+		    print_menu(&all, choice, scrollamt, max_choice, is_inputmenu);
+		} else {
+		    choice = i;
+		    print_menu(&all, choice, scrollamt, max_choice, is_inputmenu);
+		    (void) wmove(dialog, cur_y, cur_x);
+		    wrefresh(dialog);
+		}
+	    }
+	    continue;		/* wait for another key press */
+	}
+
+	if (fkey) {
+	    switch (key) {
+	    case DLGK_FIELD_PREV:
+		button = dlg_prev_button(buttons, button);
+		dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+				 FALSE, width);
+		break;
+	    case DLGK_FIELD_NEXT:
+		button = dlg_next_button(buttons, button);
+		dlg_draw_buttons(dialog, height - 2, 0, buttons, button,
+				 FALSE, width);
+		break;
+	    case DLGK_ENTER:
+		if (is_inputmenu)
+		    result = dlg_ok_buttoncode(button);
+		else
+		    result = dlg_enter_buttoncode(button);
+
+		/*
+		 * If dlg_menu() is called from dialog_menu(), we want to
+		 * capture the results into dialog_vars.input_result.
+		 */
+		if (result == DLG_EXIT_ERROR) {
+		    result = DLG_EXIT_UNKNOWN;
+		} else if (is_inputmenu
+			   || rename_menutext == dlg_dummy_menutext) {
+		    result = handle_button(result,
+					   items,
+					   scrollamt + choice);
+		}
+
+		/*
+		 * If we have a rename_menutext function, interpret the Extra
+		 * button as a request to rename the menu's text.  If that
+		 * function doesn't return "Unknown", we will exit from this
+		 * function.  Usually that is done for dialog_menu(), so the
+		 * shell script can use the updated value.  If it does return
+		 * "Unknown", update the list item only.  A direct caller of
+		 * dlg_menu() can free the renamed value - we cannot.
+		 */
+		if (is_inputmenu && result == DLG_EXIT_EXTRA) {
+		    char *tmp;
+
+		    if (input_menu_edit(&all,
+					&items[scrollamt + choice],
+					choice,
+					&tmp)) {
+			result = rename_menutext(items, scrollamt + choice, tmp);
+			if (result == DLG_EXIT_UNKNOWN) {
+			    items[scrollamt + choice].text = tmp;
+			} else {
+			    free(tmp);
+			}
+		    } else {
+			result = DLG_EXIT_UNKNOWN;
+			print_item(&all,
+				   menu,
+				   &items[scrollamt + choice],
+				   choice,
+				   Selected,
+				   is_inputmenu);
+			(void) wnoutrefresh(menu);
+			free(tmp);
+		    }
+
+		    if (result == DLG_EXIT_UNKNOWN) {
+			dlg_draw_buttons(dialog, height - 2, 0,
+					 buttons, button, FALSE, width);
+		    }
+		}
+		break;
+#ifdef KEY_RESIZE
+	    case KEY_RESIZE:
+		/* reset data */
+		height = old_height;
+		width = old_width;
+		/* repaint */
+		dlg_clear();
+		dlg_del_window(dialog);
+		refresh();
+		dlg_mouse_free_regions();
+		goto retry;
+#endif
+	    default:
+		flash();
+		break;
+	    }
+	}
+    }
+
+    dlg_mouse_free_regions();
+    dlg_unregister_window(menu);
+    dlg_del_window(dialog);
+    free(prompt);
+
+    *current_item = scrollamt + choice;
+    return result;
+}
+
+/*
+ * Display a menu for choosing among a number of options
+ */
+int
+dialog_menu(const char *title,
+	    const char *cprompt,
+	    int height,
+	    int width,
+	    int menu_height,
+	    int item_no,
+	    char **items)
+{
+    int result;
+    int choice;
+    int i, j;
+    DIALOG_LISTITEM *listitems;
+
+    listitems = dlg_calloc(DIALOG_LISTITEM, (size_t) item_no + 1);
+    assert_ptr(listitems, "dialog_menu");
+
+    for (i = j = 0; i < item_no; ++i) {
+	listitems[i].name = items[j++];
+	listitems[i].text = (dialog_vars.no_items
+			     ? dlg_strempty()
+			     : items[j++]);
+	listitems[i].help = ((dialog_vars.item_help)
+			     ? items[j++]
+			     : dlg_strempty());
+    }
+    dlg_align_columns(&listitems[0].text, sizeof(DIALOG_LISTITEM), item_no);
+
+    result = dlg_menu(title,
+		      cprompt,
+		      height,
+		      width,
+		      menu_height,
+		      item_no,
+		      listitems,
+		      &choice,
+		      (dialog_vars.input_menu
+		       ? dlg_renamed_menutext
+		       : dlg_dummy_menutext));
+
+    dlg_free_columns(&listitems[0].text, sizeof(DIALOG_LISTITEM), item_no);
+    free(listitems);
+    return result;
+}
Index: build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/file.list
===================================================================
--- build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/file.list	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/dialog/create-1.2-20140112-patch/file.list	(revision 231)
@@ -0,0 +1,3 @@
+dialog-1.2-20140112/checklist.c
+dialog-1.2-20140112/fselect.c
+dialog-1.2-20140112/menubox.c
Index: build-system-1.2.3/3pp/sources/packages/genext2fs/Makefile
===================================================================
--- build-system-1.2.3/3pp/sources/packages/genext2fs/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/genext2fs/Makefile	(revision 231)
@@ -0,0 +1,56 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/packages/a/genext2fs
+
+versions    = 1.4.1
+
+tarballs    = $(addsuffix .tar.gz, $(addprefix genext2fs-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+patches     = $(CURDIR)/patches/genext2fs-1.4.1-blocksize.patch
+patches    += $(CURDIR)/patches/genext2fs-1.4.1-configure.patch
+
+.NOTPARALLEL: $(patches)
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s) $(patches)
+
+
+include ../../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+$(patches): $(sha1s)
+	@echo -e "\n======= Create Patches =======\n" ; \
+	 ( cd create-1.4.1-blocksize-patch ; ./create.patch.sh ) ; \
+	 ( cd create-1.4.1-configure-patch ; ./create.patch.sh ) ; \
+	 echo -e "\n"
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s) $(patches)
Index: build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/create.patch.sh
===================================================================
--- build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/create.patch.sh	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/create.patch.sh	(revision 231)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=1.4.1
+
+tar --files-from=file.list -xzvf ../genext2fs-$VERSION.tar.gz
+mv genext2fs-$VERSION genext2fs-$VERSION-orig
+
+cp -rf ./genext2fs-$VERSION-new ./genext2fs-$VERSION
+
+diff -b --unified -Nr  genext2fs-$VERSION-orig  genext2fs-$VERSION > genext2fs-$VERSION-blocksize.patch
+
+mv genext2fs-$VERSION-blocksize.patch ../patches
+
+rm -rf ./genext2fs-$VERSION
+rm -rf ./genext2fs-$VERSION-orig

Property changes on: build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/file.list
===================================================================
--- build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/file.list	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/file.list	(revision 231)
@@ -0,0 +1,5 @@
+genext2fs-1.4.1/genext2fs.8
+genext2fs-1.4.1/genext2fs.c
+genext2fs-1.4.1/test-gen.lib
+genext2fs-1.4.1/test-mount.sh
+genext2fs-1.4.1/test.sh
Index: build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/genext2fs.8
===================================================================
--- build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/genext2fs.8	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/genext2fs.8	(revision 231)
@@ -0,0 +1,178 @@
+.\"                                      Hey, EMACS: -*- nroff -*-
+.\" First parameter, NAME, should be all caps
+.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
+.\" other parameters are allowed: see man(7), man(1)
+.TH GENEXT2FS 8 "October 11, 2015"
+.\" Please adjust this date whenever revising the manpage.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh        disable hyphenation
+.\" .hy        enable hyphenation
+.\" .ad l      left justify
+.\" .ad b      justify to both left and right margins
+.\" .nf        disable filling
+.\" .fi        enable filling
+.\" .br        insert line break
+.\" .sp <n>    insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+genext2fs \- ext2 filesystem generator for embedded systems
+.SH SYNOPSIS
+.B genext2fs
+.RI "[ options ] [ output\-image ]"
+.SH DESCRIPTION
+\fBgenext2fs\fP generates an ext2 filesystem
+as a normal (non-root) user. It does not require you to mount
+the image file to copy files on it, nor does it require that
+you become the superuser to make device nodes.
+
+The filesystem image is created in the file \fIoutput-image\fP. If not
+specified, it is sent to stdout.
+
+By default, the maximum number of inodes in the filesystem is the minimum
+number required to accommodate the initial contents.
+In this way, a minimal filesystem (typically read-only) can be created with
+minimal free inodes.
+If required, free inodes can be added by passing the relevant options.
+The filesystem image size in blocks can be minimised by trial and error.
+.SH OPTIONS
+.TP
+.BI "\-x, \-\-starting\-image image"
+Use this image as a starting point.
+.TP
+.BI "\-d, \-\-root directory[:path]"
+Add the given directory and contents at a particular path (by default
+the root).
+.TP
+.BI "\-D, \-\-devtable spec\-file[:path]"
+Use \fBspec-file\fP to specify inodes to be added, at the given
+path (by default the root), including files, directories and
+special files like devices.
+If the specified files are already present in the image, their
+ownership and permission modes will be adjusted accordingly.
+Furthermore, you can use a single table entry to create many devices
+with a range of minor numbers (see examples below).
+All specified inodes receive the mtime of \fBspec-file\fP itself.
+.TP
+.BI "\-B, \-\-block\-size bytes"
+Size of the block (valid block sizes: 1024, 20148 or 4096 bytes).
+.TP
+.BI "\-b, \-\-size\-in\-blocks blocks"
+Size of the image in blocks.
+.TP
+.BI "\-N, \-\-number\-of\-inodes inodes"
+Maximum number of inodes.
+.TP
+.BI "\-i, \-\-bytes\-per\-inode ratio"
+Used to calculate the maximum number of inodes from the available blocks.
+.TP
+.BI "\-m, \-\-reserved\-percentage"
+Number of reserved blocks as a percentage of size. Reserving 0 blocks will prevent creation of the "lost+found" directory.
+.TP
+.BI "\-o, \-\-creator\-os OS"
+The default value for Creator OS ('linux', 'hurd', 'freebsd' or a numerical value: 0, 1, 3).
+.TP
+.BI "\-g, \-\-block\-map path"
+Generate a block map file for this path.
+.TP
+.BI "\-e, \-\-fill\-value value"
+Fill unallocated blocks with value.
+.TP
+.BI "\-z, \-\-allow\-holes"
+Make files with holes.
+.TP
+.BI "\-f, \-\-faketime"
+Use a timestamp of 0 for inode and filesystem creation, instead of the present. Useful for testing.
+.TP
+.BI "\-q, \-\-squash"
+Squash permissions and owners (same as -P -U).
+.TP
+.BI "\-U, \-\-squash\-uids"
+Squash ownership of inodes added using the -d option, making them all
+owned by root:root.
+.TP
+.BI "\-P, \-\-squash\-perms"
+Squash permissions of inodes added using the -d option. Analogous to
+"umask 077".
+.TP
+.BI "\-v, \-\-verbose"
+Print resulting filesystem structure.
+.TP
+.BI "\-V, \-\-version"
+Print genext2fs version.
+.TP
+.BI "\-h, \-\-help"
+Display help.
+.SH EXAMPLES
+
+.EX
+.B
+genext2fs -b 1440 -d src /dev/fd0
+.EE
+
+All files in the 
+.I src
+directory will be written to
+.B /dev/fd0
+as a new ext2 filesystem image. You can then mount the floppy as
+usual.
+
+.EX
+.B
+genext2fs -b 1024 -d src -D device_table.txt flashdisk.img
+.EE
+
+This example builds a filesystem from all the files in 
+.I src,
+then device nodes are created based on the contents of the file
+.I device_table.txt.
+Entries in the device table take the form of:
+
+<name> <type> <mode> <uid> <gid> <major> <minor> <start> <inc> <count>
+
+where name is the file name and type can be one of: 
+.RS
+.nf
+f	A regular file
+d	Directory
+c	Character special device file
+b	Block special device file
+p	Fifo (named pipe)
+.fi
+.RE
+uid is the user id for the target file, gid is the group id for the
+target file.  The rest of the entries (major, minor, etc) apply only 
+to device special files.
+
+An example device file follows:
+
+.RS
+.nf
+# name	type mode uid gid major minor start inc count
+
+/dev		d	755	0	0	-	-	-	-	-
+/dev/mem	c	640	0	0	1	1	0	0	-
+/dev/tty	c	666	0	0	5	0	0	0	-
+/dev/tty	c	666	0	0	4	0	0	1	6
+/dev/loop	b	640	0	0	7	0	0	1	2
+/dev/hda	b	640	0	0	3	0	0	0	-
+/dev/hda	b	640	0	0	3	1	1	1	16
+/dev/log	s	666	0	0	-	-	-	-	-
+.fi
+.RE
+
+This device table creates the /dev directory, a character device
+node /dev/mem (major 1, minor 1), and also creates /dev/tty, 
+/dev/tty[0-5], /dev/loop[0-1], /dev/hda, /dev/hda1 to /dev/hda15 and
+/dev/log socket.
+
+.SH SEE ALSO
+.BR mkfs(8),
+.BR genromfs(8),
+.BR mkisofs(8),
+.BR mkfs.jffs2(1)
+.br
+.SH AUTHOR
+This manual page was written by David Kimdon <dwhedon@debian.org>,
+for the Debian GNU/Linux system (but may be used by others).
+Examples provided by Erik Andersen <andersen@codepoet.org>.
Index: build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/genext2fs.c
===================================================================
--- build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/genext2fs.c	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/genext2fs.c	(revision 231)
@@ -0,0 +1,2721 @@
+/* vi: set sw=8 ts=8: */
+// genext2fs.c
+//
+// ext2 filesystem generator for embedded systems
+// Copyright (C) 2000 Xavier Bestel <xavier.bestel@free.fr>
+//
+// Please direct support requests to genext2fs-devel@lists.sourceforge.net
+//
+// 'du' portions taken from coreutils/du.c in busybox:
+//	Copyright (C) 1999,2000 by Lineo, inc. and John Beppu
+//	Copyright (C) 1999,2000,2001 by John Beppu <beppu@codepoet.org>
+//	Copyright (C) 2002  Edward Betts <edward@debian.org>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version
+// 2 of the License.
+//
+// Changes:
+// 	 3 Jun 2000	Initial release
+// 	 6 Jun 2000	Bugfix: fs size multiple of 8
+// 			Bugfix: fill blocks with inodes
+// 	14 Jun 2000	Bugfix: bad chdir() with -d option
+// 			Bugfix: removed size=8n constraint
+// 			Changed -d file to -f file
+// 			Added -e option
+// 	22 Jun 2000	Changed types for 64bits archs
+// 	24 Jun 2000	Added endianness swap
+// 			Bugfix: bad dir name lookup
+// 	03 Aug 2000	Bugfix: ind. blocks endian swap
+// 	09 Aug 2000	Bugfix: symlinks endian swap
+// 	01 Sep 2000	Bugfix: getopt returns int, not char	proski@gnu.org
+// 	10 Sep 2000	Bugfix: device nodes endianness		xavier.gueguen@col.bsf.alcatel.fr
+// 			Bugfix: getcwd values for Solaris	xavier.gueguen@col.bsf.alcatel.fr
+// 			Bugfix: ANSI scanf for non-GNU C	xavier.gueguen@col.bsf.alcatel.fr
+// 	28 Jun 2001	Bugfix: getcwd differs for Solaris/GNU	mike@sowbug.com
+// 	 8 Mar 2002	Bugfix: endianness swap of x-indirects
+// 	23 Mar 2002	Bugfix: test for IFCHR or IFBLK was flawed
+// 	10 Oct 2002	Added comments,makefile targets,	vsundar@ixiacom.com    
+// 			endianess swap assert check.  
+// 			Copyright (C) 2002 Ixia communications
+// 	12 Oct 2002	Added support for triple indirection	vsundar@ixiacom.com
+// 			Copyright (C) 2002 Ixia communications
+// 	14 Oct 2002	Added support for groups		vsundar@ixiacom.com
+// 			Copyright (C) 2002 Ixia communications
+// 	 5 Jan 2003	Bugfixes: reserved inodes should be set vsundar@usc.edu
+// 			only in the first group; directory names
+// 			need to be null padded at the end; and 
+// 			number of blocks per group should be a 
+// 			multiple of 8. Updated md5 values. 
+// 	 6 Jan 2003	Erik Andersen <andersee@debian.org> added
+// 			mkfs.jffs2 compatible device table support,
+// 			along with -q, -P, -U
+
+
+#include <config.h>
+#include <stdio.h>
+
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#if MAJOR_IN_MKDEV
+# include <sys/mkdev.h>
+#elif MAJOR_IN_SYSMACROS
+# include <sys/sysmacros.h>
+#endif
+
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+# if HAVE_STDDEF_H
+#  include <stddef.h>
+# endif
+#endif
+
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#if HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+#endif
+
+#if HAVE_LIBGEN_H
+# include <libgen.h>
+#endif
+
+#include <stdarg.h>
+#include <assert.h>
+#include <time.h>
+#include <ctype.h>
+#include <errno.h>
+
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#if HAVE_GETOPT_H
+# include <getopt.h>
+#endif
+
+#if HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+struct stats {
+	unsigned long nblocks;
+	unsigned long ninodes;
+};
+
+// block size
+
+static int blocksize = 1024;
+
+#define BLOCKSIZE         blocksize
+#define BLOCKS_PER_GROUP  8192
+#define INODES_PER_GROUP  8192
+/* Percentage of blocks that are reserved.*/
+#define RESERVED_BLOCKS       5/100
+#define MAX_RESERVED_BLOCKS  25/100
+
+/* The default value for s_creator_os. */
+#if defined(__GNU__)
+# define CREATOR_OS  1 /* Hurd */
+#elif defined(__FreeBSD__)
+# define CREATOR_OS  3 /* FreeBSD */
+#else
+# define CREATOR_OS  0 /* Linux */
+#endif
+
+
+// inode block size (why is it != BLOCKSIZE ?!?)
+/* The field i_blocks in the ext2 inode stores the number of data blocks
+   but in terms of 512 bytes. That is what INODE_BLOCKSIZE represents.
+   INOBLK is the number of such blocks in an actual disk block            */
+
+#define INODE_BLOCKSIZE   512
+#define INOBLK            (BLOCKSIZE / INODE_BLOCKSIZE)
+
+// reserved inodes
+
+#define EXT2_BAD_INO         1     // Bad blocks inode
+#define EXT2_ROOT_INO        2     // Root inode
+#define EXT2_ACL_IDX_INO     3     // ACL inode
+#define EXT2_ACL_DATA_INO    4     // ACL inode
+#define EXT2_BOOT_LOADER_INO 5     // Boot loader inode
+#define EXT2_UNDEL_DIR_INO   6     // Undelete directory inode
+#define EXT2_FIRST_INO       11    // First non reserved inode
+
+// magic number for ext2
+
+#define EXT2_MAGIC_NUMBER  0xEF53
+
+
+// direct/indirect block addresses
+
+#define EXT2_NDIR_BLOCKS   11                    // direct blocks
+#define EXT2_IND_BLOCK     12                    // indirect block
+#define EXT2_DIND_BLOCK    13                    // double indirect block
+#define EXT2_TIND_BLOCK    14                    // triple indirect block
+#define EXT2_INIT_BLOCK    0xFFFFFFFF            // just initialized (not really a block address)
+
+// end of a block walk
+
+#define WALK_END           0xFFFFFFFE
+
+// file modes
+
+#define FM_IFMT    0170000	// format mask
+#define FM_IFSOCK  0140000	// socket
+#define FM_IFLNK   0120000	// symbolic link
+#define FM_IFREG   0100000	// regular file
+
+#define FM_IFBLK   0060000	// block device
+#define FM_IFDIR   0040000	// directory
+#define FM_IFCHR   0020000	// character device
+#define FM_IFIFO   0010000	// fifo
+
+#define FM_IMASK   0007777	// *all* perms mask for everything below
+
+#define FM_ISUID   0004000	// SUID
+#define FM_ISGID   0002000	// SGID
+#define FM_ISVTX   0001000	// sticky bit
+
+#define FM_IRWXU   0000700	// entire "user" mask
+#define FM_IRUSR   0000400	// read
+#define FM_IWUSR   0000200	// write
+#define FM_IXUSR   0000100	// execute
+
+#define FM_IRWXG   0000070	// entire "group" mask
+#define FM_IRGRP   0000040	// read
+#define FM_IWGRP   0000020	// write
+#define FM_IXGRP   0000010	// execute
+
+#define FM_IRWXO   0000007	// entire "other" mask
+#define FM_IROTH   0000004	// read
+#define FM_IWOTH   0000002	// write
+#define FM_IXOTH   0000001	// execute
+
+// options
+
+#define OP_HOLES     0x01       // make files with holes
+
+/* Defines for accessing group details */
+
+// Number of groups in the filesystem
+#define GRP_NBGROUPS(fs) \
+	(((fs)->sb.s_blocks_count - fs->sb.s_first_data_block + \
+	  (fs)->sb.s_blocks_per_group - 1) / (fs)->sb.s_blocks_per_group)
+
+// Get group block bitmap (bbm) given the group number
+#define GRP_GET_GROUP_BBM(fs,grp) ( get_blk((fs), get_gd((fs),(grp))->bg_block_bitmap) )
+
+// Get group inode bitmap (ibm) given the group number
+#define GRP_GET_GROUP_IBM(fs,grp) ( get_blk((fs), get_gd((fs),(grp))->bg_inode_bitmap) )
+
+// Given an inode number find the group it belongs to
+#define GRP_GROUP_OF_INODE(fs,nod) ( ((nod)-1) / (fs)->sb.s_inodes_per_group)
+
+//Given an inode number get the inode bitmap that covers it
+#define GRP_GET_INODE_BITMAP(fs,nod) \
+	( GRP_GET_GROUP_IBM((fs),GRP_GROUP_OF_INODE((fs),(nod))) )
+
+//Given an inode number find its offset within the inode bitmap that covers it
+#define GRP_IBM_OFFSET(fs,nod) \
+	( (nod) - GRP_GROUP_OF_INODE((fs),(nod))*(fs)->sb.s_inodes_per_group )
+
+// Given a block number find the group it belongs to
+#define GRP_GROUP_OF_BLOCK(fs,blk) ( ((blk)-1) / (fs)->sb.s_blocks_per_group)
+	
+//Given a block number get the block bitmap that covers it
+#define GRP_GET_BLOCK_BITMAP(fs,blk) \
+	( GRP_GET_GROUP_BBM((fs),GRP_GROUP_OF_BLOCK((fs),(blk))) )
+
+//Given a block number find its offset within the block bitmap that covers it
+#define GRP_BBM_OFFSET(fs,blk) \
+	( (blk) - GRP_GROUP_OF_BLOCK((fs),(blk))*(fs)->sb.s_blocks_per_group )
+
+
+// used types
+
+typedef signed char int8;
+typedef unsigned char uint8;
+typedef signed short int16;
+typedef unsigned short uint16;
+typedef signed int int32;
+typedef unsigned int uint32;
+
+
+// the GNU C library has a wonderful scanf("%as", string) which will
+// allocate the string with the right size, good to avoid buffer
+// overruns. the following macros use it if available or use a
+// hacky workaround
+// moreover it will define a snprintf() like a sprintf(), i.e.
+// without the buffer overrun checking, to work around bugs in
+// older solaris. Note that this is still not very portable, in that
+// the return value cannot be trusted.
+
+#if 0 /* SCANF_CAN_MALLOC */
+/* C99 define "a" for floating point, so you can have
+   runtime surprise according the library versions    */
+# define SCANF_PREFIX "a"
+# define SCANF_STRING(s) (&s)
+#else
+# define SCANF_PREFIX "511"
+# define SCANF_STRING(s) (s = malloc(512))
+#endif /* SCANF_CAN_MALLOC */
+
+#if PREFER_PORTABLE_SNPRINTF
+static inline int
+portable_snprintf(char *str, size_t n, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+	va_start(ap, fmt);
+	ret = vsprintf(str, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+# define SNPRINTF portable_snprintf
+#else
+# define SNPRINTF snprintf
+#endif /* PREFER_PORTABLE_SNPRINTF */
+
+#if !HAVE_GETLINE
+// getline() replacement for Darwin and Solaris etc.
+// This code uses backward seeks (unless rchunk is set to 1) which can't work
+// on pipes etc. However, add2fs_from_file() only calls getline() for
+// regular files, so a larger rchunk and backward seeks are okay.
+
+ssize_t 
+getdelim(char **lineptr, size_t *n, int delim, FILE *stream)
+{
+	char *p;                    // reads stored here
+	size_t const rchunk = 512;  // number of bytes to read
+	size_t const mchunk = 512;  // number of extra bytes to malloc
+	size_t m = rchunk + 1;      // initial buffer size
+	
+	if (*lineptr) {
+		if (*n < m) {
+			*lineptr = (char*)realloc(*lineptr, m);
+			if (!*lineptr) return -1;
+			*n = m;
+		}
+	} else {
+		*lineptr = (char*)malloc(m);
+		if (!*lineptr) return -1;
+		*n = m;
+	}
+
+	m = 0; // record length including seperator
+
+	do {
+		size_t i;     // number of bytes read etc
+		size_t j = 0; // number of bytes searched
+
+		p = *lineptr + m;
+
+		i = fread(p, 1, rchunk, stream);
+		if (i < rchunk && ferror(stream))
+			return -1;
+		while (j < i) {
+			++j;
+			if (*p++ == (char)delim) {
+				*p = '\0';
+				if (j != i) {
+					if (fseek(stream, j - i, SEEK_CUR))
+						return -1;
+					if (feof(stream))
+						clearerr(stream);
+				}
+				m += j;
+				return m;
+			}
+		}
+
+		m += j;
+		if (feof(stream)) {
+			if (m) return m;
+			if (!i) return -1;
+		}
+
+		// allocate space for next read plus possible null terminator
+		i = ((m + (rchunk + 1 > mchunk ? rchunk + 1 : mchunk) +
+		      mchunk - 1) / mchunk) * mchunk;
+		if (i != *n) {
+			*lineptr = (char*)realloc(*lineptr, i);
+			if (!*lineptr) return -1;
+			*n = i;
+		}
+	} while (1);
+}
+#define getline(a,b,c) getdelim(a,b,'\n',c)
+#endif /* HAVE_GETLINE */
+
+// Convert a numerical string to a float, and multiply the result by an
+// IEC or SI multiplier if provided; supported multipliers are Ki, Mi, Gi, k, M
+// and G.
+
+float
+SI_atof(const char *nptr)
+{
+	float f = 0;
+	float m = 1;
+	char *suffixptr;
+
+#if HAVE_STRTOF
+	f = strtof(nptr, &suffixptr);
+#else
+	f = (float)strtod(nptr, &suffixptr);
+#endif /* HAVE_STRTOF */
+
+	if (*suffixptr) {
+		if (!strcmp(suffixptr, "Ki"))
+			m = 1 << 10;
+		else if (!strcmp(suffixptr, "Mi"))
+			m = 1 << 20;
+		else if (!strcmp(suffixptr, "Gi"))
+			m = 1 << 30;
+		else if (!strcmp(suffixptr, "k"))
+			m = 1000;
+		else if (!strcmp(suffixptr, "M"))
+			m = 1000 * 1000;
+		else if (!strcmp(suffixptr, "G"))
+			m = 1000 * 1000 * 1000;
+	}
+	return f * m;
+}
+
+// endianness swap
+
+static inline uint16
+swab16(uint16 val)
+{
+	return (val >> 8) | (val << 8);
+}
+
+static inline uint32
+swab32(uint32 val)
+{
+	return ((val>>24) | ((val>>8)&0xFF00) |
+			((val<<8)&0xFF0000) | (val<<24));
+}
+
+
+// on-disk structures
+// this trick makes me declare things only once
+// (once for the structures, once for the endianness swap)
+
+#define superblock_decl \
+	udecl32(s_inodes_count)        /* Count of inodes in the filesystem */ \
+	udecl32(s_blocks_count)        /* Count of blocks in the filesystem */ \
+	udecl32(s_r_blocks_count)      /* Count of the number of reserved blocks */ \
+	udecl32(s_free_blocks_count)   /* Count of the number of free blocks */ \
+	udecl32(s_free_inodes_count)   /* Count of the number of free inodes */ \
+	udecl32(s_first_data_block)    /* The first block which contains data */ \
+	udecl32(s_log_block_size)      /* Indicator of the block size */ \
+	decl32(s_log_frag_size)        /* Indicator of the size of the fragments */ \
+	udecl32(s_blocks_per_group)    /* Count of the number of blocks in each block group */ \
+	udecl32(s_frags_per_group)     /* Count of the number of fragments in each block group */ \
+	udecl32(s_inodes_per_group)    /* Count of the number of inodes in each block group */ \
+	udecl32(s_mtime)               /* The time that the filesystem was last mounted */ \
+	udecl32(s_wtime)               /* The time that the filesystem was last written to */ \
+	udecl16(s_mnt_count)           /* The number of times the file system has been mounted */ \
+	decl16(s_max_mnt_count)        /* The number of times the file system can be mounted */ \
+	udecl16(s_magic)               /* Magic number indicating ex2fs */ \
+	udecl16(s_state)               /* Flags indicating the current state of the filesystem */ \
+	udecl16(s_errors)              /* Flags indicating the procedures for error reporting */ \
+	udecl16(s_minor_rev_level)     /* The minor revision level of the filesystem */ \
+	udecl32(s_lastcheck)           /* The time that the filesystem was last checked */ \
+	udecl32(s_checkinterval)       /* The maximum time permissable between checks */ \
+	udecl32(s_creator_os)          /* Indicator of which OS created the filesystem */ \
+	udecl32(s_rev_level)           /* The revision level of the filesystem */ \
+	udecl16(s_def_resuid)          /* The default uid for reserved blocks */ \
+	udecl16(s_def_resgid)          /* The default gid for reserved blocks */
+
+#define groupdescriptor_decl \
+	udecl32(bg_block_bitmap)       /* Block number of the block bitmap */ \
+	udecl32(bg_inode_bitmap)       /* Block number of the inode bitmap */ \
+	udecl32(bg_inode_table)        /* Block number of the inode table */ \
+	udecl16(bg_free_blocks_count)  /* Free blocks in the group */ \
+	udecl16(bg_free_inodes_count)  /* Free inodes in the group */ \
+	udecl16(bg_used_dirs_count)    /* Number of directories in the group */ \
+	udecl16(bg_pad)
+
+#define inode_decl \
+	udecl16(i_mode)                /* Entry type and file mode */ \
+	udecl16(i_uid)                 /* User id */ \
+	udecl32(i_size)                /* File/dir size in bytes */ \
+	udecl32(i_atime)               /* Last access time */ \
+	udecl32(i_ctime)               /* Creation time */ \
+	udecl32(i_mtime)               /* Last modification time */ \
+	udecl32(i_dtime)               /* Deletion time */ \
+	udecl16(i_gid)                 /* Group id */ \
+	udecl16(i_links_count)         /* Number of (hard) links to this inode */ \
+	udecl32(i_blocks)              /* Number of blocks used (1 block = 512 bytes) */ \
+	udecl32(i_flags)               /* ??? */ \
+	udecl32(i_reserved1) \
+	utdecl32(i_block,15)           /* Blocks table */ \
+	udecl32(i_version)             /* ??? */ \
+	udecl32(i_file_acl)            /* File access control list */ \
+	udecl32(i_dir_acl)             /* Directory access control list */ \
+	udecl32(i_faddr)               /* Fragment address */ \
+	udecl8(i_frag)                 /* Fragments count*/ \
+	udecl8(i_fsize)                /* Fragment size */ \
+	udecl16(i_pad1)
+
+#define directory_decl \
+	udecl32(d_inode)               /* Inode entry */ \
+	udecl16(d_rec_len)             /* Total size on record */ \
+	udecl16(d_name_len)            /* Size of entry name */
+
+#define decl8(x) int8 x;
+#define udecl8(x) uint8 x;
+#define decl16(x) int16 x;
+#define udecl16(x) uint16 x;
+#define decl32(x) int32 x;
+#define udecl32(x) uint32 x;
+#define utdecl32(x,n) uint32 x[n];
+
+typedef struct
+{
+	superblock_decl
+	uint32 s_reserved[235];       // Reserved
+} superblock;
+
+typedef struct
+{
+	groupdescriptor_decl
+	uint32 bg_reserved[3];
+} groupdescriptor;
+
+typedef struct
+{
+	inode_decl
+	uint32 i_reserved2[2];
+} inode;
+
+typedef struct
+{
+	directory_decl
+	char d_name[0];
+} directory;
+
+typedef uint8 *block;
+
+/* blockwalker fields:
+   The blockwalker is used to access all the blocks of a file (including
+   the indirection blocks) through repeated calls to walk_bw.  
+   
+   bpdir -> index into the inode->i_block[]. Indicates level of indirection.
+   bnum -> total number of blocks so far accessed. including indirection
+           blocks.
+   bpind,bpdind,bptind -> index into indirection blocks.
+   
+   bpind, bpdind, bptind do *NOT* index into single, double and triple
+   indirect blocks resp. as you might expect from their names. Instead 
+   they are in order the 1st, 2nd & 3rd index to be used
+   
+   As an example..
+   To access data block number 70000:
+        bpdir: 15 (we are doing triple indirection)
+        bpind: 0 ( index into the triple indirection block)
+        bpdind: 16 ( index into the double indirection block)
+        bptind: 99 ( index into the single indirection block)
+	70000 = 12 + 256 + 256*256 + 16*256 + 100 (indexing starts from zero)
+
+   So,for double indirection bpind will index into the double indirection 
+   block and bpdind into the single indirection block. For single indirection
+   only bpind will be used.
+*/
+   
+typedef struct
+{
+	uint32 bnum;
+	uint32 bpdir;
+	uint32 bpind;
+	uint32 bpdind;
+	uint32 bptind;
+} blockwalker;
+
+
+/* Filesystem structure that support groups */
+typedef struct
+{
+	uint8 zero[1024];      // Room for bootloader stuff
+	superblock sb;         // The superblock, always at 1024
+	// group descriptors come next, see get_gd() below
+} filesystem;
+
+// now the endianness swap
+
+#undef decl8
+#undef udecl8
+#undef decl16
+#undef udecl16
+#undef decl32
+#undef udecl32
+#undef utdecl32
+
+#define decl8(x)
+#define udecl8(x)
+#define decl16(x) this->x = swab16(this->x);
+#define udecl16(x) this->x = swab16(this->x);
+#define decl32(x) this->x = swab32(this->x);
+#define udecl32(x) this->x = swab32(this->x);
+#define utdecl32(x,n) { int i; for(i=0; i<n; i++) this->x[i] = swab32(this->x[i]); }
+
+#define HDLINK_CNT   16
+static int32 hdlink_cnt = HDLINK_CNT;
+struct hdlink_s
+{
+	uint32	src_inode;
+	uint32	dst_nod;
+};
+
+struct hdlinks_s 
+{
+	int32 count;
+	struct hdlink_s *hdl;
+};
+
+static struct hdlinks_s hdlinks;
+
+static void
+swap_sb(superblock *sb)
+{
+#define this sb
+	superblock_decl
+#undef this
+}
+
+static void
+swap_gd(groupdescriptor *gd)
+{
+#define this gd
+	groupdescriptor_decl
+#undef this
+}
+
+static void
+swap_nod(inode *nod)
+{
+#define this nod
+	inode_decl
+#undef this
+}
+
+static void
+swap_dir(directory *dir)
+{
+#define this dir
+	directory_decl
+#undef this
+}
+
+static void
+swap_block(block b)
+{
+	int i;
+	uint32 *blk = (uint32*)b;
+	for(i = 0; i < BLOCKSIZE/4; i++)
+		blk[i] = swab32(blk[i]);
+}
+
+#undef decl8
+#undef udecl8
+#undef decl16
+#undef udecl16
+#undef decl32
+#undef udecl32
+#undef utdecl32
+
+static char * app_name;
+static const char *const memory_exhausted = "memory exhausted";
+
+// error (un)handling
+static void
+verror_msg(const char *s, va_list p)
+{
+	fflush(stdout);
+	fprintf(stderr, "%s: ", app_name);
+	vfprintf(stderr, s, p);
+}
+static void
+error_msg(const char *s, ...)
+{
+	va_list p;
+	va_start(p, s);
+	verror_msg(s, p);
+	va_end(p);
+	putc('\n', stderr);
+}
+
+static void
+error_msg_and_die(const char *s, ...)
+{
+	va_list p;
+	va_start(p, s);
+	verror_msg(s, p);
+	va_end(p);
+	putc('\n', stderr);
+	exit(EXIT_FAILURE);
+}
+
+static void
+vperror_msg(const char *s, va_list p)
+{
+	int err = errno;
+	if (s == 0)
+		s = "";
+	verror_msg(s, p);
+	if (*s)
+		s = ": ";
+	fprintf(stderr, "%s%s\n", s, strerror(err));
+}
+
+static void
+perror_msg_and_die(const char *s, ...)
+{
+	va_list p;
+	va_start(p, s);
+	vperror_msg(s, p);
+	va_end(p);
+	exit(EXIT_FAILURE);
+}
+
+static FILE *
+xfopen(const char *path, const char *mode)
+{
+	FILE *fp;
+	if ((fp = fopen(path, mode)) == NULL)
+		perror_msg_and_die("%s", path);
+	return fp;
+}
+
+static char *
+xstrdup(const char *s)
+{
+	char *t;
+
+	if (s == NULL)
+		return NULL;
+	t = strdup(s);
+	if (t == NULL)
+		error_msg_and_die(memory_exhausted);
+	return t;
+}
+
+static void *
+xrealloc(void *ptr, size_t size)
+{
+	ptr = realloc(ptr, size);
+	if (ptr == NULL && size != 0)
+		error_msg_and_die(memory_exhausted);
+	return ptr;
+}
+
+static char *
+xreadlink(const char *path)
+{
+	static const int GROWBY = 80; /* how large we will grow strings by */
+
+	char *buf = NULL;
+	int bufsize = 0, readsize = 0;
+
+	do {
+		buf = xrealloc(buf, bufsize += GROWBY);
+		readsize = readlink(path, buf, bufsize); /* 1st try */
+		if (readsize == -1) {
+			perror_msg_and_die("%s:%s", app_name, path);
+		}
+	}
+	while (bufsize < readsize + 1);
+
+	buf[readsize] = '\0';
+	return buf;
+}
+
+int
+is_hardlink(ino_t inode)
+{
+	int i;
+
+	for(i = 0; i < hdlinks.count; i++) {
+		if(hdlinks.hdl[i].src_inode == inode)
+			return i;
+	}
+	return -1;		
+}
+
+// printf helper macro
+#define plural(a) (a), ((a) > 1) ? "s" : ""
+
+// temporary working block
+static inline uint8 *
+get_workblk(void)
+{
+	unsigned char* b=calloc(1,BLOCKSIZE);
+	return b;
+}
+static inline void
+free_workblk(block b)
+{
+	free(b);
+}
+
+/* Rounds qty upto a multiple of siz. siz should be a power of 2 */
+static inline uint32
+rndup(uint32 qty, uint32 siz)
+{
+	return (qty + (siz - 1)) & ~(siz - 1);
+}
+
+// check if something is allocated in the bitmap
+static inline uint32
+allocated(block b, uint32 item)
+{
+	return b[(item-1) / 8] & (1 << ((item-1) % 8));
+}
+
+// return a given block from a filesystem
+static inline uint8 *
+get_blk(filesystem *fs, uint32 blk)
+{
+	return (uint8*)fs + blk*BLOCKSIZE;
+}
+
+// the group descriptors are aligned on the block size
+static inline groupdescriptor *
+get_gd(filesystem *fs, int no)
+{
+	int gdblk = (sizeof (filesystem) + BLOCKSIZE - 1) / BLOCKSIZE;
+	return ((groupdescriptor *) get_blk(fs, gdblk)) + no;
+}
+
+// return a given inode from a filesystem
+static inline inode *
+get_nod(filesystem *fs, uint32 nod)
+{
+	int grp,offset;
+	inode *itab;
+
+	offset = GRP_IBM_OFFSET(fs,nod);
+	grp = GRP_GROUP_OF_INODE(fs,nod);
+	itab = (inode *)get_blk(fs, get_gd(fs,grp)->bg_inode_table);
+	return itab+offset-1;
+}
+
+// allocate a given block/inode in the bitmap
+// allocate first free if item == 0
+static uint32
+allocate(block b, uint32 item)
+{
+	if(!item)
+	{
+		int i;
+		uint8 bits;
+		for(i = 0; i < BLOCKSIZE; i++)
+			if((bits = b[i]) != (uint8)-1)
+			{
+				int j;
+				for(j = 0; j < 8; j++)
+					if(!(bits & (1 << j)))
+						break;
+				item = i * 8 + j + 1;
+				break;
+			}
+		if(i == BLOCKSIZE)
+			return 0;
+	}
+	b[(item-1) / 8] |= (1 << ((item-1) % 8));
+	return item;
+}
+
+// deallocate a given block/inode
+static void
+deallocate(block b, uint32 item)
+{
+	b[(item-1) / 8] &= ~(1 << ((item-1) % 8));
+}
+
+// allocate a block
+static uint32
+alloc_blk(filesystem *fs, uint32 nod)
+{
+	uint32 bk=0;
+	uint32 grp,nbgroups;
+
+	grp = GRP_GROUP_OF_INODE(fs,nod);
+	nbgroups = GRP_NBGROUPS(fs);
+	if(!(bk = allocate(GRP_GET_GROUP_BBM(fs, grp), 0))) {
+		for(grp=0;grp<nbgroups && !bk;grp++)
+			bk = allocate(GRP_GET_GROUP_BBM(fs, grp), 0);
+		grp--;
+	}
+	if (!bk)
+		error_msg_and_die("couldn't allocate a block (no free space)");
+	if(!(get_gd(fs, grp)->bg_free_blocks_count--))
+		error_msg_and_die("group descr %d. free blocks count == 0 (corrupted fs?)",grp);
+	if(!(fs->sb.s_free_blocks_count--))
+		error_msg_and_die("superblock free blocks count == 0 (corrupted fs?)");
+	return fs->sb.s_first_data_block + fs->sb.s_blocks_per_group*grp + (bk-1);
+}
+
+// free a block
+static void
+free_blk(filesystem *fs, uint32 bk)
+{
+	uint32 grp;
+
+	grp = bk / fs->sb.s_blocks_per_group;
+	bk %= fs->sb.s_blocks_per_group;
+	deallocate(GRP_GET_GROUP_BBM(fs, grp), bk);
+	get_gd(fs, grp)->bg_free_blocks_count++;
+	fs->sb.s_free_blocks_count++;
+}
+
+// allocate an inode
+static uint32
+alloc_nod(filesystem *fs)
+{
+	uint32 nod,best_group=0;
+	uint32 grp,nbgroups,avefreei;
+
+	nbgroups = GRP_NBGROUPS(fs);
+
+	/* Distribute inodes amongst all the blocks                           */
+	/* For every block group with more than average number of free inodes */
+	/* find the one with the most free blocks and allocate node there     */
+	/* Idea from find_group_dir in fs/ext2/ialloc.c in 2.4.19 kernel      */
+	/* We do it for all inodes.                                           */
+	avefreei  =  fs->sb.s_free_inodes_count / nbgroups;
+	for(grp=0; grp<nbgroups; grp++) {
+		if (get_gd(fs, grp)->bg_free_inodes_count < avefreei ||
+		    get_gd(fs, grp)->bg_free_inodes_count == 0)
+			continue;
+		if (!best_group || 
+			get_gd(fs, grp)->bg_free_blocks_count > get_gd(fs, best_group)->bg_free_blocks_count)
+			best_group = grp;
+	}
+	if (!(nod = allocate(GRP_GET_GROUP_IBM(fs, best_group), 0)))
+		error_msg_and_die("couldn't allocate an inode (no free inode)");
+	if(!(get_gd(fs, best_group)->bg_free_inodes_count--))
+		error_msg_and_die("group descr. free blocks count == 0 (corrupted fs?)");
+	if(!(fs->sb.s_free_inodes_count--))
+		error_msg_and_die("superblock free blocks count == 0 (corrupted fs?)");
+	return fs->sb.s_inodes_per_group*best_group+nod;
+}
+
+// print a bitmap allocation
+static void
+print_bm(block b, uint32 max)
+{
+	uint32 i;
+	printf("----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0\n");
+	for(i=1; i <= max; i++)
+	{
+		putchar(allocated(b, i) ? '*' : '.');
+		if(!(i % 100))
+			printf("\n");
+	}
+	if((i-1) % 100)
+		printf("\n");
+}
+
+// initalize a blockwalker (iterator for blocks list)
+static inline void
+init_bw(blockwalker *bw)
+{
+	bw->bnum = 0;
+	bw->bpdir = EXT2_INIT_BLOCK;
+}
+
+// return next block of inode (WALK_END for end)
+// if *create>0, append a newly allocated block at the end
+// if *create<0, free the block - warning, the metadata blocks contents is
+//				  used after being freed, so once you start
+//				  freeing blocks don't stop until the end of
+//				  the file. moreover, i_blocks isn't updated.
+//				  in fact, don't do that, just use extend_blk
+// if hole!=0, create a hole in the file
+static uint32
+walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
+{
+	uint32 *bkref = 0;
+	uint32 *b;
+	int extend = 0, reduce = 0;
+	if(create && (*create) < 0)
+		reduce = 1;
+	if(bw->bnum >= get_nod(fs, nod)->i_blocks / INOBLK)
+	{
+		if(create && (*create) > 0)
+		{
+			(*create)--;
+			extend = 1;
+		}
+		else	
+			return WALK_END;
+	}
+	// first direct block
+	if(bw->bpdir == EXT2_INIT_BLOCK)
+	{
+		bkref = &get_nod(fs, nod)->i_block[bw->bpdir = 0];
+		if(extend) // allocate first block
+			*bkref = hole ? 0 : alloc_blk(fs,nod);
+		if(reduce) // free first block
+			free_blk(fs, *bkref);
+	}
+	// direct block
+	else if(bw->bpdir < EXT2_NDIR_BLOCKS)
+	{
+		bkref = &get_nod(fs, nod)->i_block[++bw->bpdir];
+		if(extend) // allocate block
+			*bkref = hole ? 0 : alloc_blk(fs,nod);
+		if(reduce) // free block
+			free_blk(fs, *bkref);
+	}
+	// first block in indirect block
+	else if(bw->bpdir == EXT2_NDIR_BLOCKS)
+	{
+		bw->bnum++;
+		bw->bpdir = EXT2_IND_BLOCK;
+		bw->bpind = 0;
+		if(extend) // allocate indirect block
+			get_nod(fs, nod)->i_block[bw->bpdir] = alloc_blk(fs,nod);
+		if(reduce) // free indirect block
+			free_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+		b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+		bkref = &b[bw->bpind];
+		if(extend) // allocate first block
+			*bkref = hole ? 0 : alloc_blk(fs,nod);
+		if(reduce) // free first block
+			free_blk(fs, *bkref);
+	}
+	// block in indirect block
+	else if((bw->bpdir == EXT2_IND_BLOCK) && (bw->bpind < BLOCKSIZE/4 - 1))
+	{
+		bw->bpind++;
+		b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+		bkref = &b[bw->bpind];
+		if(extend) // allocate block
+			*bkref = hole ? 0 : alloc_blk(fs,nod);
+		if(reduce) // free block
+			free_blk(fs, *bkref);
+	}
+	// first block in first indirect block in first double indirect block
+	else if(bw->bpdir == EXT2_IND_BLOCK)
+	{
+		bw->bnum += 2;
+		bw->bpdir = EXT2_DIND_BLOCK;
+		bw->bpind = 0;
+		bw->bpdind = 0;
+		if(extend) // allocate double indirect block
+			get_nod(fs, nod)->i_block[bw->bpdir] = alloc_blk(fs,nod);
+		if(reduce) // free double indirect block
+			free_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+		b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+		if(extend) // allocate first indirect block
+			b[bw->bpind] = alloc_blk(fs,nod);
+		if(reduce) // free  firstindirect block
+			free_blk(fs, b[bw->bpind]);
+		b = (uint32*)get_blk(fs, b[bw->bpind]);
+		bkref = &b[bw->bpdind];
+		if(extend) // allocate first block
+			*bkref = hole ? 0 : alloc_blk(fs,nod);
+		if(reduce) // free first block
+			free_blk(fs, *bkref);
+	}
+	// block in indirect block in double indirect block
+	else if((bw->bpdir == EXT2_DIND_BLOCK) && (bw->bpdind < BLOCKSIZE/4 - 1))
+	{
+		bw->bpdind++;
+		b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+		b = (uint32*)get_blk(fs, b[bw->bpind]);
+		bkref = &b[bw->bpdind];
+		if(extend) // allocate block
+			*bkref = hole ? 0 : alloc_blk(fs,nod);
+		if(reduce) // free block
+			free_blk(fs, *bkref);
+	}
+	// first block in indirect block in double indirect block
+	else if((bw->bpdir == EXT2_DIND_BLOCK) && (bw->bpind < BLOCKSIZE/4 - 1))
+	{
+		bw->bnum++;
+		bw->bpdind = 0;
+		bw->bpind++;
+		b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+		if(extend) // allocate indirect block
+			b[bw->bpind] = alloc_blk(fs,nod);
+		if(reduce) // free indirect block
+			free_blk(fs, b[bw->bpind]);
+		b = (uint32*)get_blk(fs, b[bw->bpind]);
+		bkref = &b[bw->bpdind];
+		if(extend) // allocate first block
+			*bkref = hole ? 0 : alloc_blk(fs,nod);
+		if(reduce) // free first block
+			free_blk(fs, *bkref);
+	}
+
+	/* Adding support for triple indirection */
+	/* Just starting triple indirection. Allocate the indirection
+	   blocks and the first data block
+	 */
+	else if (bw->bpdir == EXT2_DIND_BLOCK) 
+	{
+	  	bw->bnum += 3;
+		bw->bpdir = EXT2_TIND_BLOCK;
+		bw->bpind = 0;
+		bw->bpdind = 0;
+		bw->bptind = 0;
+		if(extend) // allocate triple indirect block
+			get_nod(fs, nod)->i_block[bw->bpdir] = alloc_blk(fs,nod);
+		if(reduce) // free triple indirect block
+			free_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+		b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+		if(extend) // allocate first double indirect block
+			b[bw->bpind] = alloc_blk(fs,nod);
+		if(reduce) // free first double indirect block
+			free_blk(fs, b[bw->bpind]);
+		b = (uint32*)get_blk(fs, b[bw->bpind]);
+		if(extend) // allocate first indirect block
+			b[bw->bpdind] = alloc_blk(fs,nod);
+		if(reduce) // free first indirect block
+			free_blk(fs, b[bw->bpind]);
+		b = (uint32*)get_blk(fs, b[bw->bpdind]);
+		bkref = &b[bw->bptind];
+		if(extend) // allocate first data block
+			*bkref = hole ? 0 : alloc_blk(fs,nod);
+		if(reduce) // free first block
+			free_blk(fs, *bkref);
+	}
+	/* Still processing a single indirect block down the indirection
+	   chain.Allocate a data block for it
+	 */
+	else if ( (bw->bpdir == EXT2_TIND_BLOCK) && 
+		  (bw->bptind < BLOCKSIZE/4 -1) )
+	{
+		bw->bptind++;
+		b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+		b = (uint32*)get_blk(fs, b[bw->bpind]);
+		b = (uint32*)get_blk(fs, b[bw->bpdind]);
+		bkref = &b[bw->bptind];
+		if(extend) // allocate data block
+			*bkref = hole ? 0 : alloc_blk(fs,nod);
+		if(reduce) // free block
+			free_blk(fs, *bkref);
+	}
+	/* Finished processing a single indirect block. But still in the 
+	   same double indirect block. Allocate new single indirect block
+	   for it and a data block
+	 */
+	else if ( (bw->bpdir == EXT2_TIND_BLOCK) &&
+		  (bw->bpdind < BLOCKSIZE/4 -1) )
+	{
+		bw->bnum++;
+		bw->bptind = 0;
+		bw->bpdind++;
+		b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+		b = (uint32*)get_blk(fs, b[bw->bpind]);
+		if(extend) // allocate single indirect block
+			b[bw->bpdind] = alloc_blk(fs,nod);
+		if(reduce) // free indirect block
+			free_blk(fs, b[bw->bpind]);
+		b = (uint32*)get_blk(fs, b[bw->bpdind]);
+		bkref = &b[bw->bptind];
+		if(extend) // allocate first data block
+			*bkref = hole ? 0 : alloc_blk(fs,nod);
+		if(reduce) // free first block
+			free_blk(fs, *bkref);
+	}
+	/* Finished processing a double indirect block. Allocate the next
+	   double indirect block and the single,data blocks for it
+	 */
+	else if ( (bw->bpdir == EXT2_TIND_BLOCK) && 
+		  (bw->bpind < BLOCKSIZE/4 - 1) )
+	{
+		bw->bnum += 2;
+		bw->bpdind = 0;
+		bw->bptind = 0;
+		bw->bpind++;
+		b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+		if(extend) // allocate double indirect block
+			b[bw->bpind] = alloc_blk(fs,nod);
+		if(reduce) // free double indirect block
+			free_blk(fs, b[bw->bpind]);
+		b = (uint32*)get_blk(fs, b[bw->bpind]);
+		if(extend) // allocate single indirect block
+			b[bw->bpdind] = alloc_blk(fs,nod);
+		if(reduce) // free indirect block
+			free_blk(fs, b[bw->bpind]);
+		b = (uint32*)get_blk(fs, b[bw->bpdind]);
+		bkref = &b[bw->bptind];
+		if(extend) // allocate first block
+			*bkref = hole ? 0 : alloc_blk(fs,nod);
+		if(reduce) // free first block
+			free_blk(fs, *bkref);
+	}
+	else
+		error_msg_and_die("file too big !"); 
+	/* End change for walking triple indirection */
+
+	if(*bkref)
+	{
+		bw->bnum++;
+		if(!reduce && !allocated(GRP_GET_BLOCK_BITMAP(fs,*bkref), GRP_BBM_OFFSET(fs,*bkref)))
+			error_msg_and_die("[block %d of inode %d is unallocated !]", *bkref, nod);
+	}
+	if(extend)
+		get_nod(fs, nod)->i_blocks = bw->bnum * INOBLK;
+	return *bkref;
+}
+
+// add blocks to an inode (file/dir/etc...)
+static void
+extend_blk(filesystem *fs, uint32 nod, block b, int amount)
+{
+	int create = amount;
+	blockwalker bw, lbw;
+	uint32 bk;
+	init_bw(&bw);
+	if(amount < 0)
+	{
+		uint32 i;
+		for(i = 0; i < get_nod(fs, nod)->i_blocks / INOBLK + amount; i++)
+			walk_bw(fs, nod, &bw, 0, 0);
+		while(walk_bw(fs, nod, &bw, &create, 0) != WALK_END)
+			/*nop*/;
+		get_nod(fs, nod)->i_blocks += amount * INOBLK;
+	}
+	else
+	{
+		lbw = bw;
+		while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)
+			lbw = bw;
+		bw = lbw;
+		while(create)
+		{
+			int i, copyb = 0;
+			if(!(fs->sb.s_reserved[200] & OP_HOLES))
+				copyb = 1;
+			else
+				for(i = 0; i < BLOCKSIZE / 4; i++)
+					if(((int32*)(b + BLOCKSIZE * (amount - create)))[i])
+					{
+						copyb = 1;
+						break;
+					}
+			if((bk = walk_bw(fs, nod, &bw, &create, !copyb)) == WALK_END)
+				break;
+			if(copyb)
+				memcpy(get_blk(fs, bk), b + BLOCKSIZE * (amount - create - 1), BLOCKSIZE);
+		}
+	}
+}
+
+// link an entry (inode #) to a directory
+static void
+add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name)
+{
+	blockwalker bw;
+	uint32 bk;
+	uint8 *b;
+	directory *d;
+	int reclen, nlen;
+	inode *node;
+	inode *pnode;
+
+	pnode = get_nod(fs, dnod);
+	if((pnode->i_mode & FM_IFMT) != FM_IFDIR)
+		error_msg_and_die("can't add '%s' to a non-directory", name);
+	if(!*name)
+		error_msg_and_die("can't create an inode with an empty name");
+	if(strchr(name, '/'))
+		error_msg_and_die("bad name '%s' (contains a slash)", name);
+	nlen = strlen(name);
+	reclen = sizeof(directory) + rndup(nlen, 4);
+	if(reclen > BLOCKSIZE)
+		error_msg_and_die("bad name '%s' (too long)", name);
+	init_bw(&bw);
+	while((bk = walk_bw(fs, dnod, &bw, 0, 0)) != WALK_END) // for all blocks in dir
+	{
+		b = get_blk(fs, bk);
+		// for all dir entries in block
+		for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len))
+		{
+			// if empty dir entry, large enough, use it
+			if((!d->d_inode) && (d->d_rec_len >= reclen))
+			{
+				d->d_inode = nod;
+				node = get_nod(fs, nod);
+				node->i_links_count++;
+				d->d_name_len = nlen;
+				strncpy(d->d_name, name, nlen);
+				return;
+			}
+			// if entry with enough room (last one?), shrink it & use it
+			if(d->d_rec_len >= (sizeof(directory) + rndup(d->d_name_len, 4) + reclen))
+			{
+				reclen = d->d_rec_len;
+				d->d_rec_len = sizeof(directory) + rndup(d->d_name_len, 4);
+				reclen -= d->d_rec_len;
+				d = (directory*) (((int8*)d) + d->d_rec_len);
+				d->d_rec_len = reclen;
+				d->d_inode = nod;
+				node = get_nod(fs, nod);
+				node->i_links_count++;
+				d->d_name_len = nlen;
+				strncpy(d->d_name, name, nlen);
+				return;
+			}
+		}
+	}
+	// we found no free entry in the directory, so we add a block
+	if(!(b = get_workblk()))
+		error_msg_and_die("get_workblk() failed.");
+	d = (directory*)b;
+	d->d_inode = nod;
+	node = get_nod(fs, nod);
+	node->i_links_count++;
+	d->d_rec_len = BLOCKSIZE;
+	d->d_name_len = nlen;
+	strncpy(d->d_name, name, nlen);
+	extend_blk(fs, dnod, b, 1);
+	get_nod(fs, dnod)->i_size += BLOCKSIZE;
+	free_workblk(b);
+}
+
+// find an entry in a directory
+static uint32
+find_dir(filesystem *fs, uint32 nod, const char * name)
+{
+	blockwalker bw;
+	uint32 bk;
+	int nlen = strlen(name);
+	init_bw(&bw);
+	while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)
+	{
+		directory *d;
+		uint8 *b;
+		b = get_blk(fs, bk);
+		for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len))
+			if(d->d_inode && (nlen == d->d_name_len) && !strncmp(d->d_name, name, nlen))
+				return d->d_inode;
+	}
+	return 0;
+}
+
+// find the inode of a full path
+static uint32
+find_path(filesystem *fs, uint32 nod, const char * name)
+{
+	char *p, *n, *n2 = xstrdup(name);
+	n = n2;
+	while(*n == '/')
+	{
+		nod = EXT2_ROOT_INO;
+		n++;
+	}
+	while(*n)
+	{
+		if((p = strchr(n, '/')))
+			(*p) = 0;
+		if(!(nod = find_dir(fs, nod, n)))
+			break;
+		if(p)
+			n = p + 1;
+		else
+			break;
+	}
+	free(n2);
+	return nod;
+}
+
+// create a simple inode
+static uint32
+mknod_fs(filesystem *fs, uint32 parent_nod, const char *name, uint16 mode, uint16 uid, uint16 gid, uint8 major, uint8 minor, uint32 ctime, uint32 mtime)
+{
+	uint32 nod;
+	inode *node;
+	if((nod = find_dir(fs, parent_nod, name)))
+	{
+		node = get_nod(fs, nod);
+		if((node->i_mode & FM_IFMT) != (mode & FM_IFMT))
+			error_msg_and_die("node '%s' already exists and isn't of the same type", name);
+		node->i_mode = mode;
+	}
+	else
+	{
+		nod = alloc_nod(fs);
+		node = get_nod(fs, nod);
+		node->i_mode = mode;
+		add2dir(fs, parent_nod, nod, name);
+		switch(mode & FM_IFMT)
+		{
+			case FM_IFLNK:
+				mode = FM_IFLNK | FM_IRWXU | FM_IRWXG | FM_IRWXO;
+				break;
+			case FM_IFBLK:
+			case FM_IFCHR:
+				((uint8*)get_nod(fs, nod)->i_block)[0] = minor;
+				((uint8*)get_nod(fs, nod)->i_block)[1] = major;
+				break;
+			case FM_IFDIR:
+				add2dir(fs, nod, nod, ".");
+				add2dir(fs, nod, parent_nod, "..");
+				get_gd(fs, GRP_GROUP_OF_INODE(fs,nod))->bg_used_dirs_count++;
+				break;
+		}
+	}
+	node->i_uid = uid;
+	node->i_gid = gid;
+	node->i_atime = mtime;
+	node->i_ctime = ctime;
+	node->i_mtime = mtime;
+	return nod;
+}
+
+// make a full-fledged directory (i.e. with "." & "..")
+static inline uint32
+mkdir_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode,
+	uid_t uid, gid_t gid, uint32 ctime, uint32 mtime)
+{
+	return mknod_fs(fs, parent_nod, name, mode|FM_IFDIR, uid, gid, 0, 0, ctime, mtime);
+}
+
+// make a symlink
+static uint32
+mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint8 *b, uid_t uid, gid_t gid, uint32 ctime, uint32 mtime)
+{
+	uint32 nod = mknod_fs(fs, parent_nod, name, FM_IFLNK | FM_IRWXU | FM_IRWXG | FM_IRWXO, uid, gid, 0, 0, ctime, mtime);
+	extend_blk(fs, nod, 0, - (int)get_nod(fs, nod)->i_blocks / INOBLK);
+	get_nod(fs, nod)->i_size = size;
+	if(size <= 4 * (EXT2_TIND_BLOCK+1))
+	{
+		strncpy((char*)get_nod(fs, nod)->i_block, (char*)b, size);
+		return nod;
+	}
+	extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE);
+	return nod;
+}
+
+// make a file from a FILE*
+static uint32
+mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size_t size, FILE *f, uid_t uid, gid_t gid, uint32 ctime, uint32 mtime)
+{
+	uint8 * b;
+	uint32 nod = mknod_fs(fs, parent_nod, name, mode|FM_IFREG, uid, gid, 0, 0, ctime, mtime);
+	extend_blk(fs, nod, 0, - (int)get_nod(fs, nod)->i_blocks / INOBLK);
+	get_nod(fs, nod)->i_size = size;
+	if (size) {
+		if(!(b = (uint8*)calloc(rndup(size, BLOCKSIZE), 1)))
+			error_msg_and_die("not enough mem to read file '%s'", name);
+		if(f)
+			fread(b, size, 1, f); // FIXME: ugly. use mmap() ...
+		extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE);
+		free(b);
+	}
+	return nod;
+}
+
+// retrieves a mode info from a struct stat
+static uint32
+get_mode(struct stat *st)
+{
+	uint32 mode = 0;
+
+	if(st->st_mode & S_IRUSR)
+		mode |= FM_IRUSR;
+	if(st->st_mode & S_IWUSR)
+		mode |= FM_IWUSR;
+	if(st->st_mode & S_IXUSR)
+		mode |= FM_IXUSR;
+	if(st->st_mode & S_IRGRP)
+		mode |= FM_IRGRP;
+	if(st->st_mode & S_IWGRP)
+		mode |= FM_IWGRP;
+	if(st->st_mode & S_IXGRP)
+		mode |= FM_IXGRP;
+	if(st->st_mode & S_IROTH)
+		mode |= FM_IROTH;
+	if(st->st_mode & S_IWOTH)
+		mode |= FM_IWOTH;
+	if(st->st_mode & S_IXOTH)
+		mode |= FM_IXOTH;
+	if(st->st_mode & S_ISUID)
+		mode |= FM_ISUID;
+	if(st->st_mode & S_ISGID)
+		mode |= FM_ISGID;
+	if(st->st_mode & S_ISVTX)
+		mode |= FM_ISVTX;
+	return mode;
+}
+
+// add or fixup entries to the filesystem from a text file
+/*  device table entries take the form of:
+    <path>	<type> <mode>	<uid>	<gid>	<major>	<minor>	<start>	<inc>	<count>
+    /dev/mem     c    640       0       0         1       1       0     0         -
+
+    type can be one of: 
+	f	A regular file
+	d	Directory
+	c	Character special device file
+	b	Block special device file
+	p	Fifo (named pipe)
+
+    I don't bother with symlinks (permissions are irrelevant), hard
+    links (special cases of regular files), or sockets (why bother).
+
+    Regular files must exist in the target root directory.  If a char,
+    block, fifo, or directory does not exist, it will be created.
+*/
+
+static void
+add2fs_from_file(filesystem *fs, uint32 this_nod, FILE * fh, uint32 fs_timestamp, struct stats *stats)
+{
+	unsigned long mode, uid, gid, major, minor;
+	unsigned long start, increment, count;
+	uint32 nod, ctime, mtime;
+	char *c, type, *path = NULL, *path2 = NULL, *dir, *name, *line = NULL;
+	size_t len;
+	struct stat st;
+	int nbargs, lineno = 0;
+
+	fstat(fileno(fh), &st);
+	ctime = fs_timestamp;
+	mtime = st.st_mtime;
+	while(getline(&line, &len, fh) >= 0)
+	{
+		mode = uid = gid = major = minor = 0;
+		start = 0; increment = 1; count = 0;
+		lineno++;
+		if((c = strchr(line, '#')))
+			*c = 0;
+		if (path) {
+			free(path);
+			path = NULL;
+		}
+		if (path2) {
+			free(path2);
+			path2 = NULL;
+		}
+		nbargs = sscanf (line, "%" SCANF_PREFIX "s %c %lo %lu %lu %lu %lu %lu %lu %lu",
+					SCANF_STRING(path), &type, &mode, &uid, &gid, &major, &minor,
+					&start, &increment, &count);
+		if(nbargs < 3)
+		{
+			if(nbargs > 0)
+				error_msg("device table line %d skipped: bad format for entry '%s'", lineno, path);
+			continue;
+		}
+		mode &= FM_IMASK;
+		path2 = strdup(path);
+		name = basename(path);
+		dir = dirname(path2);
+		if((!strcmp(name, ".")) || (!strcmp(name, "..")))
+		{
+			error_msg("device table line %d skipped", lineno);
+			continue;
+		}
+		if(fs)
+		{
+			if(!(nod = find_path(fs, this_nod, dir)))
+			{
+				error_msg("device table line %d skipped: can't find directory '%s' to create '%s''", lineno, dir, name);
+				continue;
+			}
+		}
+		else
+			nod = 0;
+		switch (type)
+		{
+			case 'd':
+				mode |= FM_IFDIR;
+				break;
+			case 'f':
+				mode |= FM_IFREG;
+				break;
+			case 'p':
+				mode |= FM_IFIFO;
+				break;
+			case 's':
+				mode |= FM_IFSOCK;
+				break;
+			case 'c':
+				mode |= FM_IFCHR;
+				break;
+			case 'b':
+				mode |= FM_IFBLK;
+				break;
+			default:
+				error_msg("device table line %d skipped: bad type '%c' for entry '%s'", lineno, type, name);
+				continue;
+		}
+		if(stats) {
+			if(count > 0)
+				stats->ninodes += count - start;
+			else
+				stats->ninodes++;
+		} else {
+			if(count > 0)
+			{
+				char *dname;
+				unsigned long i;
+				unsigned len;
+				len = strlen(name) + 10;
+				dname = malloc(len + 1);
+				for(i = start; i < count; i++)
+				{
+					SNPRINTF(dname, len, "%s%lu", name, i);
+					mknod_fs(fs, nod, dname, mode, uid, gid, major, minor + (i * increment - start), ctime, mtime);
+				}
+				free(dname);
+			}
+			else
+				mknod_fs(fs, nod, name, mode, uid, gid, major, minor, ctime, mtime);
+		}
+	}
+	if (line)
+		free(line);
+	if (path) 
+		free(path);
+	if (path2)
+		free(path2);
+}
+
+// adds a tree of entries to the filesystem from current dir
+static void
+add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_perms, uint32 fs_timestamp, struct stats *stats)
+{
+	uint32 nod;
+	uint32 uid, gid, mode, ctime, mtime;
+	const char *name;
+	FILE *fh;
+	DIR *dh;
+	struct dirent *dent;
+	struct stat st;
+	char *lnk;
+	uint32 save_nod;
+
+	if(!(dh = opendir(".")))
+		perror_msg_and_die(".");
+	while((dent = readdir(dh)))
+	{
+		if((!strcmp(dent->d_name, ".")) || (!strcmp(dent->d_name, "..")))
+			continue;
+		lstat(dent->d_name, &st);
+		uid = st.st_uid;
+		gid = st.st_gid;
+		ctime = fs_timestamp;
+		mtime = st.st_mtime;
+		name = dent->d_name;
+		mode = get_mode(&st);
+		if(squash_uids)
+			uid = gid = 0;
+		if(squash_perms)
+			mode &= ~(FM_IRWXG | FM_IRWXO);
+		if(stats)
+			switch(st.st_mode & S_IFMT)
+			{
+				case S_IFLNK:
+				case S_IFREG:
+					if((st.st_mode & S_IFMT) == S_IFREG || st.st_size > 4 * (EXT2_TIND_BLOCK+1))
+						stats->nblocks += (st.st_size + BLOCKSIZE - 1) / BLOCKSIZE;
+				case S_IFCHR:
+				case S_IFBLK:
+				case S_IFIFO:
+				case S_IFSOCK:
+					stats->ninodes++;
+					break;
+				case S_IFDIR:
+					stats->ninodes++;
+					if(chdir(dent->d_name) < 0)
+						perror_msg_and_die(dent->d_name);
+					add2fs_from_dir(fs, this_nod, squash_uids, squash_perms, fs_timestamp, stats);
+					chdir("..");
+					break;
+				default:
+					break;
+			}
+		else
+		{
+			save_nod = 0;
+			/* Check for hardlinks */
+			if (!S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode) && st.st_nlink > 1) {
+				int32 hdlink = is_hardlink(st.st_ino);
+				if (hdlink >= 0) {
+					add2dir(fs, this_nod, hdlinks.hdl[hdlink].dst_nod, name);
+					continue;
+				} else {
+					save_nod = 1;
+				}
+			}
+			switch(st.st_mode & S_IFMT)
+			{
+#if HAVE_STRUCT_STAT_ST_RDEV
+				case S_IFCHR:
+					nod = mknod_fs(fs, this_nod, name, mode|FM_IFCHR, uid, gid, major(st.st_rdev), minor(st.st_rdev), ctime, mtime);
+					break;
+				case S_IFBLK:
+					nod = mknod_fs(fs, this_nod, name, mode|FM_IFBLK, uid, gid, major(st.st_rdev), minor(st.st_rdev), ctime, mtime);
+					break;
+#endif
+				case S_IFIFO:
+					nod = mknod_fs(fs, this_nod, name, mode|FM_IFIFO, uid, gid, 0, 0, ctime, mtime);
+					break;
+				case S_IFSOCK:
+					nod = mknod_fs(fs, this_nod, name, mode|FM_IFSOCK, uid, gid, 0, 0, ctime, mtime);
+					break;
+				case S_IFLNK:
+					lnk = xreadlink(dent->d_name);
+					mklink_fs(fs, this_nod, name, st.st_size, (uint8*)lnk, uid, gid, ctime, mtime);
+					free(lnk);
+					break;
+				case S_IFREG:
+					fh = xfopen(dent->d_name, "rb");
+					nod = mkfile_fs(fs, this_nod, name, mode, st.st_size, fh, uid, gid, ctime, mtime);
+					fclose(fh);
+					break;
+				case S_IFDIR:
+					nod = mkdir_fs(fs, this_nod, name, mode, uid, gid, ctime, mtime);
+					if(chdir(dent->d_name) < 0)
+						perror_msg_and_die(name);
+					add2fs_from_dir(fs, nod, squash_uids, squash_perms, fs_timestamp, stats);
+					chdir("..");
+					break;
+				default:
+					error_msg("ignoring entry %s", name);
+			}
+			if (save_nod) {
+				if (hdlinks.count == hdlink_cnt) {
+					if ((hdlinks.hdl = 
+						 realloc (hdlinks.hdl, (hdlink_cnt + HDLINK_CNT) *
+								  sizeof (struct hdlink_s))) == NULL) {
+						error_msg_and_die("Not enough memory");
+					}
+					hdlink_cnt += HDLINK_CNT;
+				}
+				hdlinks.hdl[hdlinks.count].src_inode = st.st_ino;
+				hdlinks.hdl[hdlinks.count].dst_nod = nod;
+				hdlinks.count++;
+			}
+		}
+	}
+	closedir(dh);
+}
+
+// endianness swap of x-indirect blocks
+static void
+swap_goodblocks(filesystem *fs, inode *nod)
+{
+	uint32 i,j;
+	int done=0;
+	uint32 *b,*b2;
+
+	uint32 nblk = nod->i_blocks / INOBLK;
+	if((nod->i_size && !nblk) || ((nod->i_mode & FM_IFBLK) == FM_IFBLK) || ((nod->i_mode & FM_IFCHR) == FM_IFCHR))
+		for(i = 0; i <= EXT2_TIND_BLOCK; i++)
+			nod->i_block[i] = swab32(nod->i_block[i]);
+	if(nblk <= EXT2_IND_BLOCK)
+		return;
+	swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK]));
+	if(nblk <= EXT2_DIND_BLOCK + BLOCKSIZE/4)
+		return;
+	/* Currently this will fail b'cos the number of blocks as stored
+	   in i_blocks also includes the indirection blocks (see
+	   walk_bw). But this function assumes that i_blocks only
+	   stores the count of data blocks ( Actually according to
+	   "Understanding the Linux Kernel" (Table 17-3 p502 1st Ed)
+	   i_blocks IS supposed to store the count of data blocks). so
+	   with a file of size 268K nblk would be 269.The above check
+	   will be false even though double indirection hasn't been
+	   started.This is benign as 0 means block 0 which has been
+	   zeroed out and therefore points back to itself from any offset
+	 */
+	// FIXME: I have fixed that, but I have the feeling the rest of
+	// ths function needs to be fixed for the same reasons - Xav
+	assert(nod->i_block[EXT2_DIND_BLOCK] != 0);
+	for(i = 0; i < BLOCKSIZE/4; i++)
+		if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i )
+			if (((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i])
+				swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i]));
+	swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]));
+	if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4)
+		return;
+	/* Adding support for triple indirection */
+	b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK]);
+	for(i=0;i < BLOCKSIZE/4 && !done ; i++) {
+		b2 = (uint32*)get_blk(fs,b[i]); 
+		for(j=0; j<BLOCKSIZE/4;j++) {
+			if (nblk > ( EXT2_IND_BLOCK + BLOCKSIZE/4 + 
+				     (BLOCKSIZE/4)*(BLOCKSIZE/4) + 
+				     i*(BLOCKSIZE/4)*(BLOCKSIZE/4) + 
+				     j*(BLOCKSIZE/4)) ) 
+			  if (b2[j])
+			  	swap_block(get_blk(fs,b2[j]));
+			else {
+			  done = 1;
+			  break;
+			}
+		}
+		swap_block((uint8 *)b2);
+	}
+	swap_block((uint8 *)b);
+	return;
+}
+
+static void
+swap_badblocks(filesystem *fs, inode *nod)
+{
+	uint32 i,j;
+	int done=0;
+	uint32 *b,*b2;
+
+	uint32 nblk = nod->i_blocks / INOBLK;
+	if((nod->i_size && !nblk) || ((nod->i_mode & FM_IFBLK) == FM_IFBLK) || ((nod->i_mode & FM_IFCHR) == FM_IFCHR))
+		for(i = 0; i <= EXT2_TIND_BLOCK; i++)
+			nod->i_block[i] = swab32(nod->i_block[i]);
+	if(nblk <= EXT2_IND_BLOCK)
+		return;
+	swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK]));
+	if(nblk <= EXT2_DIND_BLOCK + BLOCKSIZE/4)
+		return;
+	/* See comment in swap_goodblocks */
+	assert(nod->i_block[EXT2_DIND_BLOCK] != 0);
+	swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]));
+	for(i = 0; i < BLOCKSIZE/4; i++)
+		if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i )
+			if (((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i])
+				swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i]));
+	if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4)
+		return;
+	/* Adding support for triple indirection */
+	b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK]);
+	swap_block((uint8 *)b);
+	for(i=0;i < BLOCKSIZE/4 && !done ; i++) {
+		b2 = (uint32*)get_blk(fs,b[i]); 
+		swap_block((uint8 *)b2);
+		for(j=0; j<BLOCKSIZE/4;j++) {
+			if (nblk > ( EXT2_IND_BLOCK + BLOCKSIZE/4 + 
+				     (BLOCKSIZE/4)*(BLOCKSIZE/4) + 
+				     i*(BLOCKSIZE/4)*(BLOCKSIZE/4) + 
+				     j*(BLOCKSIZE/4)) ) 
+			  if (b2[j])
+				swap_block(get_blk(fs,b2[j]));
+			else {
+			  done = 1;
+			  break;
+			}
+		}
+	}
+	return;
+}
+
+// endianness swap of the whole filesystem
+static void
+swap_goodfs(filesystem *fs)
+{
+	uint32 i;
+	for(i = 1; i < fs->sb.s_inodes_count; i++)
+	{
+		inode *nod = get_nod(fs, i);
+		if(nod->i_mode & FM_IFDIR)
+		{
+			blockwalker bw;
+			uint32 bk;
+			init_bw(&bw);
+			while((bk = walk_bw(fs, i, &bw, 0, 0)) != WALK_END)
+			{
+				directory *d;
+				uint8 *b;
+				b = get_blk(fs, bk);
+				for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + swab16(d->d_rec_len)))
+					swap_dir(d);
+			}
+		}
+		swap_goodblocks(fs, nod);
+		swap_nod(nod);
+	}
+	for(i=0;i<GRP_NBGROUPS(fs);i++)
+		swap_gd(get_gd(fs, i));
+	swap_sb(&fs->sb);
+}
+
+static void
+swap_badfs(filesystem *fs)
+{
+	uint32 i;
+	swap_sb(&fs->sb);
+	for(i=0;i<GRP_NBGROUPS(fs);i++)
+		swap_gd(get_gd(fs, i));
+	for(i = 1; i < fs->sb.s_inodes_count; i++)
+	{
+		inode *nod = get_nod(fs, i);
+		swap_nod(nod);
+		swap_badblocks(fs, nod);
+		if(nod->i_mode & FM_IFDIR)
+		{
+			blockwalker bw;
+			uint32 bk;
+			init_bw(&bw);
+			while((bk = walk_bw(fs, i, &bw, 0, 0)) != WALK_END)
+			{
+				directory *d;
+				uint8 *b;
+				b = get_blk(fs, bk);
+				for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len))
+					swap_dir(d);
+			}
+		}
+	}
+}
+
+// initialize an empty filesystem
+static filesystem *
+init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes,
+		uint32 fs_timestamp, uint32 creator_os)
+{
+	uint32 i;
+	filesystem *fs;
+	directory *d;
+	uint8 * b;
+	uint32 nod, first_block;
+	uint32 nbgroups,nbinodes_per_group,overhead_per_group,free_blocks,
+		free_blocks_per_group,nbblocks_per_group,min_nbgroups;
+	uint32 gdsz,itblsz,bbmpos,ibmpos,itblpos;
+	uint32 j;
+	uint8 *bbm,*ibm;
+	inode *itab0;
+	
+	if(nbresrvd < 0)
+		error_msg_and_die("reserved blocks value is invalid. Note: options have changed, see --help or the man page.");
+	if(nbinodes < EXT2_FIRST_INO - 1 + (nbresrvd ? 1 : 0))
+		error_msg_and_die("too few inodes. Note: options have changed, see --help or the man page.");
+	if(nbblocks < 8)
+		error_msg_and_die("too few blocks. Note: options have changed, see --help or the man page.");
+
+	/* nbinodes is the total number of inodes in the system.
+	 * a block group can have no more than 8192 inodes.
+	 */
+	min_nbgroups = (nbinodes + INODES_PER_GROUP - 1) / INODES_PER_GROUP;
+
+	/* On filesystems with 1k block size, the bootloader area uses a full
+	 * block. For 2048 and up, the superblock can be fitted into block 0.
+	 */
+	first_block = (BLOCKSIZE == 1024);
+
+	/* nbblocks is the total number of blocks in the filesystem.
+	 * a block group can have no more than 8192 blocks.
+	 */
+	nbgroups = (nbblocks - first_block + BLOCKS_PER_GROUP - 1) / BLOCKS_PER_GROUP;
+	if(nbgroups < min_nbgroups) nbgroups = min_nbgroups;
+	nbblocks_per_group = rndup((nbblocks - first_block + nbgroups - 1)/nbgroups, 8);
+	nbinodes_per_group = rndup((nbinodes + nbgroups - 1)/nbgroups,
+						(BLOCKSIZE/sizeof(inode)));
+	if (nbinodes_per_group < 16)
+		nbinodes_per_group = 16; //minimum number b'cos the first 10 are reserved
+
+	gdsz = rndup(nbgroups*sizeof(groupdescriptor),BLOCKSIZE)/BLOCKSIZE;
+	itblsz = nbinodes_per_group * sizeof(inode)/BLOCKSIZE;
+	overhead_per_group = 3 /*sb,bbm,ibm*/ + gdsz + itblsz;
+	free_blocks = nbblocks - overhead_per_group*nbgroups - first_block;
+	free_blocks_per_group = nbblocks_per_group - overhead_per_group;
+	if(free_blocks < 0)
+		error_msg_and_die("too much overhead, try fewer inodes or more blocks. Note: options have changed, see --help or the man page.");
+
+	if(!(fs = (filesystem*)calloc(nbblocks, BLOCKSIZE)))
+		error_msg_and_die("not enough memory for filesystem");
+
+	// create the superblock for an empty filesystem
+	fs->sb.s_inodes_count = nbinodes_per_group * nbgroups;
+	fs->sb.s_blocks_count = nbblocks;
+	fs->sb.s_r_blocks_count = nbresrvd;
+	fs->sb.s_free_blocks_count = free_blocks;
+	fs->sb.s_free_inodes_count = fs->sb.s_inodes_count - EXT2_FIRST_INO + 1;
+	fs->sb.s_first_data_block = first_block;
+	fs->sb.s_log_block_size = BLOCKSIZE >> 11;
+	fs->sb.s_log_frag_size = BLOCKSIZE >> 11;
+	fs->sb.s_blocks_per_group = nbblocks_per_group;
+	fs->sb.s_frags_per_group = nbblocks_per_group;
+	fs->sb.s_inodes_per_group = nbinodes_per_group;
+	fs->sb.s_wtime = fs_timestamp;
+	fs->sb.s_magic = EXT2_MAGIC_NUMBER;
+	fs->sb.s_lastcheck = fs_timestamp;
+	fs->sb.s_creator_os = creator_os;
+
+	// set up groupdescriptors
+	for(i=0, bbmpos=first_block+1+gdsz, ibmpos=bbmpos+1, itblpos=ibmpos+1;
+		i<nbgroups;
+		i++, bbmpos+=nbblocks_per_group, ibmpos+=nbblocks_per_group, itblpos+=nbblocks_per_group)
+	{
+		groupdescriptor *gd = get_gd(fs, i);
+
+		if(free_blocks > free_blocks_per_group) {
+			gd->bg_free_blocks_count = free_blocks_per_group;
+			free_blocks -= free_blocks_per_group;
+		} else {
+			gd->bg_free_blocks_count = free_blocks;
+			free_blocks = 0; // this is the last block group
+		}
+		if(i)
+			gd->bg_free_inodes_count = nbinodes_per_group;
+		else
+			gd->bg_free_inodes_count = nbinodes_per_group -
+							EXT2_FIRST_INO + 2;
+		gd->bg_used_dirs_count = 0;
+		gd->bg_block_bitmap = bbmpos;
+		gd->bg_inode_bitmap = ibmpos;
+		gd->bg_inode_table = itblpos;
+	}
+
+	/* Mark non-filesystem blocks and inodes as allocated */
+	/* Mark system blocks and inodes as allocated         */
+	for(i = 0; i<nbgroups;i++) {
+
+		/* Block bitmap */
+		bbm = GRP_GET_GROUP_BBM(fs, i);
+		//non-filesystem blocks
+		for(j = get_gd(fs, i)->bg_free_blocks_count
+		        + overhead_per_group + 1; j <= BLOCKSIZE * 8; j++)
+			allocate(bbm, j); 
+		//system blocks
+		for(j = 1; j <= overhead_per_group; j++)
+			allocate(bbm, j); 
+		
+		/* Inode bitmap */
+		ibm = GRP_GET_GROUP_IBM(fs, i);
+		//non-filesystem inodes
+		for(j = fs->sb.s_inodes_per_group+1; j <= BLOCKSIZE * 8; j++)
+			allocate(ibm, j);
+
+		//system inodes
+		if(i == 0)
+			for(j = 1; j < EXT2_FIRST_INO; j++)
+				allocate(ibm, j);
+	}
+
+	// make root inode and directory
+	/* We have groups now. Add the root filesystem in group 0 */
+	/* Also increment the directory count for group 0 */
+	get_gd(fs, 0)->bg_free_inodes_count--;
+	get_gd(fs, 0)->bg_used_dirs_count = 1;
+	itab0 = (inode *)get_blk(fs, get_gd(fs,0)->bg_inode_table);
+	itab0[EXT2_ROOT_INO-1].i_mode = FM_IFDIR | FM_IRWXU | FM_IRGRP | FM_IROTH | FM_IXGRP | FM_IXOTH; 
+	itab0[EXT2_ROOT_INO-1].i_ctime = fs_timestamp;
+	itab0[EXT2_ROOT_INO-1].i_mtime = fs_timestamp;
+	itab0[EXT2_ROOT_INO-1].i_atime = fs_timestamp;
+	itab0[EXT2_ROOT_INO-1].i_size = BLOCKSIZE;
+	itab0[EXT2_ROOT_INO-1].i_links_count = 2;
+
+	if(!(b = get_workblk()))
+		error_msg_and_die("get_workblk() failed.");
+	d = (directory*)b;
+	d->d_inode = EXT2_ROOT_INO;
+	d->d_rec_len = sizeof(directory)+4;
+	d->d_name_len = 1;
+	strcpy(d->d_name, ".");
+	d = (directory*)(b + d->d_rec_len);
+	d->d_inode = EXT2_ROOT_INO;
+	d->d_rec_len = BLOCKSIZE - (sizeof(directory)+4);
+	d->d_name_len = 2;
+	strcpy(d->d_name, "..");
+	extend_blk(fs, EXT2_ROOT_INO, b, 1);
+
+	// make lost+found directory and reserve blocks
+	if(fs->sb.s_r_blocks_count)
+	{
+		nod = mkdir_fs(fs, EXT2_ROOT_INO, "lost+found", FM_IRWXU, 0, 0, fs_timestamp, fs_timestamp);
+		memset(b, 0, BLOCKSIZE);
+		((directory*)b)->d_rec_len = BLOCKSIZE;
+		/* We run into problems with e2fsck if directory lost+found grows
+		 * bigger than this. Need to find out why this happens - sundar
+		 */
+		if (fs->sb.s_r_blocks_count > fs->sb.s_blocks_count * MAX_RESERVED_BLOCKS ) 
+			fs->sb.s_r_blocks_count = fs->sb.s_blocks_count * MAX_RESERVED_BLOCKS;
+		for(i = 1; i < fs->sb.s_r_blocks_count; i++)
+			extend_blk(fs, nod, b, 1);
+		get_nod(fs, nod)->i_size = fs->sb.s_r_blocks_count * BLOCKSIZE;
+	}
+	free_workblk(b);
+
+	// administrative info
+	fs->sb.s_state = 1;
+	fs->sb.s_max_mnt_count = 20;
+
+	// options for me
+	if(holes)
+		fs->sb.s_reserved[200] |= OP_HOLES;
+	
+	return fs;
+}
+
+// loads a filesystem from disk
+static filesystem *
+load_fs(FILE * fh, int swapit)
+{
+	size_t fssize;
+	filesystem *fs;
+	if((fseek(fh, 0, SEEK_END) < 0) || ((ssize_t)(fssize = ftell(fh)) == -1))
+		perror_msg_and_die("input filesystem image");
+	rewind(fh);
+	fssize = (fssize + BLOCKSIZE - 1) / BLOCKSIZE;
+	if(fssize < 16) // totally arbitrary
+		error_msg_and_die("too small filesystem");
+	if(!(fs = (filesystem*)calloc(fssize, BLOCKSIZE)))
+		error_msg_and_die("not enough memory for filesystem");
+	if(fread(fs, BLOCKSIZE, fssize, fh) != fssize)
+		perror_msg_and_die("input filesystem image");
+	if(swapit)
+		swap_badfs(fs);
+	if(fs->sb.s_rev_level || (fs->sb.s_magic != EXT2_MAGIC_NUMBER))
+		error_msg_and_die("not a suitable ext2 filesystem");
+	return fs;
+}
+
+static void
+free_fs(filesystem *fs)
+{
+	free(fs);
+}
+
+// just walk through blocks list
+static void
+flist_blocks(filesystem *fs, uint32 nod, FILE *fh)
+{
+	blockwalker bw;
+	uint32 bk;
+	init_bw(&bw);
+	while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)
+		fprintf(fh, " %d", bk);
+	fprintf(fh, "\n");
+}
+
+// walk through blocks list
+static void
+list_blocks(filesystem *fs, uint32 nod)
+{
+	int bn = 0;
+	blockwalker bw;
+	uint32 bk;
+	init_bw(&bw);
+	printf("blocks in inode %d:", nod);
+	while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)
+		printf(" %d", bk), bn++;
+	printf("\n%d blocks (%d bytes)\n", bn, bn * BLOCKSIZE);
+}
+
+// saves blocks to FILE*
+static void
+write_blocks(filesystem *fs, uint32 nod, FILE* f)
+{
+	blockwalker bw;
+	uint32 bk;
+	int32 fsize = get_nod(fs, nod)->i_size;
+	init_bw(&bw);
+	while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)
+	{
+		if(fsize <= 0)
+			error_msg_and_die("wrong size while saving inode %d", nod);
+		if(fwrite(get_blk(fs, bk), (fsize > BLOCKSIZE) ? BLOCKSIZE : fsize, 1, f) != 1)
+			error_msg_and_die("error while saving inode %d", nod);
+		fsize -= BLOCKSIZE;
+	}
+}
+
+
+// print block/char device minor and major
+static void
+print_dev(filesystem *fs, uint32 nod)
+{
+	int minor, major;
+	minor = ((uint8*)get_nod(fs, nod)->i_block)[0];
+	major = ((uint8*)get_nod(fs, nod)->i_block)[1];
+	printf("major: %d, minor: %d\n", major, minor);
+}
+
+// print an inode as a directory
+static void
+print_dir(filesystem *fs, uint32 nod)
+{
+	blockwalker bw;
+	uint32 bk;
+	init_bw(&bw);
+	printf("directory for inode %d:\n", nod);
+	while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)
+	{
+		directory *d;
+		uint8 *b;
+		b = get_blk(fs, bk);
+		for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len))
+			if(d->d_inode)
+			{
+				int i;
+				printf("entry '");
+				for(i = 0; i < d->d_name_len; i++)
+					putchar(d->d_name[i]);
+				printf("' (inode %d): rec_len: %d (name_len: %d)\n", d->d_inode, d->d_rec_len, d->d_name_len);
+			}
+	}
+}
+
+// print a symbolic link
+static void
+print_link(filesystem *fs, uint32 nod)
+{
+	if(!get_nod(fs, nod)->i_blocks)
+		printf("links to '%s'\n", (char*)get_nod(fs, nod)->i_block);
+	else
+	{
+		printf("links to '");
+		write_blocks(fs, nod, stdout);
+		printf("'\n");
+	}
+}
+
+// make a ls-like printout of permissions
+static void
+make_perms(uint32 mode, char perms[11])
+{
+	strcpy(perms, "----------");
+	if(mode & FM_IRUSR)
+		perms[1] = 'r';
+	if(mode & FM_IWUSR)
+		perms[2] = 'w';
+	if(mode & FM_IXUSR)
+		perms[3] = 'x';
+	if(mode & FM_IRGRP)
+		perms[4] = 'r';
+	if(mode & FM_IWGRP)
+		perms[5] = 'w';
+	if(mode & FM_IXGRP)
+		perms[6] = 'x';
+	if(mode & FM_IROTH)
+		perms[7] = 'r';
+	if(mode & FM_IWOTH)
+		perms[8] = 'w';
+	if(mode & FM_IXOTH)
+		perms[9] = 'x';
+	if(mode & FM_ISUID)
+		perms[3] = 's';
+	if(mode & FM_ISGID)
+		perms[6] = 's';
+	if(mode & FM_ISVTX)
+		perms[9] = 't';
+	switch(mode & FM_IFMT)
+	{
+		case 0:
+			*perms = '0';
+			break;
+		case FM_IFSOCK:
+			*perms = 's';
+			break;
+		case FM_IFLNK:
+			*perms = 'l';
+			break;
+		case FM_IFREG:
+			*perms = '-';
+			break;
+		case FM_IFBLK:
+			*perms = 'b';
+			break;
+		case FM_IFDIR:
+			*perms = 'd';
+			break;
+		case FM_IFCHR:
+			*perms = 'c';
+			break;
+		case FM_IFIFO:
+			*perms = 'p';
+			break;
+		default:
+			*perms = '?';
+	}
+}
+
+// print an inode
+static void
+print_inode(filesystem *fs, uint32 nod)
+{
+	char *s;
+	char perms[11];
+	if(!get_nod(fs, nod)->i_mode)
+		return;
+	switch(nod)
+	{
+		case EXT2_BAD_INO:
+			s = "bad blocks";
+			break;
+		case EXT2_ROOT_INO:
+			s = "root";
+			break;
+		case EXT2_ACL_IDX_INO:
+		case EXT2_ACL_DATA_INO:
+			s = "ACL";
+			break;
+		case EXT2_BOOT_LOADER_INO:
+			s = "boot loader";
+			break;
+		case EXT2_UNDEL_DIR_INO:
+			s = "undelete directory";
+			break;
+		default:
+			s = (nod >= EXT2_FIRST_INO) ? "normal" : "unknown reserved"; 
+	}
+	printf("inode %d (%s, %d links): ", nod, s, get_nod(fs, nod)->i_links_count);
+	if(!allocated(GRP_GET_INODE_BITMAP(fs,nod), GRP_IBM_OFFSET(fs,nod)))
+	{
+		printf("unallocated\n");
+		return;
+	}
+	make_perms(get_nod(fs, nod)->i_mode, perms);
+	printf("%s,  size: %d byte%s (%d block%s)\n", perms, plural(get_nod(fs, nod)->i_size), plural(get_nod(fs, nod)->i_blocks / INOBLK));
+	switch(get_nod(fs, nod)->i_mode & FM_IFMT)
+	{
+		case FM_IFSOCK:
+			list_blocks(fs, nod);
+			break;
+		case FM_IFLNK:
+			print_link(fs, nod);
+			break;
+		case FM_IFREG:
+			list_blocks(fs, nod);
+			break;
+		case FM_IFBLK:
+			print_dev(fs, nod);
+			break;
+		case FM_IFDIR:
+			list_blocks(fs, nod);
+			print_dir(fs, nod);
+			break;
+		case FM_IFCHR:
+			print_dev(fs, nod);
+			break;
+		case FM_IFIFO:
+			list_blocks(fs, nod);
+			break;
+		default:
+			list_blocks(fs, nod);
+	}
+	printf("Done with inode %d\n",nod);
+}
+
+// describes various fields in a filesystem
+static void
+print_fs(filesystem *fs)
+{
+	uint32 i;
+	uint8 *ibm;
+
+	printf("%d blocks (%d free, %d reserved), first data block: %d\n",
+	       fs->sb.s_blocks_count, fs->sb.s_free_blocks_count,
+	       fs->sb.s_r_blocks_count, fs->sb.s_first_data_block);
+	printf("%d inodes (%d free)\n", fs->sb.s_inodes_count,
+	       fs->sb.s_free_inodes_count);
+	printf("block size = %d, frag size = %d\n",
+	       fs->sb.s_log_block_size ? (fs->sb.s_log_block_size << 11) : 1024,
+	       fs->sb.s_log_frag_size ? (fs->sb.s_log_frag_size << 11) : 1024);
+	printf("number of groups: %d\n",GRP_NBGROUPS(fs));
+	printf("%d blocks per group,%d frags per group,%d inodes per group\n",
+	     fs->sb.s_blocks_per_group, fs->sb.s_frags_per_group,
+	     fs->sb.s_inodes_per_group);
+	printf("Size of inode table: %d blocks\n",
+		(int)(fs->sb.s_inodes_per_group * sizeof(inode) / BLOCKSIZE));
+	for (i = 0; i < GRP_NBGROUPS(fs); i++) {
+		printf("Group No: %d\n", i+1);
+		printf("block bitmap: block %d,inode bitmap: block %d, inode table: block %d\n",
+		     get_gd(fs, i)->bg_block_bitmap,
+		     get_gd(fs, i)->bg_inode_bitmap,
+		     get_gd(fs, i)->bg_inode_table);
+		printf("block bitmap allocation:\n");
+		print_bm(GRP_GET_GROUP_BBM(fs, i),fs->sb.s_blocks_per_group);
+		printf("inode bitmap allocation:\n");
+		ibm = GRP_GET_GROUP_IBM(fs, i);
+		print_bm(ibm, fs->sb.s_inodes_per_group);
+		for (i = 1; i <= fs->sb.s_inodes_per_group; i++)
+			if (allocated(ibm, i))
+				print_inode(fs, i);
+	}
+}
+
+static void
+dump_fs(filesystem *fs, FILE * fh, int swapit)
+{
+	uint32 nbblocks = fs->sb.s_blocks_count;
+	fs->sb.s_reserved[200] = 0;
+	if(swapit)
+		swap_goodfs(fs);
+	if(fwrite(fs, BLOCKSIZE, nbblocks, fh) < nbblocks)
+		perror_msg_and_die("output filesystem image");
+	if(swapit)
+		swap_badfs(fs);
+}
+
+static void
+populate_fs(filesystem *fs, char **dopt, int didx, int squash_uids, int squash_perms, uint32 fs_timestamp, struct stats *stats)
+{
+	int i;
+	for(i = 0; i < didx; i++)
+	{
+		struct stat st;
+		FILE *fh;
+		int pdir;
+		char *pdest;
+		uint32 nod = EXT2_ROOT_INO;
+		if(fs)
+			if((pdest = strchr(dopt[i], ':')))
+			{
+				*(pdest++) = 0;
+				if(!(nod = find_path(fs, EXT2_ROOT_INO, pdest)))
+					error_msg_and_die("path %s not found in filesystem", pdest);
+			}
+		stat(dopt[i], &st);
+		switch(st.st_mode & S_IFMT)
+		{
+			case S_IFREG:
+				fh = xfopen(dopt[i], "rb");
+				add2fs_from_file(fs, nod, fh, fs_timestamp, stats);
+				fclose(fh);
+				break;
+			case S_IFDIR:
+				if((pdir = open(".", O_RDONLY)) < 0)
+					perror_msg_and_die(".");
+				if(chdir(dopt[i]) < 0)
+					perror_msg_and_die(dopt[i]);
+				add2fs_from_dir(fs, nod, squash_uids, squash_perms, fs_timestamp, stats);
+				if(fchdir(pdir) < 0)
+					perror_msg_and_die("fchdir");
+				if(close(pdir) < 0)
+					perror_msg_and_die("close");
+				break;
+			default:
+				error_msg_and_die("%s is neither a file nor a directory", dopt[i]);
+		}
+	}
+}
+
+static void
+showversion(void)
+{
+	printf("genext2fs " VERSION "\n");
+}
+
+static void
+showhelp(void)
+{
+	fprintf(stderr, "Usage: %s [options] image\n"
+	"Create an ext2 filesystem image from directories/files\n\n"
+	"  -x, --starting-image <image>\n"
+	"  -d, --root <directory>\n"
+	"  -D, --devtable <file>\n"
+	"  -B, --block-size <bytes>\n"
+	"  -b, --size-in-blocks <blocks>\n"
+	"  -i, --bytes-per-inode <bytes per inode>\n"
+	"  -N, --number-of-inodes <number of inodes>\n"
+	"  -m, --reserved-percentage <percentage of blocks to reserve>\n"
+	"  -o, --creator-os <os>      'linux', 'hurd', 'freebsd' or a numerical value.\n"
+	"  -g, --block-map <path>     Generate a block map file for this path.\n"
+	"  -e, --fill-value <value>   Fill unallocated blocks with value.\n"
+	"  -z, --allow-holes          Allow files with holes.\n"
+	"  -f, --faketime             Set filesystem timestamps to 0 (for testing).\n"
+	"  -q, --squash               Same as \"-U -P\".\n"
+	"  -U, --squash-uids          Squash owners making all files be owned by root.\n"
+	"  -P, --squash-perms         Squash permissions on all files.\n"
+	"  -h, --help\n"
+	"  -V, --version\n"
+	"  -v, --verbose\n\n"
+	"Report bugs to genext2fs-devel@lists.sourceforge.net\n", app_name);
+}
+
+#define MAX_DOPT 128
+#define MAX_GOPT 128
+
+#define MAX_FILENAME 255
+
+extern char* optarg;
+extern int optind, opterr, optopt;
+
+// parse the value for -o <os>
+int
+lookup_creator_os(const char *name)
+{
+	static const char *const creators[] =
+		{"linux", "hurd", "2", "freebsd", NULL};
+	char *endptr;
+	int i;
+
+	// numerical value ?
+	i = strtol(name, &endptr, 0);
+	if(name[0] && *endptr == '\0')
+		return i;
+
+	// symbolic name ?
+	for(i=0; creators[i]; i++)
+	       if(strcasecmp(creators[i], name) == 0)
+		       return i;
+
+	// whatever ?
+	return -1;
+}
+
+int
+main(int argc, char **argv)
+{
+	int nbblocks = -1;
+	int nbinodes = -1;
+	int nbresrvd = -1;
+	float bytes_per_inode = -1;
+	float reserved_frac = -1;
+	int fs_timestamp = -1;
+	int creator_os = CREATOR_OS;
+	char * fsout = "-";
+	char * fsin = 0;
+	char * dopt[MAX_DOPT];
+	int didx = 0;
+	char * gopt[MAX_GOPT];
+	int gidx = 0;
+	int verbose = 0;
+	int holes = 0;
+	int emptyval = 0;
+	int squash_uids = 0;
+	int squash_perms = 0;
+	uint16 endian = 1;
+	int bigendian = !*(char*)&endian;
+	filesystem *fs;
+	int i;
+	int c;
+	struct stats stats;
+
+#if HAVE_GETOPT_LONG
+	struct option longopts[] = {
+	  { "starting-image",	required_argument,	NULL, 'x' },
+	  { "root",		required_argument,	NULL, 'd' },
+	  { "devtable",		required_argument,	NULL, 'D' },
+	  { "block-size",	required_argument,	NULL, 'B' },
+	  { "size-in-blocks",	required_argument,	NULL, 'b' },
+	  { "bytes-per-inode",	required_argument,	NULL, 'i' },
+	  { "number-of-inodes",	required_argument,	NULL, 'N' },
+	  { "reserved-percentage", required_argument,	NULL, 'm' },
+	  { "creator-os",	required_argument,	NULL, 'o' },
+	  { "block-map",	required_argument,	NULL, 'g' },
+	  { "fill-value",	required_argument,	NULL, 'e' },
+	  { "allow-holes",	no_argument, 		NULL, 'z' },
+	  { "faketime",		no_argument,		NULL, 'f' },
+	  { "squash",		no_argument,		NULL, 'q' },
+	  { "squash-uids",	no_argument,		NULL, 'U' },
+	  { "squash-perms",	no_argument,		NULL, 'P' },
+	  { "help",		no_argument,		NULL, 'h' },
+	  { "version",		no_argument,		NULL, 'V' },
+	  { "verbose",		no_argument,		NULL, 'v' },
+	  { 0, 0, 0, 0}
+	} ;
+
+	app_name = argv[0];
+
+	while((c = getopt_long(argc, argv, "x:d:D:B:b:i:N:m:o:g:e:zfqUPhVv", longopts, NULL)) != EOF) {
+#else
+	app_name = argv[0];
+
+	while((c = getopt(argc, argv,      "x:d:D:B:b:i:N:m:o:g:e:zfqUPhVv")) != EOF) {
+#endif /* HAVE_GETOPT_LONG */
+		switch(c)
+		{
+			case 'x':
+				fsin = optarg;
+				break;
+			case 'd':
+			case 'D':
+				dopt[didx++] = optarg;
+				break;
+			case 'B':
+				blocksize = SI_atof(optarg);
+				break;
+			case 'b':
+				nbblocks = SI_atof(optarg);
+				break;
+			case 'i':
+				bytes_per_inode = SI_atof(optarg);
+				break;
+			case 'N':
+				nbinodes = SI_atof(optarg);
+				break;
+			case 'm':
+				reserved_frac = SI_atof(optarg) / 100;
+				break;
+			case 'o':
+				creator_os = lookup_creator_os(optarg);
+				break;
+			case 'g':
+				gopt[gidx++] = optarg;
+				break;
+			case 'e':
+				emptyval = atoi(optarg);
+				break;
+			case 'z':
+				holes = 1;
+				break;
+			case 'f':
+				fs_timestamp = 0;
+				break;
+			case 'q':
+				squash_uids = 1;
+				squash_perms = 1;
+				break;
+			case 'U':
+				squash_uids = 1;
+				break;
+			case 'P':
+				squash_perms = 1;
+				break;
+			case 'h':
+				showhelp();
+				exit(0);
+			case 'V':
+				showversion();
+				exit(0);
+			case 'v':
+				verbose = 1;
+				showversion();
+				break;
+			default:
+				error_msg_and_die("Note: options have changed, see --help or the man page.");
+		}
+	}
+
+	if(optind < (argc - 1))
+		error_msg_and_die("Too many arguments. Try --help or else see the man page.");
+	if(optind > (argc - 1))
+		error_msg_and_die("Not enough arguments. Try --help or else see the man page.");
+	fsout = argv[optind];
+
+	if(blocksize != 1024 && blocksize != 2048 && blocksize != 4096)
+		error_msg_and_die("Valid block sizes: 1024, 2048 or 4096.");
+	if(creator_os < 0)
+		error_msg_and_die("Creator OS unknown.");
+
+	hdlinks.hdl = (struct hdlink_s *)malloc(hdlink_cnt * sizeof(struct hdlink_s));
+	if (!hdlinks.hdl)
+		error_msg_and_die("Not enough memory");
+	hdlinks.count = 0 ;
+
+	if(fsin)
+	{
+		if(strcmp(fsin, "-"))
+		{
+			FILE * fh = xfopen(fsin, "rb");
+			fs = load_fs(fh, bigendian);
+			fclose(fh);
+		}
+		else
+			fs = load_fs(stdin, bigendian);
+	}
+	else
+	{
+		if(reserved_frac == -1)
+			nbresrvd = nbblocks * RESERVED_BLOCKS;
+		else 
+			nbresrvd = nbblocks * reserved_frac;
+
+		stats.ninodes = EXT2_FIRST_INO - 1 + (nbresrvd ? 1 : 0);
+		stats.nblocks = 0;
+
+		populate_fs(NULL, dopt, didx, squash_uids, squash_perms, fs_timestamp, &stats);
+
+		if(nbinodes == -1)
+			nbinodes = stats.ninodes;
+		else
+			if(stats.ninodes > (unsigned long)nbinodes)
+			{
+				fprintf(stderr, "number of inodes too low, increasing to %ld\n", stats.ninodes);
+				nbinodes = stats.ninodes;
+			}
+
+		if(bytes_per_inode != -1) {
+			int tmp_nbinodes = nbblocks * BLOCKSIZE / bytes_per_inode;
+			if(tmp_nbinodes > nbinodes)
+				nbinodes = tmp_nbinodes;
+		}
+		if(fs_timestamp == -1)
+			fs_timestamp = time(NULL);
+		fs = init_fs(nbblocks, nbinodes, nbresrvd, holes,
+				fs_timestamp, creator_os);
+	}
+	
+	populate_fs(fs, dopt, didx, squash_uids, squash_perms, fs_timestamp, NULL);
+
+	if(emptyval) {
+		uint32 b;
+		for(b = 1; b < fs->sb.s_blocks_count; b++)
+			if(!allocated(GRP_GET_BLOCK_BITMAP(fs,b),GRP_BBM_OFFSET(fs,b)))
+				memset(get_blk(fs, b), emptyval, BLOCKSIZE);
+	}
+	if(verbose)
+		print_fs(fs);
+	for(i = 0; i < gidx; i++)
+	{
+		uint32 nod;
+		char fname[MAX_FILENAME];
+		char *p;
+		FILE *fh;
+		if(!(nod = find_path(fs, EXT2_ROOT_INO, gopt[i])))
+			error_msg_and_die("path %s not found in filesystem", gopt[i]);
+		while((p = strchr(gopt[i], '/')))
+			*p = '_';
+		SNPRINTF(fname, MAX_FILENAME-1, "%s.blk", gopt[i]);
+		fh = xfopen(fname, "wb");
+		fprintf(fh, "%d:", get_nod(fs, nod)->i_size);
+		flist_blocks(fs, nod, fh);
+		fclose(fh);
+	}
+	if(strcmp(fsout, "-"))
+	{
+		FILE * fh = xfopen(fsout, "wb");
+		dump_fs(fs, fh, bigendian);
+		fclose(fh);
+	}
+	else
+		dump_fs(fs, stdout, bigendian);
+	free_fs(fs);
+	return 0;
+}
Index: build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/test-gen.lib
===================================================================
--- build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/test-gen.lib	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/test-gen.lib	(revision 231)
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+# These routines contain the filesystem generation code.
+# This code is sourced by the other scripts so that digest
+# generation is consistent.
+
+# dgen - Exercises the -d directory option of genext2fs
+# Creates an image with a file of given size
+# Usage: dgen file-size number-of-blocks 
+dgen () {
+	size=$1; blocks=$2; blocksz=$3;
+	rm -rf test
+	mkdir -p test
+	cd test
+	if [ x$size = x0 ]; then
+		> file.$1
+	else
+		dd if=/dev/zero of=file.$1 bs=$size count=1 2>/dev/null
+	fi
+        chmod 777 file.$1
+	TZ=UTC-11 touch -t 200502070321.43 file.$1 .
+	cd ..
+	./genext2fs -B $blocksz -N 17 -b $blocks -d test -f -o Linux -q ext2.img
+}
+
+# fgen - Exercises the -f spec-file option of genext2fs
+# Creates an image with the devices mentioned in the given spec file 
+# Usage: fgen spec-file number-of-blocks 
+fgen () {
+	fname=$1; blocks=$2; 
+	mkdir -p test
+	cp $fname test
+	TZ=UTC-11 touch -t 200502070321.43 test/$fname
+	./genext2fs -N 92 -b $blocks -D test/$fname -f -o Linux ext2.img
+}
+
+# gen_cleanup - Remove the files generated by the above functions
+# Usage: gen_cleanup
+gen_cleanup () {
+	rm -rf ext2.img test
+}
+
+# calc_digest - Return the MD5 digest of the test image
+# Usage: calc_digest
+calc_digest () {
+	digest=`md5sum ext2.img 2>/dev/null | cut -f 1 -d " "`
+	if [ x$digest != x ] ; then
+ 		echo $digest
+	else
+		digest=`md5 ext2.img 2>/dev/null | cut -f 4 -d " "`
+		echo $digest
+	fi
+}
+
+LC_ALL=C
+export LC_ALL
Index: build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/test-mount.sh
===================================================================
--- build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/test-mount.sh	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/test-mount.sh	(revision 231)
@@ -0,0 +1,95 @@
+#!/bin/sh
+
+# Use this script if you need to regenerate the digest values
+# in test.sh, or if you don't care about digests and you just
+# want to see some fsck results. Should be run as root.
+
+set -e
+
+. ./test-gen.lib
+
+test_cleanup () {
+	umount mnt 2>/dev/null || true
+	rm -rf mnt fout lsout
+}
+
+fail () {
+	echo FAILED
+	test_cleanup
+	gen_cleanup
+	exit 1
+}
+
+pass () {
+	md5=`calc_digest`
+	echo PASSED
+	echo $@ $md5
+	test_cleanup
+	gen_cleanup
+}
+
+# dtest-mount - Exercise the -d directory option of genext2fs
+# Creates an image with a file of given size, verifies it
+# and returns the command line with which to invoke dtest()
+# Usage: dtest-mount file-size number-of-blocks 
+dtest_mount () {
+	size=$1; blocks=$2; blocksz=$3;
+	echo Testing $blocks blocks of $blocksz bytes with file of size $size
+	dgen $size $blocks $blocksz
+	/sbin/e2fsck -fn ext2.img || fail
+	mkdir -p mnt
+	mount -t ext2 -o ro,loop ext2.img mnt || fail
+	if (! [ -f mnt/file.$size ]) || \
+	      [ $size != "`ls -al mnt | grep file.$size |
+	                                awk '{print $5}'`" ] ; then
+		fail
+	fi
+	pass dtest $size $blocks $blocksz
+}
+
+# ftest-mount - Exercise the -f spec-file option of genext2fs
+# Creates an image with the devices mentioned in the given spec 
+# file, verifies it, and returns the command line with which to
+# invoke ftest()
+# Usage: ftest-mount spec-file number-of-blocks 
+ftest_mount () {
+	fname=$1; blocks=$2 
+	echo Testing with devices file $fname
+	fgen $fname $blocks
+	/sbin/e2fsck -fn ext2.img || fail
+	mkdir -p mnt
+	mount -t ext2 -o ro,loop ext2.img mnt || fail
+	[ -d mnt/dev ] || fail
+	# Exclude those devices that have interpolated
+	# minor numbers, as being too hard to match.
+	egrep -v "(hda|hdb|tty|loop|ram|ubda)" $fname | \
+		grep '^[^	#]*	[bc]' | \
+		awk '{print $1,$4,$5,$6","$7}'| \
+		sort -d -k3.6 > fout
+	ls -aln mnt/dev | \
+		egrep -v "(hda|hdb|tty|loop|ram|ubda)" | \
+		grep ^[bc] | \
+		awk '{ print "/dev/"$10,$3,$4,$5$6}' | \
+		sort -d -k3.6 > lsout
+	diff fout lsout || fail
+	pass ftest $fname $blocks
+}
+
+dtest_mount 0 4096 1024
+dtest_mount 0 2048 2048
+dtest_mount 0 1024 4096
+dtest_mount 0 8193 1024
+dtest_mount 0 8194 1024
+dtest_mount 0 8193 4096
+dtest_mount 0 8194 2048
+dtest_mount 1 4096 1024
+dtest_mount 1 1024 4096
+dtest_mount 12288 4096 1024
+dtest_mount 274432 4096 1024
+dtest_mount 8388608 9000 1024
+dtest_mount 8388608 4500 2048
+dtest_mount 8388608 2250 4096
+dtest_mount 16777216 20000 1024
+dtest_mount 16777216 10000 2048
+
+ftest_mount device_table.txt 4096

Property changes on: build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/test-mount.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/test.sh
===================================================================
--- build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/test.sh	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/test.sh	(revision 231)
@@ -0,0 +1,72 @@
+#!/bin/sh
+
+# This script generates a variety of filesystems and checks that they
+# are identical to ones that are known to be mountable, and pass fsck
+# and various other sanity checks.
+
+# Passing these tests is preferable to passing test-mount.sh because
+# this script doesn't require root, and because passing these tests
+# guarantees byte-for-byte agreement with other builds, ports,
+# architectures, times of day etc.
+
+set -e
+
+. ./test-gen.lib
+
+# md5cmp - Calculate MD5 digest and compare it to an expected value.
+# Usage: md5cmp expected-digest
+md5cmp () {
+	checksum=$1
+	md5=`calc_digest`
+	if [ x$md5 = x$checksum ] ; then
+		echo PASSED
+	else
+		echo FAILED
+		exit 1
+	fi
+}
+
+# dtest - Exercises the -d directory option of genext2fs
+# Creates an image with a file of given size and verifies it
+# Usage: dtest file-size number-of-blocks correct-checksum
+dtest () {
+	size=$1; blocks=$2; blocksz=$3; checksum=$4
+	echo Testing with file of size $size
+	dgen $size $blocks $blocksz
+	md5cmp $checksum
+	gen_cleanup
+}
+
+# ftest - Exercises the -f spec-file option of genext2fs
+# Creates an image with the devices mentioned in the given spec 
+# file and verifies it
+# Usage: ftest spec-file number-of-blocks correct-checksum
+ftest () {
+	fname=$1; blocks=$2; checksum=$3
+	echo Testing with devices file $fname
+	fgen $fname $blocks
+	md5cmp $checksum
+	gen_cleanup
+}
+
+# NB: to regenerate these values, always use test-mount.sh, that is,
+# replace the following lines with the output of
+# sudo sh test-mount.sh|grep test
+
+dtest 0 4096 1024 3bc6424b8fcd51a0de34ee59d91d5f16
+dtest 0 2048 2048 230afa16496df019878cc2370c661cdc
+dtest 0 1024 4096 ebff5eeb38b70f3f1cd081e60eb44561
+dtest 0 8193 1024 f174804f6b433b552706cbbfc60c416d
+dtest 0 8194 1024 4855a55d0cbdc44584634df49ebd5711
+dtest 0 8193 4096 c493679698418ec7e6552005e2d2a6d8
+dtest 0 8194 2048 ec13f328fa7543563f35f494bddc059c
+dtest 1 4096 1024 09c569b6bfb45222c729c42d04d5451f
+dtest 1 1024 4096 d318a326fdc907810ae9e6b0a20e9b06
+dtest 12288 4096 1024 61febcbfbf32024ef99103fcdc282c39
+dtest 274432 4096 1024 0c517803552c55c1806e4220b0a0164f
+dtest 8388608 9000 1024 e0e5ea15bced10ab486d8135584b5d8e
+dtest 8388608 4500 2048 39f4d537a72f5053fd6891721c59680d
+dtest 8388608 2250 4096 1d697fa4bc2cfffe02ac91edfadc40bf
+dtest 16777216 20000 1024 fdf636eb905ab4dc1bf76dce5ac5d209
+dtest 16777216 10000 2048 f9824a81ea5e74fdf469c097927c292b
+ftest device_table.txt 4096 a0af06d944b11d2902dfd705484c64cc

Property changes on: build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-blocksize-patch/genext2fs-1.4.1-new/test.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-configure-patch/create.patch.sh
===================================================================
--- build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-configure-patch/create.patch.sh	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-configure-patch/create.patch.sh	(revision 231)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=1.4.1
+
+tar --files-from=file.list -xzvf ../genext2fs-$VERSION.tar.gz
+mv genext2fs-$VERSION genext2fs-$VERSION-orig
+
+cp -rf ./genext2fs-$VERSION-new ./genext2fs-$VERSION
+
+diff -b --unified -Nr  genext2fs-$VERSION-orig  genext2fs-$VERSION > genext2fs-$VERSION-configure.patch
+
+mv genext2fs-$VERSION-configure.patch ../patches
+
+rm -rf ./genext2fs-$VERSION
+rm -rf ./genext2fs-$VERSION-orig

Property changes on: build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-configure-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-configure-patch/file.list
===================================================================
--- build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-configure-patch/file.list	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-configure-patch/file.list	(revision 231)
@@ -0,0 +1,2 @@
+genext2fs-1.4.1/configure.in
+genext2fs-1.4.1/m4/ac_func_scanf_can_malloc.m4
Index: build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-configure-patch/genext2fs-1.4.1-new/configure.in
===================================================================
--- build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-configure-patch/genext2fs-1.4.1-new/configure.in	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-configure-patch/genext2fs-1.4.1-new/configure.in	(revision 231)
@@ -0,0 +1,41 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.59)
+AC_INIT(genext2fs.c)
+
+builtin(include, [m4/ac_func_snprintf.m4])dnl
+builtin(include, [m4/ac_func_scanf_can_malloc.m4])dnl
+
+AM_INIT_AUTOMAKE(genext2fs,1.4.1)
+AC_CONFIG_HEADERS([config.h])
+
+AC_GNU_SOURCE
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_INSTALL
+
+# Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_HEADER_MAJOR
+AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h memory.h stddef.h stdint.h stdlib.h string.h strings.h unistd.h])
+AC_CHECK_HEADERS([libgen.h getopt.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_UID_T
+AC_C_INLINE
+AC_CHECK_TYPE(size_t, unsigned)
+AC_CHECK_TYPE(ssize_t, signed)
+AC_CHECK_MEMBERS([struct stat.st_rdev])
+
+# Checks for library functions.
+AC_CHECK_FUNCS([getopt_long getline strtof])
+AC_FUNC_SNPRINTF
+AC_FUNC_SCANF_CAN_MALLOC
+
+AC_OUTPUT([Makefile],[
+chmod a+x $ac_top_srcdir/test-mount.sh $ac_top_srcdir/test.sh
+])
Index: build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-configure-patch/genext2fs-1.4.1-new/m4/ac_func_scanf_can_malloc.m4
===================================================================
--- build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-configure-patch/genext2fs-1.4.1-new/m4/ac_func_scanf_can_malloc.m4	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/genext2fs/create-1.4.1-configure-patch/genext2fs-1.4.1-new/m4/ac_func_scanf_can_malloc.m4	(revision 231)
@@ -0,0 +1,53 @@
+dnl AC_FUNC_SCANF_CAN_MALLOC macro
+dnl
+dnl (c) Finn Thain 2006
+dnl Copying and distribution of this file, with or without modification,
+dnl are permitted in any medium without royalty provided the copyright
+dnl notice and this notice are preserved.
+
+# AC_FUNC_SCANF_CAN_MALLOC()
+# --------------------------------------
+AC_DEFUN([AC_FUNC_SCANF_CAN_MALLOC],
+  [ AC_CHECK_HEADERS([stdlib.h])
+    AC_CACHE_CHECK([whether scanf can malloc], [ac_cv_func_scanf_can_malloc],
+    [ AC_RUN_IFELSE(
+      [ AC_LANG_PROGRAM(
+        [
+#include <stdio.h>
+#if STDC_HEADERS || HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+        ], [
+  union { float f; char *p; } u;
+  char *p;
+  u.f = 0;
+  char *scan_this = "56789";
+  int matched = sscanf(scan_this, "%as", &u);
+  if(matched < 1) return 1; /* shouldn't happens */
+  if(u.f == (float)56789) return 2;
+
+  p = u.p;
+  while(*scan_this && *p == *scan_this) {
+    ++p;
+    ++scan_this;
+  };
+  free(u.p);
+  if(*scan_this == 0) return 0;
+  return 3;
+        ])
+      ],
+      [ac_scanf_can_malloc=yes],
+      [ac_scanf_can_malloc=no],
+      [
+case $host_alias in
+  *-*-linux* ) ac_scanf_can_malloc=yes ;;
+  *-*-solaris* ) ac_scanf_can_malloc=no ;;
+  *-*-darwin* ) ac_scanf_can_malloc=no ;;
+  * ) ac_scanf_can_malloc=no ;;
+esac
+      ])
+    ])
+if test x$ac_scanf_can_malloc = "xyes"; then
+  AC_DEFINE([SCANF_CAN_MALLOC], 1, [Define to 1 if the scanf %a conversion format mallocs a buffer. Undefine if %a format denotes a float.])
+fi
+  ])
Index: build-system-1.2.3/3pp/sources/packages/genext2fs/patches/README
===================================================================
--- build-system-1.2.3/3pp/sources/packages/genext2fs/patches/README	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/genext2fs/patches/README	(revision 231)
@@ -0,0 +1,10 @@
+
+/* begin *
+
+   genext2fs-1.4.1-blocksize.patch - adds the two options to set block size and CREATOR_OS.
+                                     Also the two duncrions swap_goodblocks() [line: 1751]
+                                     and swap_badblocks() [line: 1810] are fixed;
+
+   genext2fs-1.4.1-configure.patch - changes according to new version of autotools.
+
+ * end */
Index: build-system-1.2.3/3pp/sources/packages/populatefs/Makefile
===================================================================
--- build-system-1.2.3/3pp/sources/packages/populatefs/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/populatefs/Makefile	(revision 231)
@@ -0,0 +1,61 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/packages/a/populatefs
+
+
+versions    = 1.0
+pkgname     = populatefs
+suffix      = tar.xz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+patches     = $(CURDIR)/patches/populatefs-1.0-squash.patch
+patches    += $(CURDIR)/patches/populatefs-1.0-notrunc-rfiles.patch
+patches    += $(CURDIR)/patches/populatefs-1.0-version.patch
+
+.NOTPARALLEL: $(patches)
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s) $(patches)
+
+
+include ../../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======\n" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+$(patches): $(sha1s)
+	@echo -e "\n======= Create Patches =======\n" ; \
+	 ( cd create-1.0-squash-patch         ; ./create.patch.sh ) ; \
+	 ( cd create-1.0-notrunc-rfiles-patch ; ./create.patch.sh ) ; \
+	 ( cd create-1.0-version-patch        ; ./create.patch.sh ) ; \
+	 echo -e "\n"
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s) $(patches)
Index: build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-notrunc-rfiles-patch/create.patch.sh
===================================================================
--- build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-notrunc-rfiles-patch/create.patch.sh	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-notrunc-rfiles-patch/create.patch.sh	(revision 231)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=1.0
+
+tar --files-from=file.list -xJvf ../populatefs-$VERSION.tar.xz
+mv populatefs-$VERSION populatefs-$VERSION-orig
+
+cp -rf ./populatefs-$VERSION-new ./populatefs-$VERSION
+
+diff -b --unified -Nr  populatefs-$VERSION-orig  populatefs-$VERSION > populatefs-$VERSION-notrunc-rfiles.patch
+
+mv populatefs-$VERSION-notrunc-rfiles.patch ../patches
+
+rm -rf ./populatefs-$VERSION
+rm -rf ./populatefs-$VERSION-orig

Property changes on: build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-notrunc-rfiles-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-notrunc-rfiles-patch/file.list
===================================================================
--- build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-notrunc-rfiles-patch/file.list	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-notrunc-rfiles-patch/file.list	(revision 231)
@@ -0,0 +1 @@
+populatefs-1.0/src/mod_file.c
Index: build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-notrunc-rfiles-patch/populatefs-1.0-new/src/mod_file.c
===================================================================
--- build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-notrunc-rfiles-patch/populatefs-1.0-new/src/mod_file.c	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-notrunc-rfiles-patch/populatefs-1.0-new/src/mod_file.c	(revision 231)
@@ -0,0 +1,272 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <libgen.h>
+#include <ext2fs/ext2fs.h>
+
+#include "log.h"
+#include "debugfs.h"
+#include "mod_file.h"
+
+#if 0 // C99 define "a" for floating point, so you can have runtime surprise varying from the version of the library
+# define SCANF_PREFIX "a"
+# define SCANF_STRING(s) (&s)
+#else
+# define SCANF_PREFIX "511"
+# define SCANF_STRING(s) (s = malloc(512))
+#endif
+
+void addFilespec(FILE *fd, int squash_uids, int squash_perms)
+{
+
+	unsigned long rmode, mode, uid, gid, major, minor, i;
+	unsigned long start, increment, count, octmode, decmode;
+	char *c, *dir, *name, *dname = NULL, *path = NULL, *path2 = NULL, *line = NULL;
+	char type;
+	size_t len;
+	int argv, i2, overWrite = 0, lineno = 0;
+	__u16 inodeType;
+
+	while ( getline(&line, &len, fd) >= 0 ) {
+		rmode = mode = uid = gid = major = minor = start = count = overWrite = 0;
+		increment = 1;
+		lineno++;
+
+		if (( c = strchr(line, '#'))) *c = 0;
+		if ( path ) {
+			free( path ); path = NULL;
+		}
+		if ( path2 ) {
+			free( path2 ); path2 = NULL;
+		}
+
+		argv = sscanf(line, "%" SCANF_PREFIX "s %c %ld %lu %lu %lu %lu %lu %lu %lu",
+			      SCANF_STRING(path), &type, &rmode, &uid, &gid, &major, &minor,
+			      &start, &increment, &count);
+
+		if ( argv < 3 ) {
+			if ( argv > 0 )
+				log_warning("device table[%d]: bad format for entry '%s' [skip]", lineno, path);
+			continue;
+		}
+
+		i2 = 0;
+		octmode = rmode;
+		decmode = 0;
+		while ( octmode != 0 ) {
+			decmode = decmode + (octmode % 10) * pow(8, i2++);
+			octmode = octmode / 10;
+		}
+
+		if ( squash_uids ) uid = gid = 0;
+
+		mode = decmode;
+		path2 = strdup( path );
+		name = basename( path );
+		dir = dirname( path2 );
+
+		if (( !strcmp(name, ".")) || ( !strcmp(name, "..")) || ( !strcmp(name, "/"))) {
+			log_warning("device table[%d]: [skip]", lineno);
+			continue;
+		}
+
+		log_action(ACT_CHDIR, dir, NULL, 0, 0, 0, 0, 0, 0, 0);
+		if ( !do_chdir(dir)) {
+			log_warning("device table[%d]: target directory '%s' for entry '%s' does not exist [skip]", lineno, dir, name);
+			log_action(ACT_CHDIR, "/", NULL, 0, 0, 0, 0, 0, 0, 0);
+			if ( !do_chdir("/"))
+				log_error("[Filesystem error] cannot chdir to root");
+			continue;
+		}
+
+		if (( type != 'd' ) && ( type != 'f' ) && ( type != 'p' ) && ( type != 'c' ) && ( type != 'b' ) && ( type != 's')) {
+			log_warning("device table[%d]: bad type '%c' for entry '%s' [skip]", lineno, type, name);
+			continue;
+		}
+
+		if (squash_perms) {
+			mode &= ~( LINUX_S_IRWXG | LINUX_S_IRWXO );
+			rmode &= ~( LINUX_S_IRWXG | LINUX_S_IRWXO);
+		}
+
+		if ( count > 0 ) {
+
+			if ( dname ) {
+				free( dname );
+				dname = NULL;
+			}
+
+			unsigned len;
+			len = strlen(name) + 10;
+			dname = malloc(len + 1);
+
+			for ( i = start; i < count; i++ ) {
+				snprintf(dname, len, "%s%lu", name, i);
+
+				if (( overWrite = name_to_inode(dname)))
+					inodeType = inode_mode(dname);
+
+				if (( type == 'd' ) && ( overWrite ) && ( !LINUX_S_ISDIR(inodeType)))
+					log_error("[Remote fs mismatch] %s/%s exists but isn't a directory when it should be.", log_cwd(), dname);
+				else if (( type != 'd' ) && ( overWrite )) {
+
+					if ( LINUX_S_ISDIR(inodeType))
+						log_error("[Remote fs mismatch] %s/%s exists but is a directory when it shouldn't be.", log_cwd(), dname);
+
+					if ((!LINUX_S_ISREG(inodeType)) && (!LINUX_S_ISLNK(inodeType)) &&
+					    (!LINUX_S_ISBLK(inodeType)) && (!LINUX_S_ISCHR(inodeType)) &&
+					    (!LINUX_S_ISFIFO(inodeType)) && (!LINUX_S_ISSOCK(inodeType)))
+						log_error("[Remote fs mismatch] Existing file %s/%s has unknown/unsupported type [0x%x].", log_cwd(), dname, inodeType);
+				}
+
+				switch ( type ) {
+				case 'd':
+					mode |= LINUX_S_IFDIR;
+					log_action(ACT_MKDIR, dname, NULL, 0, 0, 0, 0, 0, 0, overWrite);
+
+					if ( !overWrite )
+						if ( !do_mkdir(dname))
+							log_error("[Filesystem error] cannot mkdir %s/%s", log_cwd(), dname);
+
+					break;
+
+				case 'c':
+				case 'b':
+					if ( type == 'c' )
+						mode |= LINUX_S_IFCHR;
+					else
+						mode |= LINUX_S_IFBLK;
+
+					if ( overWrite ) {
+						log_action(ACT_RM, dname, NULL, 0, 0, 0, 0, 0, 0, overWrite);
+						if ( !do_rm(dname))
+							log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), dname);
+					}
+
+					log_action(ACT_MKNOD, dname, NULL, 0, 0, 0, type, major, minor + ((i * increment) - start), overWrite);
+					if ( !do_mknod(dname, type, major, minor + ((i * increment) - start)))
+						log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), dname);
+					break;
+
+				case 's':
+				case 'p':
+					if ( type == 's' )
+						mode |= LINUX_S_IFSOCK;
+					else	mode |= LINUX_S_IFIFO;
+
+					if ( overWrite ) {
+						log_action(ACT_RM, dname, NULL, 0, 0, 0, 0, 0, 0, overWrite);
+						if ( !do_rm(dname))
+							log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), dname);
+					}
+
+					log_action(ACT_MKNOD, dname, NULL, 0, 0, 0, type, 0, 0, overWrite);
+					if ( !do_mknod(dname, type, 0, 0))
+						log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), dname);
+
+					break;
+				}
+
+				log_action(ACT_CHMOD, dname, NULL, rmode, 0, 0, 0, 0, 0, 0);
+				if ( !do_chmod(dname, rmode))
+					log_error("[Filesystem error] cannot chmod %s/%s", log_cwd(), dname);
+				log_action(ACT_CHOWN, dname, NULL, 0, uid, gid, 0, 0, 0, 0);
+				if ( !do_chown(dname, uid, gid))
+					log_error("[Filesystem error] cannot chown %s/%s", log_cwd(), dname);
+			}
+
+			log_action(ACT_CHDIR, "/", NULL, 0, 0, 0, 0, 0, 0, 0);
+			if ( !do_chdir("/"))
+				log_error("[Filesystem error] cannot chdir to root");
+			free(dname);
+			dname = NULL;
+
+		} else {
+
+			if (( overWrite = name_to_inode(name)))
+				inodeType = inode_mode(name);
+
+			if (( type == 'd' ) && ( overWrite ) && ( !LINUX_S_ISDIR(inodeType)))
+				log_error("[Remote fs mismatch] %s/%s exists but isn't a directory when it should be.", log_cwd(), dname);
+			else if ( type != 'd' ) {
+				if (( overWrite ) && ( LINUX_S_ISDIR(inodeType)))
+					log_error("[Remote fs mismatch] %s/%s exists but is a directory when it shouldn't be.", log_cwd(), dname);
+
+				if (( overWrite ) && (!LINUX_S_ISREG(inodeType)) && (!LINUX_S_ISLNK(inodeType)) &&
+				    (!LINUX_S_ISBLK(inodeType)) && (!LINUX_S_ISCHR(inodeType)) &&
+				    (!LINUX_S_ISFIFO(inodeType)) && (!LINUX_S_ISSOCK(inodeType)))
+					log_error("[Remote fs mismatch] Existing file %s/%s has unknown/unsupported type [0x%x].",  log_cwd(), dname, inodeType);
+			}
+
+			switch ( type ) {
+			case 'd':
+				mode |= LINUX_S_IFDIR;
+				log_action(ACT_MKDIR, name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
+
+				if ( !overWrite )
+					if ( !do_mkdir(name))
+						log_error("[Filesystem error] cannot mkdir %s/%s", log_cwd(), name);
+				break;
+
+			case 'c':
+			case 'b':
+				if ( type == 'c' )
+					mode |= LINUX_S_IFCHR;
+				else
+					mode |= LINUX_S_IFBLK;
+
+				if ( overWrite ) {
+					log_action(ACT_RM, name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
+					if ( !do_rm(name))
+						log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), name);
+				}
+
+				log_action(ACT_MKNOD, name, NULL, 0, 0, 0, type, major, minor, overWrite);
+				if ( !do_mknod(name, type, major, minor))
+					log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), name);
+				break;
+
+			case 's':
+			case 'p':
+				if ( type == 's' )
+					mode |= LINUX_S_IFSOCK;
+				else	mode |= LINUX_S_IFIFO;
+
+				if ( overWrite ) {
+					log_action(ACT_RM, name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
+					if ( !do_rm(name))
+						log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), name);
+				}
+
+				log_action(ACT_MKNOD, name, NULL, 0, 0, 0, type, 0, 0, overWrite);
+				if ( !do_mknod(name, type, 0, 0))
+					log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), name);
+				break;
+			}
+
+			log_action(ACT_CHMOD, name, NULL, rmode, 0, 0, 0, 0, 0, 0);
+			if ( !do_chmod(name, rmode))
+				log_error("[Filesystem error] cannot chmod %s/%s", log_cwd(), name);
+			log_action(ACT_CHOWN, name, NULL, 0, uid, gid, 0, 0, 0, 0);
+			if ( !do_chown(name, uid, gid))
+				log_error("[Filesystem error] cannot chown %s/%s", log_cwd(), name);
+			log_action(ACT_CHDIR, "/", NULL, 0, 0, 0, 0, 0, 0, 0);
+			if ( !do_chdir("/"))
+				log_error("[Filesystem error] cannot chdir to root");
+		}
+
+	}
+
+
+	if ( line ) {
+		free( line ); line = NULL;
+	}
+	if ( path ) {
+		free( path ); path = NULL;
+	}
+	if ( path2 ) {
+		free( path2 ); path2 = NULL;
+	}
+
+}
Index: build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-version-patch/create.patch.sh
===================================================================
--- build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-version-patch/create.patch.sh	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-version-patch/create.patch.sh	(revision 231)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=1.0
+
+tar --files-from=file.list -xJvf ../populatefs-$VERSION.tar.xz
+mv populatefs-$VERSION populatefs-$VERSION-orig
+
+cp -rf ./populatefs-$VERSION-new ./populatefs-$VERSION
+
+diff -b --unified -Nr  populatefs-$VERSION-orig  populatefs-$VERSION > populatefs-$VERSION-version.patch
+
+mv populatefs-$VERSION-version.patch ../patches
+
+rm -rf ./populatefs-$VERSION
+rm -rf ./populatefs-$VERSION-orig

Property changes on: build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-version-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-version-patch/file.list
===================================================================
--- build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-version-patch/file.list	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-version-patch/file.list	(revision 231)
@@ -0,0 +1 @@
+populatefs-1.0/Makefile
Index: build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-version-patch/populatefs-1.0-new/Makefile
===================================================================
--- build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-version-patch/populatefs-1.0-new/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-version-patch/populatefs-1.0-new/Makefile	(revision 231)
@@ -0,0 +1,108 @@
+DESTDIR?=
+prefix?=/usr
+bindir?=${prefix}/bin
+libdir?=${prefix}/lib
+includedir?=${prefix}/include
+CC?=gcc
+AR?=ar
+RANLIB?=ranlib
+CP=cp
+LN_S?=ln -s
+RM?=rm -f
+MKDIR?=mkdir
+RMDIR?=rmdir
+INSTALL?=install
+STRIP?=strip -s
+CFLAGS?= -fPIC -Wall
+EXTRA_CFLAGS?= -DHAVE_GETOPT_H=1
+INCLUDES?=
+LDFLAGS?= -L/usr/lib
+EXTRA_LDFLAGS?=
+LIBS= -lext2fs -lm
+EXTRA_LIBS?=
+EXTRAVERSION?=
+
+##################################################
+#                                                #
+#  Don't go changing stuff further this point..  #
+#  Unless, you really know what you are doing..  #
+#                                                #
+##################################################
+
+VERSION_MAJOR=1
+VERSION_MINOR=0
+VERSION=$(VERSION_MAJOR).$(VERSION_MINOR)
+LIBPOPULATEFS=libpopulatefs
+LIBPOPULATEFS_DEPENDS=src/debugfs.o src/util.o src/linklist.o src/mod_file.o src/mod_path.o src/log.o
+LDADD_LIBPOPULATEFS= -lpopulatefs
+OBJS=src/util.o src/log.o src/linklist.o src/debugfs.o src/mod_path.o src/mod_file.o
+HDRS=src/log.h src/util.h src/linklist.h src/debugfs.h src/mod_path.h src/mod_file.h
+
+all: $(HDRS) $(OBJS) src/main.o src/$(LIBPOPULATEFS).a src/$(LIBPOPULATEFS).so.$(VERSION) src/populatefs
+
+src/populatefs: src/main.o src/$(LIBPOPULATEFS).a $(HDRS)
+	$(CC) $< -o $@ -L./src $(LDFLAGS) $(EXTRA_LDFLAGS) -Wl,-Bstatic $(LDADD_LIBPOPULATEFS) -Wl,-Bdynamic $(LIBS) $(EXTRA_LIBS)
+
+src/%.o: src/%.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DPOPULATEFS_VERSION="\"$(VERSION)\"" -DPOPULATEFS_EXTRAVERSION="\"$(EXTRAVERSION)\"" $(INCLUDES) -c $< -o $@
+
+src/$(LIBPOPULATEFS).a: $(LIBPOPULATEFS_DEPENDS)
+	$(AR)	rcsv $@	$(LIBPOPULATEFS_DEPENDS)
+	$(RANLIB) $@
+
+src/$(LIBPOPULATEFS).so.$(VERSION): $(LIBPOPULATEFS_DEPENDS)
+	$(CC) -shared -Wl,-soname,$(LIBPOPULATEFS).so -Wl,-soname,$(LIBPOPULATEFS).so.$(VERSION_MAJOR) -o $@	$(LIBPOPULATEFS_DEPENDS)
+
+install-bin: src/populatefs
+	$(MKDIR) -p $(DESTDIR)/$(bindir)
+	$(INSTALL) src/populatefs $(DESTDIR)/$(bindir)/
+	$(STRIP) $(DESTDIR)/$(bindir)/populatefs
+
+install-headers: $(HDRS)
+	$(MKDIR) -p $(DESTDIR)/$(includedir)/populatefs
+	$(CP) src/log.h $(DESTDIR)/$(includedir)/populatefs/
+	$(CP) src/util.h $(DESTDIR)/$(includedir)/populatefs/
+	$(CP) src/linklist.h $(DESTDIR)/$(includedir)/populatefs/
+	$(CP) src/debugfs.h $(DESTDIR)/$(includedir)/populatefs/
+	$(CP) src/mod_path.h $(DESTDIR)/$(includedir)/populatefs/
+	$(CP) src/mod_file.h $(DESTDIR)/$(includedir)/populatefs/
+
+install-libs: src/$(LIBPOPULATEFS).so.$(VERSION)
+	$(MKDIR) -p $(DESTDIR)/$(libdir)
+	$(RM) $(DESTDIR)/$(libdir)/$(LIBPOPULATEFS).so.$(VERSION_MAJOR) \
+		$(DESTDIR)/$(libdir)//$(LIBPOPULATEFS).so
+	$(INSTALL) src/$(LIBPOPULATEFS).so.$(VERSION) $(DESTDIR)/$(libdir)/
+	$(STRIP) $(DESTDIR)/$(libdir)/$(LIBPOPULATEFS).so.$(VERSION)
+	$(LN_S) $(LIBPOPULATEFS).so.$(VERSION) $(DESTDIR)/$(libdir)/$(LIBPOPULATEFS).so.$(VERSION_MAJOR)
+	$(LN_S) $(LIBPOPULATEFS).so.$(VERSION) $(DESTDIR)/$(libdir)/$(LIBPOPULATEFS).so
+
+install-static-libs: src/$(LIBPOPULATEFS).a
+	$(MKDIR) -p $(DESTDIR)/$(libdir)
+	$(CP) src/$(LIBPOPULATEFS).a $(DESTDIR)/$(libdir)/
+
+uninstall-bin:
+	$(RM) $(DESTDIR)/$(bindir)/populatefs
+
+uninstall-headers:
+	$(RM) $(DESTDIR)/$(includedir)/populatefs/log.h
+	$(RM) $(DESTDIR)/$(includedir)/populatefs/util.h
+	$(RM) $(DESTDIR)/$(includedir)/populatefs/linklist.h
+	$(RM) $(DESTDIR)/$(includedir)/populatefs/debugfs.h
+	$(RM) $(DESTDIR)/$(includedir)/populatefs/mod_path.h
+	$(RM) $(DESTDIR)/$(includedir)/populatefs/mod_file.h
+	$(RMDIR) --ignore-fail-on-non-empty $(DESTDIR)/$(includedir)/populatefs
+
+uninstall-libs:
+	$(RM) $(DESTDIR)/$(libdir)/$(LIBPOPULATEFS).so*
+	$(RMDIR) --ignore-fail-on-non-empty $(DESTDIR)/$(libdir)/populatefs
+
+uninstall-static-libs:
+	$(RM) $(DESTDIR)/$(libdir)/populatefs/$(LIBPOPULATEFS).a
+	$(RMDIR) --ignore-fail-on-non-empty $(DESTDIR)/$(libdir)/populatefs
+
+install: all install-bin install-headers install-libs
+
+uninstall: uninstall-bin uninstall-libs
+
+clean:
+	$(RM) src/*.o src/*.a src/*.so* src/populatefs
Index: build-system-1.2.3/3pp/sources/packages/populatefs/patches/README
===================================================================
--- build-system-1.2.3/3pp/sources/packages/populatefs/patches/README	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/populatefs/patches/README	(revision 231)
@@ -0,0 +1,10 @@
+
+/* begin *
+
+   populatefs-1.0-squash.patch         - Original populatefs owerrides uid:gid defined by devices table.
+                                         This is an issue. This patch changes this behaviour according
+                                         to normal genext2fs tool.
+   populatefs-1.0-notrunc-rfiles.patch - Not truncate existed files it new owner and permissions are
+                                         defined in the device table.
+
+ * end */
Index: build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-squash-patch/create.patch.sh
===================================================================
--- build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-squash-patch/create.patch.sh	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-squash-patch/create.patch.sh	(revision 231)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=1.0
+
+tar --files-from=file.list -xJvf ../populatefs-$VERSION.tar.xz
+mv populatefs-$VERSION populatefs-$VERSION-orig
+
+cp -rf ./populatefs-$VERSION-new ./populatefs-$VERSION
+
+diff -b --unified -Nr  populatefs-$VERSION-orig  populatefs-$VERSION > populatefs-$VERSION-squash.patch
+
+mv populatefs-$VERSION-squash.patch ../patches
+
+rm -rf ./populatefs-$VERSION
+rm -rf ./populatefs-$VERSION-orig

Property changes on: build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-squash-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-squash-patch/file.list
===================================================================
--- build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-squash-patch/file.list	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-squash-patch/file.list	(revision 231)
@@ -0,0 +1 @@
+populatefs-1.0/src/main.c
Index: build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-squash-patch/populatefs-1.0-new/src/main.c
===================================================================
--- build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-squash-patch/populatefs-1.0-new/src/main.c	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/populatefs/create-1.0-squash-patch/populatefs-1.0-new/src/main.c	(revision 231)
@@ -0,0 +1,143 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#else
+extern int optind;
+extern char *optarg;
+#endif
+
+#include "debugfs.h"
+#include "linklist.h"
+#include "log.h"
+#include "mod_file.h"
+#include "mod_path.h"
+
+#define MAX_SOURCES 128
+
+int main(int argc, char **argv)
+{
+
+	const char *usage =
+		"Usage: %s [options] image\r\n"
+		"Manipulate disk image from directories/files\r\n\n"
+		" -d <directory>   Add the given directory and contents at a particular path to root\r\n"
+		" -D <file>        Add device nodes and directories from filespec\r\n"
+		" -U               Squash owners making all files be owner by root:root\r\n"
+		" -P               Squash permissions on all files\r\n"
+		" -q               Same as \"-U -P\"\r\n"
+		" -h               Display this usage guide\r\n"
+		" -V               Show version\r\n"
+		" -v               Be verbose\r\n"
+		" -w               Be even more verbose\r\n"
+		"\n";
+
+	const char *version =
+		"populatefs %s%s\n";
+
+	int c;
+	int sourcenum = 0;
+	char *source[MAX_SOURCES];
+	FILE *fd;
+	int squash_uids = 0;
+	int squash_perms = 0;
+	int firstRun = 1;
+
+	setLoggingLevel(LOG_OFF);
+
+	while ((c = getopt(argc, argv, "d:D:UPqVvw")) != EOF) {
+		switch (c) {
+		case 'd':
+		case 'D':
+			source[sourcenum] = optarg;
+
+			// Remove trailing slash from path name..
+			if (( source[sourcenum][strlen(source[sourcenum]) - 1] == '/' ) && ( source[sourcenum][1] != 0 ))
+				source[sourcenum][strlen(source[sourcenum]) - 1] = 0;
+
+			sourcenum++;
+			break;
+		case 'U':
+			squash_uids = 1;
+			break;
+		case 'P':
+			squash_perms = 1;
+			break;
+		case 'q':
+			squash_uids = squash_perms = 1;
+			break;
+		case 'v':
+			setLoggingLevel(LOG_ON);
+			break;
+		case 'w':
+			setLoggingLevel(LOG_VERBOSE);
+			break;
+		case 'V':
+			printf(version, POPULATEFS_VERSION, POPULATEFS_EXTRAVERSION);
+			exit(0);
+		default:
+			printf(usage, argv[0]);
+			return 1;
+		}
+	}
+
+	if ((( sourcenum == 0 ) && ( squash_uids == 0 )) || ( optind != argc - 1 )) {
+		printf(usage, argv[0]);
+		return 1;
+	}
+
+	if ( logLevel())
+		printf(version, POPULATEFS_VERSION, POPULATEFS_EXTRAVERSION);
+
+	if ( !fs_isClosed())
+		log_error("[Filesystem error] Filesystem image %s already open.", argv[optind]);
+
+	if ( !open_filesystem(argv[optind]))
+		log_error("[Filesystem error] %s cannot be opened.", argv[optind]);
+
+	if ( !fs_isReadWrite())
+		log_error("[Filesystem error] %s cannot be opened with write priviledges.", argv[optind]);
+
+	for (c = 0; c < sourcenum; c++) {
+		struct stat st;
+		stat(source[c], &st);
+
+		if (( st.st_mode & S_IFMT ) == S_IFREG )
+			printf("Populating filesystem from filespec (%s)\r\n", source[c]);
+		else if (( st.st_mode & S_IFMT ) == S_IFDIR )
+			printf("Populating filesystem from path (%s)\r\n", source[c]);
+		else
+			log_error("%s is neither a file nor existing path.", source[c]);
+
+		log_action(ACT_CHDIR, "/", NULL, 0, 0, 0, 0, 0, 0, 0);
+		do_chdir("/");
+		switch (st.st_mode & S_IFMT) {
+		case S_IFREG:
+			if (( fd = fopen(source[c], "rb")) == NULL)
+				log_error("Cannot open %s for reading.", source[c]);
+			if ( firstRun ) {
+				log_action(ACT_CHOWN, "/", NULL, 0, squash_uids ? 0 : st.st_uid, squash_uids ? 0 : st.st_gid, 0, 0, 0, 0);
+				do_chown(".", squash_uids ? 0 : st.st_uid, squash_uids ? 0 : st.st_gid);
+				firstRun = 0;
+			}
+			addFilespec(fd, 0, 0);
+			fclose(fd);
+			break;
+		case S_IFDIR:
+			modPath_set_pathLen(strlen(source[c]));
+			addPath(source[c], squash_uids, squash_perms);
+			linklist_release();
+			break;
+		}
+	}
+
+	if ( !close_filesystem())
+		log_error("[Filesystem error] Cannot close %s properly.", argv[optind]);
+
+	purge_warnings();
+	printf("Filesystem %s populated.\r\n", argv[optind]);
+
+	return 0;
+}
Index: build-system-1.2.3/3pp/sources/packages/jsmin/Makefile
===================================================================
--- build-system-1.2.3/3pp/sources/packages/jsmin/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/jsmin/Makefile	(revision 231)
@@ -0,0 +1,48 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/packages/a/jsmin
+
+
+versions    = 0.0.1
+pkgname     = jsmin
+suffix      = tar.gz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s)
+
+
+include ../../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======\n" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) -i & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s)
Index: build-system-1.2.3/3pp/sources/packages/Makefile
===================================================================
--- build-system-1.2.3/3pp/sources/packages/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/sources/packages/Makefile	(revision 231)
@@ -0,0 +1,13 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+SOURCE_REQUIRES += ALL_DIRS
+
+
+include ../../../../build-system/core.mk
+
+
+download_clean:
+	@true
+
+.PHONY: download_clean
Index: build-system-1.2.3/3pp/sources/Makefile
===================================================================
--- build-system-1.2.3/3pp/sources/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/sources/Makefile	(revision 231)
@@ -0,0 +1,13 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+SOURCE_REQUIRES += ALL_DIRS
+
+
+include ../../../build-system/core.mk
+
+
+download_clean:
+	@true
+
+.PHONY: download_clean
Index: build-system-1.2.3/3pp/python2/2.7.11/Makefile
===================================================================
--- build-system-1.2.3/3pp/python2/2.7.11/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/python2/2.7.11/Makefile	(revision 231)
@@ -0,0 +1,70 @@
+
+COMPONENT_TARGETS = $(HARDWARE_BUILD)
+
+include ../../../../build-system/constants.mk
+
+SOURCE_REQUIRES = build-system/3pp/sources/packages/python2
+
+
+# ======= __END_OF_REQUIRES__ =======
+
+version         = 2.7.11
+tar_xz_archive  = $(BUILDSYSTEM)/3pp/sources/packages/python2/Python-$(version).tar.xz
+SRC_ARCHIVE     = $(tar_xz_archive)
+SRC_DIR         = $(TARGET_BUILD_DIR)/Python-$(version)
+src_done        = $(TARGET_BUILD_DIR)/.source-done
+
+PATCHES = PATCHES
+
+build_target    = $(TARGET_BUILD_DIR)/.built
+install_target  = $(TARGET_BUILD_DIR)/.installed
+
+
+LDFLAGS    += -Wl,-rpath,$(BUILDSYSTEM)/usr/lib
+
+extra_configure_switches  = --libdir=$(BUILDSYSTEM)/usr/lib
+extra_configure_switches += --bindir=$(BUILDSYSTEM)/usr/bin
+extra_configure_switches += --docdir=$(BUILDSYSTEM)/usr/share/doc/$(src_dir_name)
+extra_configure_switches += --mandir=$(BUILDSYSTEM)/usr/share/man
+extra_configure_switches += --with-system-expat
+extra_configure_switches += --with-system-ffi
+extra_configure_switches += --with-threads
+extra_configure_switches += --enable-ipv6
+extra_configure_switches += --enable-shared
+
+python_environment  = RFS=$(BUILDSYSTEM)
+python_environment += PYTHONHOME=$(BUILDSYSTEM)/usr/lib/python2.7
+python_environment += LDFLAGS='$(LDFLAGS)'
+
+
+BUILD_TARGETS = $(install_target)
+
+include ../../../../build-system/core.mk
+
+$(src_done): $(SRC_ARCHIVE) $(PATCHES_DEP)
+	$(UNPACK_SRC_ARCHIVE)
+	$(APPLY_PATCHES)
+	@touch $@
+
+$(build_target): $(src_done)
+	@cd $(SRC_DIR) && $(python_environment) ./configure \
+	  --prefix=$(BUILDSYSTEM)/usr \
+	  --exec-prefix=$(BUILDSYSTEM)/usr \
+	  --build=$(BUILD) \
+	  --host=$(BUILD)  \
+	  $(extra_configure_switches)
+	@cd $(SRC_DIR) && $(python_environment) $(MAKE)
+	@touch $@
+
+$(install_target): $(build_target)
+	@echo -e "\n======= Installing Python 2.7 binary =======\n"
+	@cd $(SRC_DIR) && $(MAKE) -j1 $(python_environment) install
+	@( cd $(BUILDSYSTEM)/usr/bin ; \
+	   mv 2to3  2to3-2.7 ; ln -sf 2to3-2.7 2to3   ; \
+	   mv idle  idle2.7  ; ln -sf idle2.7  idle2  ; ln -sf idle2  idle ; \
+	   mv pydoc pydoc2.7 ; ln -sf pydoc2.7 pydoc2 ; ln -sf pydoc2 pydoc; \
+	 )
+	@echo -e "\n======= Setup PYTHON2 build-system variable =======\n"
+	@mkdir -p $(BUILDSYSTEM)/sbin && \
+	  echo "PYTHON2 := $(BUILDSYSTEM)/usr/bin/python2" >> $(BUILDSYSTEM)/sbin/.config
+	@touch $@
Index: build-system-1.2.3/3pp/python2/2.7.11/PATCHES
===================================================================
Index: build-system-1.2.3/3pp/python3/3.5.1/Makefile
===================================================================
--- build-system-1.2.3/3pp/python3/3.5.1/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/python3/3.5.1/Makefile	(revision 231)
@@ -0,0 +1,71 @@
+
+COMPONENT_TARGETS = $(HARDWARE_BUILD)
+
+include ../../../../build-system/constants.mk
+
+SOURCE_REQUIRES = build-system/3pp/sources/packages/python3
+
+
+# ======= __END_OF_REQUIRES__ =======
+
+version         = 3.5.1
+tar_xz_archive  = $(BUILDSYSTEM)/3pp/sources/packages/python3/Python-$(version).tar.xz
+SRC_ARCHIVE     = $(tar_xz_archive)
+SRC_DIR         = $(TARGET_BUILD_DIR)/Python-$(version)
+src_done        = $(TARGET_BUILD_DIR)/.source-done
+
+PATCHES = PATCHES
+
+build_target    = $(TARGET_BUILD_DIR)/.built
+install_target  = $(TARGET_BUILD_DIR)/.installed
+
+
+LDFLAGS    += -Wl,-rpath,$(BUILDSYSTEM)/usr/lib
+
+extra_configure_switches  = --libdir=$(BUILDSYSTEM)/usr/lib
+extra_configure_switches += --bindir=$(BUILDSYSTEM)/usr/bin
+extra_configure_switches += --docdir=$(BUILDSYSTEM)/usr/share/doc/$(src_dir_name)
+extra_configure_switches += --mandir=$(BUILDSYSTEM)/usr/share/man
+extra_configure_switches += --with-system-expat
+extra_configure_switches += --with-system-ffi
+extra_configure_switches += --with-threads
+extra_configure_switches += --enable-ipv6
+extra_configure_switches += --enable-shared
+
+python_environment  = RFS=$(BUILDSYSTEM)
+python_environment += PYTHONHOME=$(BUILDSYSTEM)/usr/lib/python3.5
+python_environment += LDFLAGS='$(LDFLAGS)'
+
+
+BUILD_TARGETS = $(install_target)
+
+include ../../../../build-system/core.mk
+
+$(src_done): $(SRC_ARCHIVE) $(PATCHES_DEP)
+	$(UNPACK_SRC_ARCHIVE)
+	$(APPLY_PATCHES)
+	@touch $@
+
+$(build_target): $(src_done)
+	@cd $(SRC_DIR) && $(python_environment) ./configure \
+	  --prefix=$(BUILDSYSTEM)/usr \
+	  --exec-prefix=$(BUILDSYSTEM)/usr \
+	  --build=$(BUILD) \
+	  --host=$(BUILD)  \
+	  $(extra_configure_switches)
+	@cd $(SRC_DIR) && $(python_environment) $(MAKE)
+	@touch $@
+
+$(install_target): $(build_target)
+	@echo -e "\n======= Installing Python 3.5 binary =======\n"
+	@cd $(SRC_DIR) && $(MAKE) -j1 $(python_environment) install
+	@echo -e "\n======= tune python3.5m-config CFLAGS for target machine =======\n"
+	@( cd $(BUILDSYSTEM)/usr/bin ; \
+	   sed -i 's,includedir=$$(echo "$${prefix},includedir=$$(echo "/usr,g' python3.5m-config ; \
+	   sed -i 's,LIBPL=$$(echo "$${prefix},LIBPL=$$(echo "/usr,g' python3.5m-config ; \
+	   sed -i "s,$(BUILDSYSTEM),,g" python3.5m-config ; \
+	 )
+	@echo -e "\n======= Setup PYTHON3 build-system variable =======\n"
+	@mkdir -p $(BUILDSYSTEM)/sbin && \
+	  echo "PYTHON3 := $(BUILDSYSTEM)/usr/bin/python3" >> $(BUILDSYSTEM)/sbin/.config
+	@touch $@
Index: build-system-1.2.3/3pp/python3/3.5.1/PATCHES
===================================================================
Index: build-system-1.2.3/3pp/sqlite/3.12.2.0/Makefile
===================================================================
--- build-system-1.2.3/3pp/sqlite/3.12.2.0/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/sqlite/3.12.2.0/Makefile	(revision 231)
@@ -0,0 +1,56 @@
+
+COMPONENT_TARGETS = $(HARDWARE_BUILD)
+
+include ../../../../build-system/constants.mk
+
+SOURCE_REQUIRES = build-system/3pp/sources/packages/sqlite
+
+
+# ======= __END_OF_REQUIRES__ =======
+
+version         = 3.12.2.0
+tar_gz_archive  = $(BUILDSYSTEM)/3pp/sources/packages/sqlite/sqlite-$(version).tar.gz
+src_dir         = sqlite-$(version)
+build_dir       = $(TARGET_BUILD_DIR)/built
+
+src_done        = $(TARGET_BUILD_DIR)/.source-done
+SRC_DIR         = $(TARGET_BUILD_DIR)/sqlite-$(version)
+SRC_ARCHIVE     = $(tar_gz_archive)
+
+PATCHES = PATCHES
+
+build_target    = $(TARGET_BUILD_DIR)/.built
+install_target  = $(TARGET_BUILD_DIR)/.installed
+
+environment     =
+extra_configure_switches  = --libdir=/usr/lib
+extra_configure_switches += --docdir=/usr/share/doc/$(src_dir)
+extra_configure_switches += --mandir=/usr/share/man
+extra_configure_switches += --localstatedir=/var
+extra_configure_switches += --enable-threadsafe=yes
+extra_configure_switches += --enable-dynamic-extensions=yes
+extra_configure_switches += --disable-dependency-tracking
+extra_configure_switches += --enable-static=yes
+extra_configure_switches += --enable-shared=yes
+
+BUILD_TARGETS = $(install_target)
+
+include ../../../../build-system/core.mk
+
+$(src_done): $(SRC_ARCHIVE) $(PATCHES_DEP)
+	$(UNPACK_SRC_ARCHIVE)
+	$(APPLY_PATCHES)
+	@touch $@
+
+$(build_target): $(src_done)
+	@mkdir -p $(build_dir)
+	@cd $(build_dir) && $(environment) ../$(src_dir)/configure \
+	  --prefix=/usr \
+	  $(extra_configure_switches)
+	@$(environment) $(MAKE) -C $(build_dir) all
+	@touch $@
+
+$(install_target): $(build_target)
+	@echo -e "\n======= Installing SQLite binary =======\n"
+	@cd $(build_dir) && $(MAKE) install DESTDIR=$(BUILDSYSTEM)
+	@touch $@
Index: build-system-1.2.3/3pp/sqlite/3.12.2.0/PATCHES
===================================================================
Index: build-system-1.2.3/3pp/genext2fs/1.4.1/Makefile
===================================================================
--- build-system-1.2.3/3pp/genext2fs/1.4.1/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/genext2fs/1.4.1/Makefile	(revision 231)
@@ -0,0 +1,57 @@
+
+COMPONENT_TARGETS = $(HARDWARE_BUILD)
+
+include ../../../../build-system/constants.mk
+
+SOURCE_REQUIRES = build-system/3pp/sources/packages/genext2fs
+
+
+# ======= __END_OF_REQUIRES__ =======
+
+
+version         = 1.4.1
+tar_gz_archive  = $(BUILDSYSTEM)/3pp/sources/packages/genext2fs/genext2fs-$(version).tar.gz
+src_dir         = genext2fs-$(version)
+build_dir       = $(TARGET_BUILD_DIR)/built
+
+src_done        = $(TARGET_BUILD_DIR)/.source-done
+SRC_DIR         = $(TARGET_BUILD_DIR)/genext2fs-$(version)
+SRC_ARCHIVE     = $(tar_gz_archive)
+
+PATCHES = PATCHES
+
+build_target    = $(TARGET_BUILD_DIR)/.built
+install_target  = $(TARGET_BUILD_DIR)/.installed
+
+environment     =
+
+BUILD_TARGETS = $(install_target)
+
+
+include ../../../../build-system/core.mk
+
+
+extra_configure_switches = --libdir=/usr/lib$(BUILD_MULTILIB_SUFFIX)
+
+$(src_done): $(SRC_ARCHIVE) $(PATCHES_DEP)
+	$(UNPACK_SRC_ARCHIVE)
+	$(APPLY_PATCHES)
+	@touch $@
+
+$(build_target): $(src_done)
+	@mkdir -p $(build_dir)
+	@( cd $(SRC_DIR) ; \
+	   autoreconf -i ; rm -rf autom4te.cache ; rm -f *~ ; \
+	 )
+	@cd $(build_dir) && $(environment) ../$(src_dir)/configure \
+	  --prefix=/usr \
+	  $(extra_configure_switches)
+	@$(environment) $(MAKE) -C $(build_dir) all
+	@touch $@
+
+$(install_target): $(build_target)
+	@echo -e "\n======= Installing genext2fs binary =======\n"
+	@mkdir -p $(BUILDSYSTEM)/sbin && \
+	  cp -a $(build_dir)/genext2fs $(BUILDSYSTEM)/sbin && \
+	  echo "GENEXT2FS := $(BUILDSYSTEM)/sbin/genext2fs" >> $(BUILDSYSTEM)/sbin/.config
+	@touch $@
Index: build-system-1.2.3/3pp/genext2fs/1.4.1/PATCHES
===================================================================
--- build-system-1.2.3/3pp/genext2fs/1.4.1/PATCHES	(nonexistent)
+++ build-system-1.2.3/3pp/genext2fs/1.4.1/PATCHES	(revision 231)
@@ -0,0 +1,3 @@
+
+../../sources/packages/genext2fs/patches/genext2fs-1.4.1-blocksize.patch -p0
+../../sources/packages/genext2fs/patches/genext2fs-1.4.1-configure.patch -p0
Index: build-system-1.2.3/3pp/populatefs/1.0/PATCHES
===================================================================
--- build-system-1.2.3/3pp/populatefs/1.0/PATCHES	(nonexistent)
+++ build-system-1.2.3/3pp/populatefs/1.0/PATCHES	(revision 231)
@@ -0,0 +1,4 @@
+
+../../sources/packages/populatefs/patches/populatefs-1.0-squash.patch         -p0
+../../sources/packages/populatefs/patches/populatefs-1.0-notrunc-rfiles.patch -p0
+../../sources/packages/populatefs/patches/populatefs-1.0-version.patch        -p0
Index: build-system-1.2.3/3pp/populatefs/1.0/Makefile
===================================================================
--- build-system-1.2.3/3pp/populatefs/1.0/Makefile	(nonexistent)
+++ build-system-1.2.3/3pp/populatefs/1.0/Makefile	(revision 231)
@@ -0,0 +1,55 @@
+
+COMPONENT_TARGETS = $(HARDWARE_BUILD)
+
+include ../../../../build-system/constants.mk
+
+SOURCE_REQUIRES = build-system/3pp/sources/packages/populatefs
+
+
+# ======= __END_OF_REQUIRES__ =======
+
+
+version         = 1.0
+tar_xz_archive  = $(BUILDSYSTEM)/3pp/sources/packages/populatefs/populatefs-$(version).tar.xz
+src_dir         = populatefs-$(version)
+build_dir       = $(TARGET_BUILD_DIR)/built
+
+src_done        = $(TARGET_BUILD_DIR)/.source-done
+SRC_DIR         = $(TARGET_BUILD_DIR)/populatefs-$(version)
+SRC_ARCHIVE     = $(tar_xz_archive)
+
+PATCHES = PATCHES
+
+build_target    = $(TARGET_BUILD_DIR)/.built
+install_target  = $(TARGET_BUILD_DIR)/.installed
+
+BUILD_TARGETS = $(install_target)
+
+
+include ../../../../build-system/core.mk
+
+
+environment     = prefix=/usr
+environment    += bindir=/sbin
+environment    += libdir=/usr/lib$(BUILD_MULTILIB_SUFFIX)
+environment    += includedir=/usr/include
+environment    += LDFLAGS=-L/usr/lib$(BUILD_MULTILIB_SUFFIX)
+
+
+$(src_done): $(SRC_ARCHIVE) $(PATCHES_DEP)
+	$(UNPACK_SRC_ARCHIVE)
+	$(APPLY_PATCHES)
+	@touch $@
+
+$(build_target): $(src_done)
+	@( cd $(SRC_DIR) ; \
+	   $(MAKE) $(environment) ; \
+	 )
+	@touch $@
+
+$(install_target): $(build_target)
+	@echo -e "\n======= Installing POPULATEFS binary =======\n"
+	@mkdir -p $(BUILDSYSTEM)/sbin && \
+	  cp -a $(SRC_DIR)/src/populatefs $(BUILDSYSTEM)/sbin && \
+	  echo "POPULATEFS := $(BUILDSYSTEM)/sbin/populatefs" >> $(BUILDSYSTEM)/sbin/.config
+	@touch $@
Index: build-system-1.2.3/Makefile
===================================================================
--- build-system-1.2.3/Makefile	(nonexistent)
+++ build-system-1.2.3/Makefile	(revision 231)
@@ -0,0 +1,62 @@
+
+COMPONENT_TARGETS = $(HARDWARE_BUILD)
+
+include constants.mk
+
+REQUIRES  = build-system/3pp/dialog/1.2-20140112
+REQUIRES += build-system/3pp/genext2fs/1.4.1
+REQUIRES += build-system/3pp/populatefs/1.0
+REQUIRES += build-system/3pp/jsmin/0.0.1
+REQUIRES += build-system/3pp/pseudo/1.8.1
+REQUIRES += build-system/3pp/python2/2.7.11
+REQUIRES += build-system/3pp/python3/3.5.1
+REQUIRES += build-system/progs
+
+
+# ======= __END_OF_REQUIRES__ =======
+
+
+config_makefile = build-config.mk
+
+BUILD_TARGETS = $(config_makefile)
+
+CLEANUP_FILES  = $(config_makefile)
+CLEANUP_FILES += $(CURDIR)/sbin
+CLEANUP_FILES += $(CURDIR)/usr
+CLEANUP_FILES += $(CURDIR)/var
+
+CLEANUP_FILES += $(CURDIR)/pkgtool/check-db-integrity
+CLEANUP_FILES += $(CURDIR)/pkgtool/check-package
+CLEANUP_FILES += $(CURDIR)/pkgtool/check-requires
+CLEANUP_FILES += $(CURDIR)/pkgtool/install-package
+CLEANUP_FILES += $(CURDIR)/pkgtool/make-package
+CLEANUP_FILES += $(CURDIR)/pkgtool/remove-package
+CLEANUP_FILES += $(CURDIR)/pkgtool/update-package
+
+
+# CORE Makefile:
+
+include core.mk
+
+
+$(config_makefile): $(config_makefile).template
+	@( cd $(CURDIR)/pkgtool ; \
+	   cat check-db-integrity.in | sed -e "s/@DISTRO@/$(DISTRO_NAME)/g" > check-db-integrity ; \
+	   cat check-package.in      | sed -e "s/@DISTRO@/$(DISTRO_NAME)/g" > check-package      ; \
+	   cat check-requires.in     | sed -e "s/@DISTRO@/$(DISTRO_NAME)/g" > check-requires     ; \
+	   cat install-package.in    | sed -e "s/@DISTRO@/$(DISTRO_NAME)/g" > install-package    ; \
+	   cat make-package.in       | sed -e "s/@MKPKGVERSION@/$(SYSTEM_VERSION)/g" \
+	                             | sed -e "s,@BUGURL@,$(BUG_URL),g"     > make-package       ; \
+	   cat remove-package.in     | sed -e "s/@DISTRO@/$(DISTRO_NAME)/g" > remove-package     ; \
+	   cat update-package.in     | sed -e "s/@DISTRO@/$(DISTRO_NAME)/g" > update-package     ; \
+	   chmod 0755 check-db-integrity ; \
+	   chmod 0755 check-package      ; \
+	   chmod 0755 check-requires     ; \
+	   chmod 0755 install-package    ; \
+	   chmod 0755 make-package       ; \
+	   chmod 0755 remove-package     ; \
+	   chmod 0755 update-package     ; \
+	 )
+	@mkdir -p $(CURDIR)/var/{tmp,pseudo}
+	@echo "Creating $(config_makefile) ..."
+	@cp $(config_makefile).template $@
Index: build-system-1.2.3/build_packages_list
===================================================================
--- build-system-1.2.3/build_packages_list	(nonexistent)
+++ build-system-1.2.3/build_packages_list	(revision 231)
@@ -0,0 +1,674 @@
+#!/usr/bin/perl
+
+use FindBin;
+use lib $FindBin::Bin;
+
+use strict;
+use warnings FATAL => 'all';
+
+use IO::Handle;
+use File::Basename;
+use File::Temp;
+
+use _kxLab;
+
+#
+# Generate $(HARDWARE).pkglist file for current directory
+#
+# usage:
+#   $0 topdir toolchain hardware
+#
+# where:
+#      'topdir' - is a absolute path to the top directory of checked out branch
+#   'toolchain' - is a TOOLCHAIN name
+#    'hardware' - is a HARDWARE variant
+#
+
+# global variables
+my ($build_system);
+my ($topdir, $toolchain, $hardware, $flavour);
+my ($target_build_dir, $requires_file);
+my ($pkglist_file);
+my ($distro_name, $distro_version, $url);
+my $tarball_suffix = "txz";
+
+my %sub_trees;
+my %tree;
+
+
+sub usage
+{
+  print <<EOF;
+
+Usage: $0 topdir toolchain hardware
+Where:
+          topdir - is a absolute path to the top of checked out branch;
+       toolchain - is a TOOLCHAIN name;
+        hardware - is a HARDWARE variant.
+
+EOF
+  exit;
+}
+
+#
+# Getting information from build-system/constants.mk
+#
+sub distro_name
+{
+  my $build_system = shift;
+  my $name;
+
+  open( FILE, "< $build_system/constants.mk" );
+
+  while( <FILE> )
+  {
+    if( /^DISTRO_NAME(.+= +)(.+)/ )
+    {
+      $name = $2;
+    }
+  }
+  close( FILE );
+
+  return $name;
+}
+
+sub distro_version
+{
+  my $build_system = shift;
+  my $name;
+
+  open( FILE, "< $build_system/constants.mk" );
+
+  while( <FILE> )
+  {
+    if( /^DISTRO_VERSION(.+= +)(.+)/ )
+    {
+      $name = $2;
+    }
+  }
+  close( FILE );
+
+  return $name;
+}
+
+sub bug_url
+{
+  my $build_system = shift;
+  my $url;
+
+  open( FILE, "< $build_system/constants.mk" );
+
+  while( <FILE> )
+  {
+    if( /^BUG_URL(.+= +)(.+)/ )
+    {
+      $url = $2;
+    }
+  }
+  close( FILE );
+
+  return $url;
+}
+
+#
+# Getting information from Makefile
+#
+sub pkg_rootfs_target
+{
+  my $makefile = shift;
+  my $install = "";
+
+  open( FILE, "< $makefile" );
+
+  while( <FILE> )
+  {
+    if( /^ROOTFS_TARGETS(.+= +)(.+)/ )
+    {
+      if( $2 ne "" ) { $install = "install"; }
+    }
+    elsif( /^ROOTFS_UPDATE_TARGETS(.+= +)(.+)/ )
+    {
+      if( $2 ne "" ) { $install = "update"; }
+    }
+  }
+  close( FILE );
+
+  if( $install eq "" ) { $install = "no";  }
+
+  return $install;
+}
+
+sub pkg_group
+{
+  my $makefile = shift;
+  my $group;
+
+  open( FILE, "< $makefile" );
+
+  while( <FILE> )
+  {
+    if( /^PKG_GROUP(.+= +)(.+)/ )
+    {
+      $group = $2;
+    }
+  }
+  close( FILE );
+
+  return $group;
+}
+
+sub pkg_name
+{
+  my $makefile = shift;
+  my $name = "";
+
+  open( FILE, "< $makefile" );
+
+  while( <FILE> )
+  {
+    if( /^[A-Z_0-9]*_PKG_NAME(.+= +)(.+)/ )
+    {
+      $name = $2;
+    }
+  }
+  close( FILE );
+
+  return $name;
+}
+
+sub pkg_version
+{
+  my $makefile = shift;
+  my $version;
+
+  open( FILE, "< $makefile" );
+
+  while( <FILE> )
+  {
+    if( /^[A-Z_0-9]*_PKG_VERSION(.+= +)(.+)/ )
+    {
+      $version = $2;
+    }
+  }
+  close( FILE );
+
+  return $version;
+}
+
+sub pkg_license
+{
+  my $makefile = shift;
+  my $license;
+
+  open( FILE, "< $makefile" );
+
+  while( <FILE> )
+  {
+    if( /^[A-Z_0-9]*_PKG_LICENSE(.+= +)(.+)/ )
+    {
+      $license = $2;
+    }
+  }
+  close( FILE );
+
+  return $license;
+}
+
+sub pkg_short_description
+{
+  my $makefile = shift;
+  my $description;
+
+  open( FILE, "< $makefile" );
+
+  while( <FILE> )
+  {
+    if( /^[A-Z_0-9]*_PKG_SHORT_DESCRIPTION(.+= +)(.+)/ )
+    {
+      $description = $2;
+    }
+  }
+  close( FILE );
+
+  #
+  # In Makefiles we have to mask characters '\', '&', '*', '(', ')' inside
+  # the new value in the assignment operator with backslash. So, for axample,
+  # the value "name & \ * ( ) end" we have to assign as follow
+  #
+  # ..._SHORT_DESCRIPTION = name \& \\ \* \( \) end
+  #
+  # Here we have to remove backslashes and fill escaped symbols as is:
+  #
+  $description =~ s/\\(.?)/$1/g;
+
+  return $description;
+}
+
+
+sub get_treedirs
+{
+  my @list;
+
+  seek( REQUIRES_FILE, 0, SEEK_SET );
+
+  while( <REQUIRES_FILE> )
+  {
+    if( /^TREEDIRS(.+= +)(.+)/ )
+    {
+      @list = split( ' ', $2 );
+    }
+  }
+
+  return @list;
+}
+
+sub get_root
+{
+  my $root;
+
+  seek( REQUIRES_FILE, 0, SEEK_SET );
+
+  while( <REQUIRES_FILE> )
+  {
+    if( /^# ROOT(=)(.+)/ )
+    {
+      $root = $2;
+    }
+  }
+
+  return $root;
+}
+
+sub get_deps
+{
+  my %deps;
+
+  seek( REQUIRES_FILE, 0, SEEK_SET );
+
+  while( <REQUIRES_FILE> )
+  {
+    if( /(.+)(: +)(.+)/ )
+    {
+      $deps{$1} = $3;
+    }
+  }
+  return %deps;
+}
+
+my $root_node = 1;
+
+#
+# PACKAGE HASH:
+# ============
+#
+#   name              => $(PKG_NAME)       from Makefile
+#   version           => $(PKG_VERSION)    from Makefile
+#   group             => $(PKG_GROUP)      from Makefile {app,base,dev,libs,net,...}
+#
+#   arch              => $toolchain        from comandline args
+#   hardware          => $hardware         from comandline args
+#   flavour           => $flavour          from comandline args for ROOT pkg, from REQUIRES for dependencies
+#   tarball           => "$name-$version-$arch-$distro_name-$distro_version.$tarball_suffix"
+#
+#   distro_name       => $(DISTRO_NAME)    from build-system/constants.mk
+#   distro_version    => $(DISTRO_VERSION) from build-system/constants.mk
+#   url               => $(BUG_URL)        from build-system/constants.mk
+#   license           =>                   from Makefile
+#   short_description =>                   from Makefile
+#   description       =>    first line     from .DESCRIPTION
+#   uncompressed_size =>                   from .PKGINFO
+#   total_files       =>                   from .PKGINFO
+#
+#   dir               => path to Makefile  from .$(HW)_requires
+#   children          =>
+#
+sub fill_package_info
+{
+  my $base_dir = shift;
+  my $makefile = shift;
+  my $flavour  = shift;
+  my ( $product_path, $tarball_file );
+  my %pkg;
+
+  $pkg{'dir'}     = $base_dir;
+  $pkg{'install'} = pkg_rootfs_target( $makefile );
+
+  $pkg{'name'} = pkg_name( $makefile );
+  if( $pkg{'name'} eq "" )
+  {
+    # There is no package for this Makefile
+    $pkg{'name'} = $pkg{'dir'};
+    return %pkg;
+  }
+
+  $pkg{'version'}           = pkg_version( $makefile );
+  $pkg{'arch'}              = $toolchain;
+  $pkg{'hardware'}          = $hardware;
+  $pkg{'flavour'}           = $flavour;
+  $pkg{'group'}             = pkg_group( $makefile );
+  $pkg{'distro_name'}       = $distro_name;
+  $pkg{'distro_version'}    = $distro_version;
+  $pkg{'url'}               = $url;
+  $pkg{'license'}           = pkg_license( $makefile );
+  $pkg{'short_description'} = pkg_short_description( $makefile );
+
+  $pkg{'tarball'} = $pkg{'name'}    . "-" . 
+                    $pkg{'version'} . "-" . 
+                    $pkg{'arch'}    . "-" . 
+                    $distro_name    . "-" . 
+                    $distro_version . "." . 
+                    $tarball_suffix;
+
+  return %pkg;
+}
+
+
+
+#
+# Parse the command line options
+#
+
+# Get the rest arguments of the command line
+$topdir    = shift;
+$toolchain = shift;
+$hardware  = shift;
+$flavour   = shift;
+
+my $makefile = "Makefile";
+
+if( ! defined $topdir    or $topdir eq "" )    { usage; }
+if( ! defined $toolchain or $toolchain eq "" ) { usage; }
+if( ! defined $hardware  or $hardware eq "" )  { usage; }
+if( ! defined $flavour   or $flavour eq "" )   { $flavour = ""; }
+
+_kxLab::error( "$0: $topdir is not a directory" ) if( ! -d $topdir );
+_kxLab::error( "$0: Makefile missing: $makefile" ) if ( ! -f $makefile );
+
+$build_system = $topdir . "/build-system";
+
+$distro_name    = distro_name( $build_system );
+$distro_version = distro_version( $build_system );
+$url            = bug_url( $build_system );
+
+
+if( $flavour eq "" )
+{
+  $target_build_dir  = "." . $toolchain . "/" . $hardware;
+}
+else
+{
+  $target_build_dir  = "." . $toolchain . "/" . $hardware . "/" . $flavour;
+}
+
+$requires_file  = $target_build_dir . "/.requires";
+
+if( $flavour eq "" )
+{
+  $pkglist_file   = $target_build_dir . "/" . $hardware . ".pkglist";
+}
+else
+{
+  $pkglist_file   = $target_build_dir . "/" . $hardware . "-" . $flavour . ".pkglist";
+}
+
+
+# open the intput file
+open(REQUIRES_FILE, "< $requires_file") or
+  _kxLab::error( "$0: Could not open $requires_file file: $!" );
+# open the output files
+open(PKGLIST_FILE, "> $pkglist_file") or
+  _kxLab::error( "$0: Could not open $pkglist_file file: $!" );
+
+
+my $root     = get_root();
+my @treedirs = get_treedirs();
+my %deps     = get_deps();
+
+#
+# This is the root package
+#
+%tree = fill_package_info( $root, $makefile, $flavour );
+
+my %sequence;
+my $order = 0;
+
+#################################################################
+# if( there is any dependencies )
+#
+if( %deps )
+{
+  my @dep_keys = keys %deps;
+
+  my $count = scalar( keys %deps );
+
+  foreach my $dir ( @treedirs )
+  {
+    if( ! grep { $_ eq $dir } @dep_keys )
+    {
+      my $key = $dir;
+      $sequence{$key} = ++$order;
+      @treedirs = grep { $_ ne $key } @treedirs;
+
+      # Split dir^flavour:
+      my ($d, $f);
+      $d = `echo $dir | cut -f 1 -d '^'`;
+      $d =~ s/^\s+|\s+$//;
+      if( $dir =~ m/\^/ )
+      {
+        $f = `echo $dir | cut -f 2 -d '^'`;
+        $f =~ s/^\s+|\s+$//;
+      }
+      else
+      {
+        $f = "";
+      }
+
+      # Insert into sub_trees:
+      my %pkg = fill_package_info( $d, $topdir . "/" . $d . "/Makefile", $f );
+      $sub_trees{$dir} = \%pkg;
+
+      delete $deps{$dir};
+    }
+  }
+
+
+  for( my $i = 0; $i < $count; ++$i )
+  {
+    my @installed = keys %sequence;
+
+    foreach my $key (sort keys %deps)
+    {
+      my $ok = 1;
+      my @dirs = split( ' ', $deps{$key} );
+
+      if( $key ne "all" )
+      {
+        foreach my $dir ( @dirs )
+        {
+          if( ! grep { $_ eq $dir } @installed )
+          {
+            $ok = 0;
+          }
+        }
+
+        if( $ok == 1 )
+        {
+          $sequence{$key} = ++$order;
+
+          # Split dir^flavour:
+          my ($d, $f);
+          $d = `echo $key | cut -f 1 -d '^'`;
+          $d =~ s/^\s+|\s+$//;
+          if( $key =~ m/\^/ )
+          {
+            $f = `echo $key | cut -f 2 -d '^'`;
+            $f =~ s/^\s+|\s+$//;
+          }
+          else
+          {
+            $f = "";
+          }
+
+          # create package node:
+          my %pkg = fill_package_info( $d, $topdir . "/" . $d . "/Makefile", $f );
+          # add children:
+          foreach my $dir ( @dirs )
+          {
+            my $child = $sub_trees{$dir};
+            push( @{$pkg{'children'}}, $child );
+          }
+
+          # insert new sub tree into $sub_tree:
+          $sub_trees{$key} = \%pkg;
+
+          delete $deps{$key};
+        }
+      }
+    }
+  }
+
+  #
+  # The root node children
+  #
+  my @dirs = split( ' ', $deps{'all'} );
+  foreach my $dir ( @dirs )
+  {
+    my $child = $sub_trees{$dir};
+    push( @{$tree{'children'}}, $child );
+  }
+
+}
+else
+{
+  my %pkg;
+
+  $pkg{'dir'}  = "void";
+  $pkg{'name'} = "void";
+
+  push( @{$tree{'children'}}, \%pkg );
+}
+#
+# End if( there is any dependencies )
+#################################################################
+
+
+#################################################################
+# Building Required Packages List:
+#
+sub compare_order
+{
+  $sequence{$a} <=> $sequence{$b};
+}
+
+print PKGLIST_FILE "#\n";
+print PKGLIST_FILE "# file format:\n";
+print PKGLIST_FILE "# ===========\n";
+print PKGLIST_FILE "#\n";
+print PKGLIST_FILE "# Each line contains six fields separated by colon symbol ':' like following.\n";
+print PKGLIST_FILE "#\n";
+print PKGLIST_FILE "# pkgname:version:description:tarball:procedure:priority\n";
+print PKGLIST_FILE "#\n";
+print PKGLIST_FILE "# where:\n";
+print PKGLIST_FILE "#\n";
+print PKGLIST_FILE "#   pkgname     - should be the same as the value of pkgname  in the '.DESCRIPTION' file;\n";
+print PKGLIST_FILE "#   version     - package version for showing in check list  dialog box  if this file is\n";
+print PKGLIST_FILE "#                 used to complete common check dialog for installing group  of packages;\n";
+print PKGLIST_FILE "#   description - short description for showing in check list dialog box if this file is\n";
+print PKGLIST_FILE "#                 used to complete common check dialog for installing  group of packages;\n";
+print PKGLIST_FILE "#   tarball     - should end in '." . $tarball_suffix . "';\n";
+print PKGLIST_FILE "#   procedure   - installation procedure {install | update}:\n";
+print PKGLIST_FILE "#                  * 'install' - if package requires normal installation,\n";
+print PKGLIST_FILE "#                  * 'update'  - if already installed package should be updated by this\n";
+print PKGLIST_FILE "#                                package archive;\n";
+print PKGLIST_FILE "#   priority    - { REQUIRED|RECOMMENDED|OPTIONAL|SKIP }\n";
+print PKGLIST_FILE "#                  synonims:\n";
+print PKGLIST_FILE "#                    { REQUIRED    | required    | REQ | req }\n";
+print PKGLIST_FILE "#                    { RECOMMENDED | recommended | REC | rec }\n";
+print PKGLIST_FILE "#                    { OPTIONAL    | optional    | OPT | opt }\n";
+print PKGLIST_FILE "#                    { SKIP        | skip        | SKP | skp }\n";
+print PKGLIST_FILE "#\n";
+
+
+my $packages_done = 0;
+
+sub print_result
+{
+  my $out_string = sprintf( "####### Packages Install List (done: %4d packages)\n", $packages_done );
+
+  print $out_string;
+}
+
+print "#######\n";
+
+foreach my $dir (sort compare_order( (keys %sequence) ))
+{
+  my $package;
+
+  if( $dir ne "all" )
+  {
+    $package = $sub_trees{$dir};
+    #
+    # Currently gcc-runtime has not ROOTFS_TARGET and not all packages requires GCC.
+    # We will not add GCC in this procedure forcibly. But developers have to care about
+    # competing packages GCC and gcc-runtime.
+    #
+    if( $package->{'install'} ne "no" )
+    {
+      if( $package->{'flavour'} eq "" )
+      {
+        print PKGLIST_FILE $package->{'name'}              . ":" .
+                           $package->{'version'}           . ":" .
+                           $package->{'short_description'} . ":" .
+                           $package->{'group'}             . "/" .
+                           $package->{'tarball'}           . ":" .
+                           $package->{'install'}           . ":REQUIRED\n";
+      }
+      else
+      {
+        print PKGLIST_FILE $package->{'name'}              . ":" .
+                           $package->{'version'}           . ":" .
+                           $package->{'short_description'} . ":" .
+                           $package->{'group'}             . "/" .
+                           $package->{'flavour'}           . "/" .
+                           $package->{'tarball'}           . ":" .
+                           $package->{'install'}           .  ":REQUIRED\n";
+      }
+      ++$packages_done;
+    }
+  }
+}
+
+if( $tree{'install'} ne "no" )
+{
+  if( $tree{'flavour'} eq "" )
+  {
+    print PKGLIST_FILE $tree{'name'}              . ":" .
+                       $tree{'version'}           . ":" .
+                       $tree{'short_description'} . ":" .
+                       $tree{'group'}             . "/" .
+                       $tree{'tarball'}           . ":" .
+                       $tree{'install'}           . ":REQUIRED\n";
+  }
+  else
+  {
+    print PKGLIST_FILE $tree{'name'}              . ":" .
+                       $tree{'version'}           . ":" .
+                       $tree{'short_description'} . ":" .
+                       $tree{'group'}             . "/" .
+                       $tree{'flavour'}           . "/" .
+                       $tree{'tarball'}           . ":" .
+                       $tree{'install'}           .  ":REQUIRED\n";
+  }
+  ++$packages_done;
+}
+
+print_result();
+print "#######\n";
+#
+# End of Building Required Packages List.
+#################################################################
+
+# close input files
+close REQUIRES_FILE;
+# close output files
+close PKGLIST_FILE;

Property changes on: build-system-1.2.3/build_packages_list
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/build_requires_tree
===================================================================
--- build-system-1.2.3/build_requires_tree	(nonexistent)
+++ build-system-1.2.3/build_requires_tree	(revision 231)
@@ -0,0 +1,895 @@
+#!/usr/bin/perl
+
+use FindBin;
+use lib $FindBin::Bin;
+
+use strict;
+use warnings FATAL => 'all';
+
+use IO::Handle;
+use File::Basename;
+use File::Temp;
+
+use _kxLab;
+
+#
+# Generate .$(HARDWARE).{json,html} file for current directory
+#
+# usage:
+#   $0 topdir toolchain hardware
+#
+# where:
+#      'topdir' - is a absolute path to the top directory of checked out branch
+#   'toolchain' - is a TOOLCHAIN name
+#    'hardware' - is a HARDWARE variant
+#
+
+# global variables
+my ($build_system);
+my ($topdir, $toolchain, $hardware, $flavour);
+my ($target_build_dir, $requires_file);
+my ($html_tree_file, $js_tree_file, $js_min_tree_file);
+my ($distro_name, $distro_version, $url);
+my $tarball_suffix = "txz";
+
+my %sub_trees;
+my %tree;
+
+
+sub usage
+{
+  print <<EOF;
+
+Usage: $0 topdir toolchain hardware
+Where:
+          topdir - is a absolute path to the top of checked out branch;
+       toolchain - is a TOOLCHAIN name;
+        hardware - is a HARDWARE variant.
+
+EOF
+  exit;
+}
+
+#
+# Getting information from build-system/constants.mk
+#
+sub distro_name
+{
+  my $build_system = shift;
+  my $name;
+
+  open( FILE, "< $build_system/constants.mk" );
+
+  while( <FILE> )
+  {
+    if( /^DISTRO_NAME(.+= +)(.+)/ )
+    {
+      $name = $2;
+    }
+  }
+  close( FILE );
+
+  return $name;
+}
+
+sub distro_version
+{
+  my $build_system = shift;
+  my $name;
+
+  open( FILE, "< $build_system/constants.mk" );
+
+  while( <FILE> )
+  {
+    if( /^DISTRO_VERSION(.+= +)(.+)/ )
+    {
+      $name = $2;
+    }
+  }
+  close( FILE );
+
+  return $name;
+}
+
+sub bug_url
+{
+  my $build_system = shift;
+  my $url;
+
+  open( FILE, "< $build_system/constants.mk" );
+
+  while( <FILE> )
+  {
+    if( /^BUG_URL(.+= +)(.+)/ )
+    {
+      $url = $2;
+    }
+  }
+  close( FILE );
+
+  return $url;
+}
+
+#
+# Getting information from Makefile
+#
+sub pkg_rootfs_target
+{
+  my $makefile = shift;
+  my $install = "";
+
+  open( FILE, "< $makefile" );
+
+  while( <FILE> )
+  {
+    if( /^ROOTFS_TARGETS(.+= +)(.+)/ )
+    {
+      if( $2 ne "" ) { $install = "install"; }
+    }
+    elsif( /^ROOTFS_UPDATE_TARGETS(.+= +)(.+)/ )
+    {
+      if( $2 ne "" ) { $install = "update"; }
+    }
+  }
+  close( FILE );
+
+  if( $install eq "" ) { $install = "no";  }
+#  else                 { $install = "yes"; }
+
+  return $install;
+}
+
+sub pkg_group
+{
+  my $makefile = shift;
+  my $group;
+
+  open( FILE, "< $makefile" );
+
+  while( <FILE> )
+  {
+    if( /^PKG_GROUP(.+= +)(.+)/ )
+    {
+      $group = $2;
+    }
+  }
+  close( FILE );
+
+  return $group;
+}
+
+sub pkg_name
+{
+  my $makefile = shift;
+  my $name = "";
+
+  open( FILE, "< $makefile" );
+
+  while( <FILE> )
+  {
+    if( /^[A-Z_0-9]*_PKG_NAME(.+= +)(.+)/ )
+    {
+      $name = $2;
+    }
+  }
+  close( FILE );
+
+  return $name;
+}
+
+sub pkg_version
+{
+  my $makefile = shift;
+  my $version;
+
+  open( FILE, "< $makefile" );
+
+  while( <FILE> )
+  {
+    if( /^[A-Z_0-9]*_PKG_VERSION(.+= +)(.+)/ )
+    {
+      $version = $2;
+    }
+  }
+  close( FILE );
+
+  return $version;
+}
+
+sub pkg_license
+{
+  my $makefile = shift;
+  my $license;
+
+  open( FILE, "< $makefile" );
+
+  while( <FILE> )
+  {
+    if( /^[A-Z_0-9]*_PKG_LICENSE(.+= +)(.+)/ )
+    {
+      $license = $2;
+    }
+  }
+  close( FILE );
+
+  return $license;
+}
+
+sub pkg_short_description
+{
+  my $makefile = shift;
+  my $description;
+
+  open( FILE, "< $makefile" );
+
+  while( <FILE> )
+  {
+    if( /^[A-Z_0-9]*_PKG_SHORT_DESCRIPTION(.+= +)(.+)/ )
+    {
+      $description = $2;
+    }
+  }
+  close( FILE );
+
+  #
+  # In Makefiles we have to mask characters '\', '&', '*', '(', ')' inside
+  # the new value in the assignment operator with backslash. So, for axample,
+  # the value "name & \ * ( ) end" we have to assign as follow
+  #
+  # ..._SHORT_DESCRIPTION = name \& \\ \* \( \) end
+  #
+  # Here we have to remove backslashes and fill escaped symbols as is:
+  #
+  $description =~ s/\\(.?)/$1/g;
+
+  return $description;
+}
+
+#
+# Getting information from tarball/{.PKGINFI | .DESCRIPTION}
+#
+sub get_pkg_info
+{
+  my $infofile   = shift;
+  my $data_field = shift;
+  my $data       = "";
+
+  open( FILE, "< $infofile" );
+
+  while( <FILE> )
+  {
+    if( /^$data_field=(.+)/ )
+    {
+      $data = $1;
+    }
+  }
+  close( FILE );
+
+  return $data;
+}
+
+sub get_pkg_description
+{
+  my $descfile   = shift;
+  my $data       = "";
+  my @fields;
+
+  open( FILE, "< $descfile" );
+
+  # Read the first line only
+  @fields = split( ':', <FILE> );
+  $data = $fields[1];
+  $data =~ s/^\s+|\s+$//;
+  $data =~ s/\"/\'/g;
+  chomp $data;
+
+  close( FILE );
+
+  return $data;
+}
+
+
+sub get_treedirs
+{
+  my @list;
+
+  seek( REQUIRES_FILE, 0, SEEK_SET );
+
+  while( <REQUIRES_FILE> )
+  {
+    if( /^TREEDIRS(.+= +)(.+)/ )
+    {
+      @list = split( ' ', $2 );
+    }
+  }
+
+  return @list;
+}
+
+sub get_ntreedirs
+{
+  my @list;
+
+  seek( REQUIRES_FILE, 0, SEEK_SET );
+
+  while( <REQUIRES_FILE> )
+  {
+    if( /^TREEDIRS(.+= +)(.+)/ )
+    {
+      @list = split( ' ', $2 );
+    }
+  }
+
+  return $#list;
+}
+
+sub get_root
+{
+  my $root;
+
+  seek( REQUIRES_FILE, 0, SEEK_SET );
+
+  while( <REQUIRES_FILE> )
+  {
+    if( /^# ROOT(=)(.+)/ )
+    {
+      $root = $2;
+    }
+  }
+
+  return $root;
+}
+
+sub get_deps
+{
+  my %deps;
+
+  seek( REQUIRES_FILE, 0, SEEK_SET );
+
+  while( <REQUIRES_FILE> )
+  {
+    if( /(.+)(: +)(.+)/ )
+    {
+      $deps{$1} = $3;
+    }
+  }
+  return %deps;
+}
+
+my $root_node = 1;
+
+#
+# PACKAGE HASH:
+# ============
+#
+#   name              => $(PKG_NAME)       from Makefile
+#   version           => $(PKG_VERSION)    from Makefile
+#   group             => $(PKG_GROUP)      from Makefile {app,base,dev,libs,net,...}
+#
+#   arch              => $toolchain        from comandline args
+#   hardware          => $hardware         from comandline args
+#   flavour           => $flavour          from comandline args for ROOT pkg, from REQUIRES for dependencies
+#   tarball           => "$name-$version-$arch-$distro_name-$distro_version.$tarball_suffix"
+#
+#   distro_name       => $(DISTRO_NAME)    from build-system/constants.mk
+#   distro_version    => $(DISTRO_VERSION) from build-system/constants.mk
+#   url               => $(BUG_URL)        from build-system/constants.mk
+#   license           =>                   from Makefile
+#   short_description =>                   from Makefile
+#   description       =>    first line     from .DESCRIPTION
+#   uncompressed_size =>                   from .PKGINFO
+#   total_files       =>                   from .PKGINFO
+#
+#   dir               => path to Makefile  from .$(HW)_requires
+#   children          =>
+#
+sub fill_package_info
+{
+  my $base_dir = shift;
+  my $makefile = shift;
+  my $flavour  = shift;
+  my ( $product_path, $tarball_file );
+  my %pkg;
+
+  $pkg{'dir'}     = $base_dir;
+  $pkg{'install'} = pkg_rootfs_target( $makefile );
+
+  $pkg{'name'} = pkg_name( $makefile );
+  if( $pkg{'name'} eq "" )
+  {
+    # There is no package for this Makefile
+    $pkg{'name'} = $pkg{'dir'};
+    return %pkg;
+  }
+
+  $pkg{'version'}           = pkg_version( $makefile );
+  $pkg{'arch'}              = $toolchain;
+  $pkg{'hardware'}          = $hardware;
+  $pkg{'flavour'}           = $flavour;
+  $pkg{'group'}             = pkg_group( $makefile );
+  $pkg{'distro_name'}       = $distro_name;
+  $pkg{'distro_version'}    = $distro_version;
+  $pkg{'url'}               = $url;
+  $pkg{'license'}           = pkg_license( $makefile );
+  $pkg{'short_description'} = pkg_short_description( $makefile );
+
+  $pkg{'tarball'} = $pkg{'name'}    . "-" . 
+                    $pkg{'version'} . "-" . 
+                    $pkg{'arch'}    . "-" . 
+                    $distro_name    . "-" . 
+                    $distro_version . "." . 
+                    $tarball_suffix;
+
+  $pkg{'description'}       = '';
+  $pkg{'uncompressed_size'} = '';
+  $pkg{'total_files'}       = '';
+
+  $product_path = $topdir . "/dist/products/" . $toolchain . "/" . $hardware;
+  if( $flavour eq "" )
+  {
+    $tarball_file = $product_path . "/" . $pkg{'group'} . "/" . $pkg{'tarball'};
+  }
+  else
+  {
+    $tarball_file = $product_path . "/" . $pkg{'group'} . "/" . $pkg{'flavour'} . "/" . $pkg{'tarball'};
+  }
+
+  if( -e $tarball_file )
+  {
+    my $cleanup = 1;
+    my $fname   = "$target_build_dir/.$hardware.pkginfo.XXXXXXXX";
+    my $tempname;
+
+    (undef, $tempname) = File::Temp::tempfile( $fname, OPEN => 0, UNLINK => $cleanup );
+
+    _kxLab::system( "xzcat $tarball_file | tar -xvf - \".PKGINFO\" -O  1> $tempname  2> /dev/null" );
+
+    $pkg{'uncompressed_size'} = get_pkg_info( $tempname, "uncompressed_size" );
+    $pkg{'total_files'}       = get_pkg_info( $tempname, "total_files" );
+
+    unlink $tempname;
+
+    (undef, $tempname) = File::Temp::tempfile( $fname, OPEN => 0, UNLINK => $cleanup );
+
+    _kxLab::system( "xzcat $tarball_file | tar -xvf - \".DESCRIPTION\" -O  1> $tempname  2> /dev/null" );
+    $pkg{ 'description' } = get_pkg_description( $tempname );
+
+    unlink $tempname;
+  }
+
+  return %pkg;
+}
+
+
+sub print_package_head
+{
+  my ( $level, $pkg )  = @_;
+  my $indent = "";
+
+  $level *= 2;
+  while( $level )
+  {
+    $indent .= " ";
+    $level--;
+  }
+  print JS_TREE_FILE $indent . "{\n";
+
+  if( $pkg->{'name'} eq $pkg->{'dir'} )
+  {
+    if( $root_node == 1 )
+    {
+      print JS_TREE_FILE $indent . " \"distro\": [\n";
+      print JS_TREE_FILE $indent . "  \"" . $distro_name . "\",\n";
+      print JS_TREE_FILE $indent . "  \"" . $distro_version . "\",\n";
+      print JS_TREE_FILE $indent . "  \"" . $url . "\"\n";
+      print JS_TREE_FILE $indent . " ],\n";
+    }
+    print JS_TREE_FILE $indent . " \"name\":     \"" . $pkg->{'name'} . "\"";
+  }
+  else
+  {
+    if( $root_node == 1 )
+    {
+      print JS_TREE_FILE $indent . " \"distro\": [\n";
+      print JS_TREE_FILE $indent . "  \"" . $distro_name . "\",\n";
+      print JS_TREE_FILE $indent . "  \"" . $distro_version . "\",\n";
+      print JS_TREE_FILE $indent . "  \"" . $url . "\"\n";
+      print JS_TREE_FILE $indent . " ],\n";
+    }
+    print JS_TREE_FILE $indent . " \"name\":              \"" . $pkg->{'name'}              . "\",\n";
+    print JS_TREE_FILE $indent . " \"version\":           \"" . $pkg->{'version'}           . "\",\n";
+    print JS_TREE_FILE $indent . " \"group\":             \"" . $pkg->{'group'}             . "\",\n";
+    print JS_TREE_FILE $indent . " \"arch\":              \"" . $pkg->{'arch'}              . "\",\n";
+    print JS_TREE_FILE $indent . " \"hardware\":          \"" . $pkg->{'hardware'}          . "\",\n";
+    print JS_TREE_FILE $indent . " \"flavour\":           \"" . $pkg->{'flavour'}           . "\",\n";
+    print JS_TREE_FILE $indent . " \"license\":           \"" . $pkg->{'license'}           . "\",\n";
+    print JS_TREE_FILE $indent . " \"description\":       \"" . $pkg->{'description'}       . "\",\n";
+    print JS_TREE_FILE $indent . " \"uncompressed_size\": \"" . $pkg->{'uncompressed_size'} . "\",\n";
+    print JS_TREE_FILE $indent . " \"total_files\":       \"" . $pkg->{'total_files'}       . "\"";
+  }
+}
+
+sub print_package_start_children
+{
+  my $level = shift;
+  my $indent = "";
+
+  $level *= 2;
+  while( $level )
+  {
+    $indent .= " ";
+    $level--;
+  }
+  print JS_TREE_FILE $indent . " \"children\": [\n";
+}
+
+sub print_package_finish_children
+{
+  my $level  = shift;
+  my $indent = "";
+
+  $level *= 2;
+  while( $level ) { $indent .= " "; $level--; }
+  print JS_TREE_FILE $indent . " ]\n";
+}
+
+sub print_package_tail
+{
+  my $level  = shift;
+  my $indent = "";
+
+  $level *= 2;
+  while( $level ) { $indent .= " "; $level--; }
+  print JS_TREE_FILE $indent . "}";
+}
+
+sub print_comma
+{
+  my $comma = shift;
+
+  if( $comma > 0 ) { print JS_TREE_FILE ",\n"; }
+  else             { print JS_TREE_FILE  "\n"; }
+}
+
+
+#
+# Parse the command line options
+#
+
+# Get the rest arguments of the command line
+$topdir    = shift;
+$toolchain = shift;
+$hardware  = shift;
+$flavour   = shift;
+
+my $makefile = "Makefile";
+
+if( ! defined $topdir    or $topdir eq "" )    { usage; }
+if( ! defined $toolchain or $toolchain eq "" ) { usage; }
+if( ! defined $hardware  or $hardware eq "" )  { usage; }
+if( ! defined $flavour   or $flavour eq "" )   { $flavour = ""; }
+
+_kxLab::error( "$0: $topdir is not a directory" ) if( ! -d $topdir );
+_kxLab::error( "$0: Makefile missing: $makefile" ) if ( ! -f $makefile );
+
+$build_system = $topdir . "/build-system";
+
+$distro_name    = distro_name( $build_system );
+$distro_version = distro_version( $build_system );
+$url            = bug_url( $build_system );
+
+
+if( $flavour eq "" )
+{
+  $target_build_dir  = "." . $toolchain . "/" . $hardware;
+}
+else
+{
+  $target_build_dir  = "." . $toolchain . "/" . $hardware . "/" . $flavour;
+}
+
+$requires_file  = $target_build_dir . "/.requires";
+
+if( $flavour eq "" )
+{
+  $html_tree_file = $target_build_dir . "/" . $hardware . ".html";
+  $js_tree_file   = $target_build_dir . "/" . $hardware . ".json";
+}
+else
+{
+  $html_tree_file = $target_build_dir . "/" . $hardware . "-" . $flavour . ".html";
+  $js_tree_file   = $target_build_dir . "/" . $hardware . "-" . $flavour . ".json";
+}
+
+my $jsmin = $ENV{JSMIN};
+if( $jsmin ne "" )
+{
+  $js_min_tree_file = $js_tree_file;
+  $js_min_tree_file =~ s/\.json$/\.min\.json/;
+}
+
+# open the intput file
+open(REQUIRES_FILE, "< $requires_file") or
+  _kxLab::error( "$0: Could not open $requires_file file: $!" );
+# open the output files
+open(JS_TREE_FILE, "> $js_tree_file") or
+  _kxLab::error( "$0: Could not open $js_tree_file file: $!" );
+
+
+my $depth    = 2;
+my $level    = 0;
+my $root     = get_root();
+my @treedirs = get_treedirs();
+my %deps     = get_deps();
+
+sub print_tree
+{
+  my ($level, $last, $pkg) = @_;
+
+  if( $depth < $level ) { $depth = $level; }
+
+  print_package_head( $level, \%{$pkg} );
+  $root_node = 0;
+
+  if( $pkg->{'children'} )
+  {
+    print_comma( 1 );
+    print_package_start_children( $level );
+
+    my @a = @{$pkg->{'children'}};
+    my $n = $#a;
+
+    foreach my $p ( @{$pkg->{'children'}} )
+    {
+      print_tree( $level + 1, $n--, \%{$p} );
+    }
+
+    print_package_finish_children( $level );
+  }
+  else
+  {
+    print_comma( 0 );
+  }
+  print_package_tail( $level );
+  print_comma( $last );
+}
+
+
+#
+# This is the root package
+#
+%tree = fill_package_info( $root, $makefile, $flavour );
+
+
+my %sequence;
+my $order = 0;
+
+#################################################################
+# if( there is any dependencies )
+#
+if( %deps )
+{
+  my @dep_keys = keys %deps;
+
+  my $count = scalar( keys %deps );
+
+  foreach my $dir ( @treedirs )
+  {
+    if( ! grep { $_ eq $dir } @dep_keys )
+    {
+      my $key = $dir;
+      $sequence{$key} = ++$order;
+      @treedirs = grep { $_ ne $key } @treedirs;
+
+      # Split dir^flavour:
+      my ($d, $f);
+      $d = `echo $dir | cut -f 1 -d '^'`;
+      $d =~ s/^\s+|\s+$//;
+      if( $dir =~ m/\^/ )
+      {
+        $f = `echo $dir | cut -f 2 -d '^'`;
+        $f =~ s/^\s+|\s+$//;
+      }
+      else
+      {
+        $f = "";
+      }
+
+      # Insert into sub_trees:
+      my %pkg = fill_package_info( $d, $topdir . "/" . $d . "/Makefile", $f );
+      $sub_trees{$dir} = \%pkg;
+
+      delete $deps{$dir};
+    }
+  }
+
+
+  for( my $i = 0; $i < $count; ++$i )
+  {
+    my @installed = keys %sequence;
+
+    foreach my $key (sort keys %deps)
+    {
+      my $ok = 1;
+      my @dirs = split( ' ', $deps{$key} );
+
+      if( $key ne "all" )
+      {
+        foreach my $dir ( @dirs )
+        {
+          if( ! grep { $_ eq $dir } @installed )
+          {
+            $ok = 0;
+          }
+        }
+
+        if( $ok == 1 )
+        {
+          $sequence{$key} = ++$order;
+
+          # Split dir^flavour:
+          my ($d, $f);
+          $d = `echo $key | cut -f 1 -d '^'`;
+          $d =~ s/^\s+|\s+$//;
+          if( $key =~ m/\^/ )
+          {
+            $f = `echo $key | cut -f 2 -d '^'`;
+            $f =~ s/^\s+|\s+$//;
+          }
+          else
+          {
+            $f = "";
+          }
+
+          # create package node:
+          my %pkg = fill_package_info( $d, $topdir . "/" . $d . "/Makefile", $f );
+          # add children:
+          foreach my $dir ( @dirs )
+          {
+            my $child = $sub_trees{$dir};
+            push( @{$pkg{'children'}}, $child );
+          }
+
+          # insert new sub tree into $sub_tree:
+          $sub_trees{$key} = \%pkg;
+
+          delete $deps{$key};
+        }
+      }
+    }
+  }
+
+  #
+  # The root node children
+  #
+  my @dirs = split( ' ', $deps{'all'} );
+  foreach my $dir ( @dirs )
+  {
+    my $child = $sub_trees{$dir};
+    push( @{$tree{'children'}}, $child );
+  }
+
+}
+else
+{
+  my %pkg;
+
+  $pkg{'dir'}  = "void";
+  $pkg{'name'} = "void";
+
+  push( @{$tree{'children'}}, \%pkg );
+}
+#
+# End if( there is any dependencies )
+#################################################################
+
+
+
+print_tree( $level, 0, \%tree );
+
+
+
+#################################################################
+# Calculate SVG size and make HTML from template:
+#
+my $copyright_url = $url;
+my $html_template = $build_system . "/html/requires_tree_html.template";
+my $w = $depth;
+my $h = get_ntreedirs();
+my ($width, $height);
+
+$width  = ($w + 4) * 160;
+$height = ($h + 4) * 24;
+
+$root =~ s/\//\\\//g;
+$root =~ s/\-/\\\-/g;
+$root =~ s/\+/\\\+/g;
+$root =~ s/\./\\\./g;
+
+$copyright_url =~ s/\//\\\//g;
+$copyright_url =~ s/\-/\\\-/g;
+$copyright_url =~ s/\+/\\\+/g;
+$copyright_url =~ s/\./\\\./g;
+
+
+
+my $js_data_file = basename( $js_tree_file );
+
+if( $jsmin ne "" )
+{
+  # minimize JSON data file:
+  _kxLab::system( "$jsmin -o $js_min_tree_file $js_tree_file" );
+  $js_data_file = basename( $js_min_tree_file );
+}
+
+my $call_string = sprintf( "cat %s | "                          .
+                           "sed 's/\@HARDWARE\@/%s/g' | "       .
+                           "sed 's/\@ROOT\@/%s/g' | "           .
+                           "sed 's/\@TARBALL_SUFFIX\@/%s/g' | " .
+                           "sed 's/\@BUG_URL\@/%s/g' | "        .
+                           "sed 's/\@SVG_WIDTH\@/%d/g' | "      .
+                           "sed 's/\@SVG_HEIGHT\@/%d/g' | "     .
+                           "sed 's/\@JSON_DATA_FILE\@/%s/g' > " . $html_tree_file,
+                           $html_template,
+                           $hardware,
+                           $root,
+                           $tarball_suffix,
+                           $copyright_url,
+                           $width, $height,
+                           $js_data_file );
+_kxLab::system( $call_string );
+
+#
+# End of creating HTML file
+#################################################################
+
+
+#################################################################
+# Count the number of packages [see: build_packages_list script]:
+#
+sub compare_order
+{
+  $sequence{$a} <=> $sequence{$b};
+}
+
+my $packages_done = 0;
+
+sub print_result
+{
+  my $out_string = sprintf( "####### Required Packages Tree (done: %4d packages)\n", $packages_done );
+
+  print $out_string;
+}
+
+print "#######\n";
+
+foreach my $dir (sort compare_order( (keys %sequence) ))
+{
+  my $package;
+
+  if( $dir ne "all" )
+  {
+    $package = $sub_trees{$dir};
+
+    if( $package->{'install'} ne "no" )
+    {
+      ++$packages_done;
+    }
+  }
+}
+
+if( $tree{'install'} ne "no" )
+{
+  ++$packages_done;
+}
+
+print_result();
+print "#######\n";
+#
+# End of Counting the number of packages.
+#################################################################
+
+# close input files
+close REQUIRES_FILE;
+# close output files
+close JS_TREE_FILE;

Property changes on: build-system-1.2.3/build_requires_tree
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/configure-targets
===================================================================
--- build-system-1.2.3/configure-targets	(nonexistent)
+++ build-system-1.2.3/configure-targets	(revision 231)
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+CWD=`pwd`
+
+BUILDSYSTEM=${BUILDSYSTEM:-$CWD}
+
+CONFIG=${CONFIG:-build-config.mk}
+CONSTANTS=${CONSTANTS:-constants.mk}
+
+if [ ! -r $CONFIG ] ; then
+  echo "$0: ERROR: There is no $CONFIG file for configuring target HW."
+  echo ""
+  exit 1
+fi
+
+: ${DIALOG=$BUILDSYSTEM/sbin/dialog}
+: ${DIALOGRC=$BUILDSYSTEM/pkgtool/dialogrc}
+
+export DIALOGRC
+
+: ${DIALOG_OK=0}
+: ${DIALOG_CANCEL=1}
+: ${DIALOG_HELP=2}
+: ${DIALOG_EXTRA=3}
+: ${DIALOG_ITEM_HELP=4}
+: ${DIALOG_ESC=255}
+
+umask 002
+if [ ! -z "$TMPDIR" ] ; then mkdir -p $TMPDIR ; fi
+TMP=$(mkdir -p /tmp/radix && mktemp -d -p /tmp/radix build-system.XXXXXXXX) || { echo "Cannot create '/tmp/...' directory" ; exit 92; }
+trap "rm -rf $TMP" EXIT
+
+
+cat > $TMP/sel$$ << EOF
+--colors \\
+--backtitle "\Z7Build System\Zn" \\
+--title " \Z1SELECTING HARDWARE TO BUILD\Zn " \\
+--clear \\
+--checklist "\\n\\
+Please confirm the hardwares, for which you wish to build\\n\\
+software. Use the UP/DOWN keys to scroll through the list,\\n\\
+and the SPACE key to deselect any items you don't want to\\n\\
+build.\\n\\n\\
+Press ENTER when you are done." \\
+21 68 8 \\
+EOF
+
+
+hwlist=`cat $CONFIG | grep "^ENABLE_.*[ \t]*=.*" | sed "s,^ENABLE_\(.*\)[ \t]*=.*,\1," | tr 'A-Z' 'a-z'`
+
+for hw in $hwlist ; do
+  hh=`echo $hw | tr 'a-z' 'A-Z'`
+  spec=`cat $CONSTANTS | grep "^${hh}_SPEC[ \t]*=.*" | sed "s,^${hh}_SPEC[ \t]*=[ \t]*\(.*\),\1," | sed "s,\\\\\,,g"`
+  enabled=`cat $CONFIG | grep "^ENABLE_${hh}[ \t]*=.*" | sed "s,^ENABLE_${hh}[ \t]*=[ \t]*\(.*\),\1,"`
+  if [ "$enabled" == "true" ] ; then
+    en="on"
+  else
+    en="off"
+  fi
+  echo "\"$hw\" \"$spec\" $en \\" >> $TMP/sel$$
+done
+
+
+$DIALOG --file $TMP/sel$$  2> $TMP/ret$$
+
+retval=$?
+
+case $retval in
+  $DIALOG_OK)
+    enabled="`cat $TMP/ret$$`"
+    for hw in $hwlist ; do
+      hh=`echo $hw | tr 'a-z' 'A-Z'`
+      sed -i "s,^\(ENABLE_${hh}[ \t]*=[ \t]*\).*,\1false," $CONFIG
+    done
+    for hw in $enabled ; do
+      hh=`echo $hw | tr 'a-z' 'A-Z'`
+      sed -i "s,^\(ENABLE_${hh}[ \t]*=[ \t]*\).*,\1true," $CONFIG
+    done
+    ;;
+esac

Property changes on: build-system-1.2.3/configure-targets
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/core.mk
===================================================================
--- build-system-1.2.3/core.mk	(nonexistent)
+++ build-system-1.2.3/core.mk	(revision 231)
@@ -0,0 +1,1913 @@
+
+# include once
+ifndef CORE_MK
+
+#######
+####### helpful variables
+#######
+
+comma := ,
+empty :=
+space := $(empty) $(empty)
+
+
+#######
+####### Set up TOP_BUILD_DIR, TOP_BUILD_DIR_ABS and BUILDSYSTEM variables
+#######
+
+ifndef MAKEFILE_LIST
+
+# Work-around for GNU make pre-3.80, which lacks MAKEFILE_LIST and $(eval ...)
+
+TOP_BUILD_DIR := $(shell perl -e 'for ($$_ = "$(CURDIR)"; ! -d "$$_/build-system"; s!(.*)/(.*)!\1!) { $$q .= "../"; } chop $$q; print "$$q"')
+ifeq ($(TOP_BUILD_DIR),)
+TOP_BUILD_DIR=.
+endif
+export TOP_BUILD_DIR_ABS := $(shell perl -e 'for ($$_ = "$(CURDIR)"; ! -d "$$_/build-system"; s!(.*)/(.*)!\1!) { } print')
+export BUILDSYSTEM := $(TOP_BUILD_DIR_ABS)/build-system
+
+else
+
+# Normal operation for GNU make 3.80 and above
+
+__pop = $(patsubst %/,%,$(dir $(1)))
+__tmp := $(call __pop,$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
+# Special case for build-system/Makefile
+ifeq ($(__tmp),.)
+__tmp := ../$(notdir $(CURDIR))
+endif
+
+ifndef TOP_BUILD_DIR
+TOP_BUILD_DIR := $(call __pop,$(__tmp))
+endif
+
+ifndef TOP_BUILD_DIR_ABS
+TOP_BUILD_DIR_ABS := $(CURDIR)
+ifneq ($(TOP_BUILD_DIR),.)
+$(foreach ,$(subst /, ,$(TOP_BUILD_DIR)),$(eval TOP_BUILD_DIR_ABS := $(call __pop,$(TOP_BUILD_DIR_ABS))))
+endif
+export TOP_BUILD_DIR_ABS
+endif
+
+ifndef BUILDSYSTEM
+export BUILDSYSTEM := $(TOP_BUILD_DIR_ABS)/$(notdir $(__tmp))
+endif
+
+endif
+
+
+
+
+#######
+####### Config:
+#######
+
+include $(BUILDSYSTEM)/constants.mk
+
+#
+# All available hardware:
+#
+HARDWARE_ALL = $(strip $(foreach hw, $(filter HARDWARE_%,       \
+                                 $(filter-out HARDWARE_ALL      \
+                                              HARDWARE_NAMES,   \
+                                              $(.VARIABLES))), $($(hw))))
+
+HARDWARE_NAMES = $(filter-out $(HARDWARE_NOARCH), $(HARDWARE_ALL))
+
+#
+# All available toolchains:
+#
+TOOLCHAIN_ALL = $(strip $(foreach t, $(filter TOOLCHAIN_%,       \
+                                 $(filter-out TOOLCHAIN_ALL      \
+                                              TOOLCHAIN_NAMES    \
+                                              TOOLCHAIN_DIR      \
+                                              TOOLCHAIN_PATH     \
+                                              TOOLCHAIN_VERSION, \
+                                              $(.VARIABLES))), $($(t))))
+
+TOOLCHAIN_NAMES = $(TOOLCHAIN_ALL)
+
+COMPONENT_TOOLCHAINS = $(TOOLCHAIN_ALL)
+
+
+
+
+#######
+####### Config:
+#######
+
+ifneq ($(wildcard $(BUILDSYSTEM)/build-config.mk),)
+include $(BUILDSYSTEM)/build-config.mk
+else
+include $(BUILDSYSTEM)/build-config.mk.template
+endif
+
+# Reading build-config.mk:
+
+# ENABLE_NOARCH & ENABLE_BUILD always enabled:
+ENABLE_NOARCH = true
+ENABLE_BUILD  = true
+
+enabled = $(filter ENABLE_%, $(filter-out ENABLE_ARCH ENABLE_TARGETS, $(.VARIABLES)))
+
+hardware_filter = $(strip $(foreach t, \
+                     $(strip $(foreach b, \
+                       $(enabled), $(if $(filter true, $($(b))), \
+                         $(subst ENABLE_, HARDWARE_, $(b))))), $($(t))))
+
+# If no HARDWARE set
+ifeq ($(HARDWARE),)
+
+# COMPONENT_TARGETS must have a value specified in the Makefile
+ifeq ($(COMPONENT_TARGETS),)
+$(error Error: COMPONENT_TARGETS must have a value)
+endif
+
+# End if no HARDWARE set
+endif
+
+
+
+#######
+####### Filter out disabled targets
+#######
+
+COMPONENT_TARGETS := $(filter $(hardware_filter), $(COMPONENT_TARGETS))
+
+# Remove duplicates:
+COMPONENT_TARGETS := $(sort $(COMPONENT_TARGETS))
+
+
+#######
+####### Filter out disabled toolchains:
+#######
+
+COMPONENT_TOOLCHAINS := $(strip \
+                          $(foreach toolchain, $(COMPONENT_TOOLCHAINS), \
+                            $(if $(filter $($(shell echo $(toolchain) | tr '[a-z-]' '[A-Z_]')_HARDWARE_VARIANTS), \
+                                          $(COMPONENT_TARGETS)),$(toolchain),)))
+
+COMPONENT_TOOLCHAINS := $(sort $(COMPONENT_TOOLCHAINS))
+
+
+
+# Error if TOOLCHAIN is invalid
+ifneq ($(TOOLCHAIN),)
+ifeq ($(filter $(TOOLCHAIN), $(COMPONENT_TOOLCHAINS)),)
+$(error Error: TOOLCHAIN=$(TOOLCHAIN) is invalid for selected COMPONENT_TARGETS in Makefile)
+endif
+endif
+
+# Error if HARDWARE is invalid
+ifneq ($(HARDWARE),)
+ifeq ($(filter $(HARDWARE), $(COMPONENT_TARGETS)),)
+$(error Error: HARDWARE=$(HARDWARE) is invalid for selected COMPONENT_TARGETS in Makefile)
+endif
+endif
+
+
+################################################################
+#######
+####### Directories setup Section:
+#######
+
+#
+# Set up SOURCE PACKAGE directory:
+#
+export SRC_PACKAGE_DIR       := sources
+export SRC_PACKAGE_PATH      := $(TOP_BUILD_DIR)/$(SRC_PACKAGE_DIR)
+export SRC_PACKAGE_PATH_ABS  := $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR)
+
+
+#
+# Set up DESTINATION directories:
+#
+DEST_DIR_ABS           = $(TOP_BUILD_DIR_ABS)/dist
+
+ifeq ($(NEED_ABS_PATH),)
+DEST_DIR               = $(TOP_BUILD_DIR)/dist
+else
+DEST_DIR               = $(DEST_DIR_ABS)
+endif
+
+
+#
+# Default PREFIX: is $(TOP_BUILD_DIR)/dist
+#
+PREFIX ?= $(DEST_DIR)
+
+
+#
+# Install DIRs (for SCRIPT_, BIN_, ... TARGETS) [should be always ABS]:
+#
+TARGET_DEST_DIR   = $(DEST_DIR_ABS)/$(addprefix ., $(TOOLCHAIN))/$(HARDWARE)
+PRODUCTS_DEST_DIR = $(DEST_DIR_ABS)/products/$(TOOLCHAIN)/$(HARDWARE)
+ROOTFS_DEST_DIR   = $(DEST_DIR_ABS)/rootfs/$(TOOLCHAIN)/$(HARDWARE)
+
+#######
+####### End of Directories setup Section.
+#######
+################################################################
+
+
+
+################################################################
+#######
+####### Targets setup Section:
+#######
+
+ifdef TARGET_SETUP_MK
+$(error Error: 'target-setup.mk' should not be included directly, include 'constants.mk' instead.)
+endif
+
+include $(BUILDSYSTEM)/target-setup.mk
+
+#######
+####### End of Targets setup Section.
+#######
+################################################################
+
+
+
+
+
+
+
+
+################################################################
+# Get toolchain by HARDWARE function:
+#
+# toolchain()
+#
+toolchain = $($(strip                                                          \
+                $(foreach v, $(filter %_HARDWARE_VARIANTS, $(.VARIABLES)),     \
+                  $(if $(filter $1, $($(v))),                                  \
+                    $(addprefix TOOLCHAIN_,$(subst _HARDWARE_VARIANTS,,$(v))), \
+                   ))))
+
+# usage:
+#   pc32_toolchain = $(call toolchain,$(HARDWARE_PC32))
+#
+# Get toolchain by HARDWARE function.
+################################################################
+
+
+################################################################
+# Check the list of available targets for current Makefile
+#
+__available_targets =                                                                      \
+  $(foreach arch, $(shell echo $(COMPONENT_TOOLCHAINS) | sed -e 's/x86_64/x86-64/g'),      \
+    $(foreach hardware, $($(shell echo ${arch} | tr '[a-z-]' '[A-Z_]')_HARDWARE_VARIANTS), \
+      $(if $(filter $(hardware),$(COMPONENT_TARGETS)),                                     \
+        $(if $($(shell echo $(hardware) | tr '[a-z]' '[A-Z]')_FLAVOURS),                   \
+          $(foreach flavour, $($(shell echo $(hardware) | tr '[a-z]' '[A-Z]')_FLAVOURS),   \
+            .target_$(arch)_$(hardware)_$(flavour)                                         \
+           ) .target_$(arch)_$(hardware),                                                  \
+          $(if $(FLAVOURS),                                                                \
+            $(foreach flavour, $(FLAVOURS),                                                \
+              .target_$(arch)_$(hardware)_$(flavour)                                       \
+             ) .target_$(arch)_$(hardware),                                                \
+            .target_$(arch)_$(hardware)                                                    \
+           )                                                                               \
+         ),                                                                                \
+       )                                                                                   \
+     )                                                                                     \
+   )
+
+__available_targets := $(strip $(__available_targets))
+__available_targets := $(sort $(__available_targets))
+#
+#
+################################################################
+
+
+
+#######
+####### Silent make:
+#######
+
+#ifeq ($(VERBOSE),)
+#ifeq ($(COMPONENT_IS_3PP),)
+#MAKEFLAGS += -s
+#endif
+#endif
+#
+#ifeq ($(VERBOSE),)
+#guiet = @
+#else
+#quiet =
+#endif
+
+
+#######
+####### Number of CPU cores:
+#######
+
+NUMPROCS := 1
+OS       := $(shell uname -s)
+
+ifeq ($(OS),Linux)
+NUMPROCS := $(shell grep -c ^processor /proc/cpuinfo)
+endif
+
+
+#######
+####### Parallel control:
+#######
+
+ifneq ($(NOT_PARALLEL),)
+MAKEFLAGS += -j1
+.NOTPARALLEL:
+endif
+
+
+
+#######
+####### Global Cleanup List may be start here with += assign symbol:
+#######
+#######   CLEANUP_FILES += ...
+#######
+####### IMPORTANT NOTE:
+####### ==============
+#######    Do not add directories such as .$(TOOLCHAIN), $(TARGET_BUILD_DIR), $(HARDWARE), etc.
+#######
+
+
+
+all: BUILD_TREE := true
+export BUILD_TREE
+
+all:
+	@$(MAKE) local_all
+
+
+clean: CLEAN_TREE := true
+export CLEAN_TREE
+
+clean:
+	@$(MAKE) local_clean
+
+
+dist_clean: DIST_CLEAN_TREE := true
+export DIST_CLEAN_TREE
+
+dist_clean:
+	@$(MAKE) local_dist_clean
+
+
+rootfs_clean: ROOTFS_CLEAN_TREE := true
+export ROOTFS_CLEAN_TREE
+
+rootfs_clean:
+	@$(MAKE) local_rootfs_clean
+
+
+
+
+# MAKE goals which not depended from Makefile
+__quick_targets := help ccache_stats configure_targets local_clean global_clean downloads_clean build-config.mk $(HACK_TARGETS)
+
+
+
+
+################################################################
+#######
+####### Build preparations & HW Independed GOALs Section:
+#######
+
+#
+# GLOBAL setup targets:
+# ====================
+#   These targets are built before all targets. For example, source tarballs
+#   have to be downloaded before starting the build.
+#
+#   NOTE:
+#     BUILDSYSTEM is a setup target for other directories and the BUILDSYSTEM
+#     requires only '.sources' target as a setup target.
+#
+ifeq ($(filter %_clean,$(MAKECMDGOALS)),)
+ifeq ($(shell pwd),$(BUILDSYSTEM))
+__setup_targets = .sources
+else
+__setup_targets = .sources .build_system
+endif
+endif
+
+
+.setup:
+ifeq ($(__final__),)
+.setup: $(__setup_targets)
+else
+.setup: .makefile
+endif
+
+
+#######
+####### If Makefile has been changed we cannot warranty that this is afected only
+####### one  HW  target from the list of targets prepared by this local Makefile.
+#######
+####### So, in this case we have to clean up all built targets.
+#######
+
+# Check if Makefile has been changed:
+.makefile: Makefile
+ifneq ($(shell pwd),$(TOP_BUILD_DIR_ABS))
+ifneq ($(if $(MAKECMDGOALS),$(filter-out $(__quick_targets),$(MAKECMDGOALS)),true),)
+	@touch $@
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+	@echo ""
+	@echo -e "#######"
+	@echo -e "####### New makefile ($(<F)), clean up & rebuild source requires!"
+	@echo -e "#######"
+	@echo ""
+	@$(MAKE) local_dist_clean
+	@if $(MAKE) local_clean; then true; else rm -f $@; fi
+else
+	@if $(MAKE) download_clean; then true; else rm -f $@; fi
+endif
+endif
+endif
+
+
+
+#######
+####### Build directory dependencies into .src_requires  which
+####### is used as a Makefile for srource tarballs downloading
+#######
+
+#######
+####### NOTE:
+####### ====
+#######  Source tarballs are downloaded once for whole dependencies tree
+#######  of the current directory where we make the build using command
+#######  such as 'make' or 'make local_all'.
+#######  Target local_all is not affects the downloading sources for the
+#######  whole dependencies tree (target local_all affects the building
+#######  of packages only).
+#######  In this case the $(__final__) variable is not defined.
+#######  On the contrary when the BUILDSYSTEM builds each packages of
+#######  dependencies tree the $(__final__) variable is defined and
+#######  we don't try to download sources because they already downloaded.
+#######  More over we don't need to have the '.src_requires' and
+#######  '.src_requires_depend' files.
+#######
+#######  Such behavior is invented aspecialy to avoid competition in case
+#######  when during parallel build different processes can run the same
+#######  Makefile and all of them can start the sources preparation.
+#######
+
+.sources: .src_requires
+
+.src_requires_depend: .src_requires ;
+
+.src_requires: .makefile
+ifneq ($(shell pwd),$(TOP_BUILD_DIR_ABS))
+ifeq ($(filter %_clean,$(MAKECMDGOALS)),)
+ifeq ($(__final__),)
+	@echo ""
+	@echo -e "################################################################"
+	@echo -e "#######"
+	@echo -e "####### Start of building source requires for '$(subst $(TOP_BUILD_DIR_ABS)/,,$(CURDIR))':"
+	@echo -e "#######"
+	@$(BUILDSYSTEM)/build_src_requires $(TOP_BUILD_DIR_ABS)
+	@__final__= TREE_RULE=local_all $(MAKE) TOOLCHAIN=$(TOOLCHAIN_NOARCH) HARDWARE=$(HARDWARE_NOARCH) FLAVOUR= -f .src_requires
+	@echo -e "#######"
+	@echo -e "####### End of building source requires for '$(subst $(TOP_BUILD_DIR_ABS)/,,$(CURDIR))'."
+	@echo -e "#######"
+	@echo -e "################################################################"
+	@echo ""
+	@touch $@
+	@touch .src_requires_depend
+endif
+endif
+endif
+
+
+
+.build_system: .src_requires
+ifneq ($(shell pwd),$(TOP_BUILD_DIR_ABS))
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+ifeq ($(shell pwd | grep $(BUILDSYSTEM)),)
+	@echo -e "################################################################"
+	@echo -e "#######"
+	@echo -e "####### Start to Check the BUILDSYSTEM is ready:"
+	@echo -e "#######"
+	@( cd $(BUILDSYSTEM) ; __final__= $(MAKE) TOOLCHAIN=$(TOOLCHAIN_BUILD_MACHINE) HARDWARE=$(HARDWARE_BUILD) FLAVOUR= all )
+	@echo -e "#######"
+	@echo -e "####### End of checking the BUILDSYSTEM."
+	@echo -e "#######"
+	@echo -e "################################################################"
+endif
+endif
+endif
+
+
+
+#######
+####### Clean the whole source tree
+#######
+
+global_clean: .global_clean
+
+.global_clean:
+	@echo ""
+	@echo -e "#######"
+	@echo -e "####### Cleaning the whole sources tree excluding downloaded sources..."
+	@echo -e "#######"
+	@$(BUILDSYSTEM)/global_clean $(addprefix ., $(TOOLCHAIN_NAMES)) $(TOP_BUILD_DIR_ABS)
+
+
+#######
+####### Clean all downloaded source tarballs
+#######
+
+downloads_clean: .downloads_clean
+
+.downloads_clean:
+	@echo ""
+	@echo -e "#######"
+	@echo -e "####### Cleaning Up all downloaded sources..."
+	@echo -e "#######"
+	@$(BUILDSYSTEM)/downloads_clean $(addprefix ., $(TOOLCHAIN_NOARCH)) $(BUILDSYSTEM)/3pp/sources
+ifneq ($(wildcard $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR)),)
+	@$(BUILDSYSTEM)/downloads_clean $(addprefix ., $(TOOLCHAIN_NOARCH)) $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR)
+endif
+
+
+help:
+	@echo ""
+	@echo -e "Build System $(SYSTEM_VERSION)"
+	@echo ""
+	@echo -e "You can build and install software using command line such as follow:"
+	@echo ""
+	@echo -e "   $$ [TOOLCHAIN=toolchain] [HARDWARE=hardware] [FLAVOUR=flavour] make [goal]"
+	@echo ""
+	@echo -e "The following MAKE goals are available:"
+	@echo ""
+	@echo -e "   all                - perform make build and install software in the all"
+	@echo -e "                        required directories which defined by REQUIRES"
+	@echo -e "                        variable in the local Makefile;"
+	@echo -e "   local_all          - build and install software prepared onlu by local"
+	@echo -e "                        Makefile;"
+	@echo -e "   dist_clean,"
+	@echo -e "   local_dist_clean   - remove distribution packages from target directory"
+	@echo -e "                        defined by PRODUCTS_DEST_DIR variable. Note that"
+	@echo -e "                        is depends from targets defined by COMPONENT_TARGETS"
+	@echo -e "                        variable or command line;"
+	@echo -e "   rootfs_clean,"
+	@echo -e "   local_rootfs_clean - uninstall packages installed into target 'root file"
+	@echo -e "                        system' directory which defined by ROOTFS_DEST_DIR"
+	@echo -e "                        variable;"
+	@echo -e "   clean,"
+	@echo -e "   local_clean        - clean up all built targets by this Makefile;"
+	@echo ""
+	@echo -e "   If the one from above goals has prefix 'local_' then this goal affects only"
+	@echo -e "   current directory.  Otherwise this goal will be performed for all required"
+	@echo -e "   directories which defined by REQUIRES variable."
+	@echo ""
+	@echo -e "   configure_targets  - select hardwares, for which the software will be built."
+	@echo -e "                        This command edits the build-config.mk file;"
+	@echo ""
+	@echo -e "   requires_tree      - create HTML file to show the requires tree for current"
+	@echo -e "                        directory. Note that this goal depends on goal all;"
+	@echo -e "   packages_list      - create HW.pkglist file which contains the list of packages"
+	@echo -e "                        in install order. Note that this goal depends on goal all;"
+	@echo -e "   devices_table      - create Devices Table for rootfs image creation procedure;"
+	@echo -e "   ext4fs_image       - create Ext4 Root FS for target Boot Image;"
+	@echo -e "   products_release   - install files into products directory for release;"
+	@echo ""
+	@echo -e "   global_clean       - clean up whole sourses tree excluding downloaded"
+	@echo -e "                        source tarballs;"
+	@echo -e "   downloads_clean    - remove all sourse tarball from 'sourses' directory;"
+	@echo ""
+	@echo -e "   ccache_stats       - show the ccache statistic."
+	@echo ""
+	@echo -e "Local Makefile is prepared for following target HW platforms:"
+	@echo ""
+	@for platform in $(COMPONENT_TARGETS) ; do \
+	  echo -e "   $$platform"; \
+	 done
+	@echo ""
+	@echo -e "Enjoy."
+	@echo ""
+
+ccache_stats:
+ifeq ($(NO_CCACHE),)
+	@echo ""
+	@echo -e "CCACHE statistic:"
+	@echo ""
+	@CCACHE_DIR=$(CACHED_CC_OUTPUT) $(CCACHE) -s
+	@echo ""
+	@echo -e "To set max cache size make use the following command"
+	@echo ""
+	@echo -e "   $$ CCACHE_DIR=$(CACHED_CC_OUTPUT) $(CCACHE)-M 64G"
+	@echo ""
+	@echo -e "see CCACHE(1) for more information."
+	@echo ""
+else
+	@echo ""
+	@echo -e "CCACHE disabled by setting 'NO_CCACHE=$(NO_CCACHE)' variable for this Makefile."
+	@echo ""
+endif
+
+configure_targets: $(BUILDSYSTEM)/build-config.mk
+	@BUILDSYSTEM=$(BUILDSYSTEM)            \
+	 CONFIG=$(BUILDSYSTEM)/build-config.mk \
+	 CONSTANTS=$(BUILDSYSTEM)/constants.mk \
+	 $(BUILDSYSTEM)/configure-targets
+
+#######
+####### End of Build preparations & HW Independed GOALs Section.
+#######
+################################################################
+
+
+################################################################
+#######
+####### Source archive and patch handling:
+#######
+
+# Patch dependency:
+PATCHES_DEP = $(foreach patch,$(PATCHES),\
+	$(shell $(BUILDSYSTEM)/apply_patches $(patch) -dep-))
+
+SRC_DIR_BASE = $(dir $(SRC_DIR))
+
+# Unpack SRC_ARCHIVE in SRC_DIR and backup old SRC_DIR:
+UNPACK_SRC_ARCHIVE = \
+	@echo "Expanding $(SRC_ARCHIVE)"; \
+	if [ -d $(SRC_DIR) ]; then mv $(SRC_DIR) $$(mktemp -d $(SRC_DIR).bak.XXXXXX); fi; \
+	mkdir -p $(SRC_DIR_BASE); \
+	$(if $(findstring .rpm,$(SRC_ARCHIVE)), \
+	  cd $(SRC_DIR_BASE) && rpm2cpio $(SRC_ARCHIVE) | cpio -id --quiet, \
+	  $(if $(findstring .zip,$(SRC_ARCHIVE)), \
+	    unzip -q -d $(SRC_DIR_BASE) $(SRC_ARCHIVE), \
+	    tar $(if $(findstring .bz2,$(SRC_ARCHIVE)),-xjf, \
+	             $(if $(findstring .xz,$(SRC_ARCHIVE)),-xJf, \
+	             $(if $(findstring .txz,$(SRC_ARCHIVE)),-xJf,-xzf))) \
+	        $(SRC_ARCHIVE) -C $(SRC_DIR_BASE))); \
+	chmod -R u+w $(SRC_DIR)
+
+# Apply patches in PATCHES on SRC_DIR_BASE:
+APPLY_PATCHES = $(quiet)$(foreach patch,$(PATCHES),\
+	$(BUILDSYSTEM)/apply_patches $(patch) $(SRC_DIR_BASE) &&) true
+
+# Apply patches in PATCHES on BASE of directory defined as argument:
+apply-patches = $(quiet)$(foreach patch,$(PATCHES),\
+	$(BUILDSYSTEM)/apply_patches $(patch) $(dir $1) &&) true
+
+# Apply patches in OPT_PATCHES on SRC_DIR_BASE:
+APPLY_OPT_PATCHES = $(quiet)$(foreach patch,$(OPT_PATCHES),\
+	$(BUILDSYSTEM)/apply_patches $(patch) $(SRC_DIR_BASE) &&) true
+
+# Apply patches in OPT_PATCHES on BASE of directory defined as argument:
+apply-opt-patches = $(quiet)$(foreach patch,$(OPT_PATCHES),\
+	$(BUILDSYSTEM)/apply_patches $(patch) $(dir $1) &&) true
+
+
+################################################################
+# Functions:
+# =========
+#
+# Install package content into the current development environment:
+# ----------------------------------------------------------------
+#
+# NOTE:
+#     - When we pass ARGS through STDIN [using '--' as end of options] we splits ARGS
+#       by new-line '\n' symbol.
+#     - When we pass ARGS in the command line, we have to add  | tr '\n' ' ' | filter
+#       to change new-line with space.
+#
+install-into-devenv = \
+	@( cd $1 ; \
+	   find . \( -type d -empty -o -type f -o -type l \) -printf '%P\n' | sed -e 's, ,\\040,g' | \
+	   DO_CREATE_DIST_FILES=1 CWD=$(CURDIR) \
+	   $(BUILDSYSTEM)/install_targets       \
+	     --preserve-source-dir=true         \
+	     --destination=$(TARGET_DEST_DIR)   \
+	     --toolchain=$(TOOLCHAIN)           \
+	     --hardware=$(HARDWARE)             \
+	     --flavour=$(FLAVOUR)               \
+	     --                                 \
+	 )
+# usage:
+#   $(call install-into-devenv,$(PKGDIR))
+#   where PKGDIR - is a directory where package installed from sources.
+# ----------------------------------------------------------------
+#
+# Pull and Push variables into Perl Storable Hash saved in the
+# $(BUILDSYSTEM)/var/tmp directory. These functions also prints
+# echo to stdout stream:
+# ----------------------------------------------------------------
+push-env = $(shell $(BUILDSYSTEM)/transmitting_hash \
+	     --set --hardware=$(HARDWARE) --flavour=$(FLAVOUR) \
+	     --pool-name=$(strip $1) --name=$(strip $2) --value=$(strip $3))
+
+pull-env = $(shell $(BUILDSYSTEM)/transmitting_hash \
+	     --get --hardware=$(HARDWARE) --flavour=$(FLAVOUR) \
+	     --pool-name=$(strip $1) --name=$(strip $2) --value=$(strip $3))
+
+push-env-vo = $(shell $(BUILDSYSTEM)/transmitting_hash \
+	     --set --value-only --hardware=$(HARDWARE) --flavour=$(FLAVOUR) \
+	     --pool-name=$(strip $1) --name=$(strip $2) --value=$(strip $3))
+
+pull-env-vo = $(shell $(BUILDSYSTEM)/transmitting_hash \
+	     --get --value-only --hardware=$(HARDWARE) --flavour=$(FLAVOUR) \
+	     --pool-name=$(strip $1) --name=$(strip $2) --value=$(strip $3))
+#
+# usage:
+# -----
+#   environment  = $(call push-env, perl, HOME, \'/home/kx\')
+#   environment += $(call push-env, perl, DIR, \'$(CURDIR)\')
+#   environment += $(call push-env, perl, BASH, \'/bin/bash\')
+#   environment += --set $(call push-env, perl, archlib, \'/usr/lib$(LIBSUFFIX)/perl5/$(ARCHNAME)\')
+#
+#   environment  = HOME=$(call pull-env-vo, perl, HOME, \'/home/olga\')
+#   environment += DIR=$(call pull-env-vo, perl, DIR, \'$(CURDIR)\')
+#   environment += BASH=$(call pull-env-vo, perl, BASH, \'/bin/sh\')
+#   environment += --set archlib=$(call pull-env-vo, perl, archlib, \'/usr/lib$(LIBSUFFIX)/perl5/$(ARCHNAME)\')
+# ----------------------------------------------------------------
+#
+# End of Functions.
+################################################################
+
+
+
+################################################################
+#
+# Example rule:
+#
+# src_done = $(SRC_DIR)/.source-done
+#
+# $(src_done): $(SRC_ARCHIVE) $(PATCHES_DEP)
+# 	$(UNPACK_SRC_ARCHIVE)
+# 	$(APPLY_PATCHES)
+# 	 <other stuff that needs to be done to the source,
+# 	   should be empty in most cases>
+# 	@touch $@
+#
+################################################################
+
+#######
+####### Source archive and patch handling.
+#######
+################################################################
+
+
+################################################################
+#######
+####### Include files with references to BUILD-SYSTEM scripts:
+#######
+
+-include $(BUILDSYSTEM)/pkgtool/.config
+-include $(BUILDSYSTEM)/progs/.config
+-include $(BUILDSYSTEM)/scripts/.config
+-include $(BUILDSYSTEM)/sbin/.config
+
+#######
+####### References to BUILD-SYSTEM scripts.
+#######
+################################################################
+
+
+
+################################################################
+#
+# No '__final__' target selected:
+# ==============================
+#
+# Parse TOOLCHAIN, HARDWARE, FLAVOUR selected in command line
+# and build the list of '__final__' targets.
+#
+ifeq ($(__final__),)
+
+#
+# The FLAVOUR can be defined in command line.
+# If command line defines empty flavour FLAVOUR= then
+# we define that variable is set but has no values.
+#
+__cmdline_flavour_defined = $(if $(filter FLAVOUR,$(.VARIABLES)),true,false)
+ifeq ($(__cmdline_flavour_defined),true)
+__cmdline_flavour_value = $(FLAVOUR)
+else
+__cmdline_flavour_value =
+endif
+
+##############################################################
+# -----------+----------+---------+-------------------+-----
+#  TOOLCHAIN | HARDWARE | FLAVOUR | FLAVOUR has VALUE | REF
+# -----------+----------+---------+-------------------+-----
+#    defined |  defined | defined |         yes       | (0)
+#    defined |  defined | defined |         no        | (1)
+#    defined |  defined |    ~    |         ~         | (2)
+# -----------+----------+---------+-------------------+-----
+#    defined |     ~    | defined |         yes       | (3)
+#    defined |     ~    | defined |         no        | (4)
+#    defined |     ~    |    ~    |         ~         | (5)
+# -----------+----------+---------+-------------------+-----
+#       ~    |  defined | defined |         yes       | (6)
+#       ~    |  defined | defined |         no        | (7)
+#       ~    |  defined |    ~    |         ~         | (8)
+# -----------+----------+---------+-------------------+-----
+#       ~    |     ~    | defined |         yes       | (9)
+#       ~    |     ~    | defined |         no        | (A)
+#       ~    |     ~    |    ~    |         ~         | (B)
+# -----------+----------+---------+-------------------+-----
+##############################################################
+
+# we allow only available combinations according to component targets and flavours lists
+
+ifeq ($(TOOLCHAIN),)
+ifeq ($(HARDWARE),)
+ifeq ($(FLAVOUR),)
+ifeq ($(__cmdline_flavour_defined),false)
+# (B) ======= loop: T, H, F;                           =======
+__target_args = $(__available_targets)
+else
+# (A) ======= loop: T, H   ; where          F=0        =======
+__target_args = $(foreach arch, $(shell echo $(COMPONENT_TOOLCHAINS) | sed -e 's/x86_64/x86-64/g'),        \
+                  $(foreach hardware, $($(shell echo ${arch} | tr '[a-z-]' '[A-Z_]')_HARDWARE_VARIANTS),   \
+                    .target_$(arch)_$(hardware)                                                            \
+                   )                                                                                       \
+                 )
+endif
+else
+# (9) ======= loop: T, H   ; where          F=const    =======
+__target_args = $(foreach arch, $(shell echo $(COMPONENT_TOOLCHAINS) | sed -e 's/x86_64/x86-64/g'),        \
+                  $(foreach hardware, $($(shell echo ${arch} | tr '[a-z-]' '[A-Z_]')_HARDWARE_VARIANTS),   \
+                    $(if $(filter $(FLAVOUR), $($(shell echo ${hardware} | tr '[a-z]' '[A-Z]')_FLAVOURS)), \
+                       .target_$(arch)_$(hardware)_$(FLAVOUR),                                             \
+                       $(if $(filter $(FLAVOUR), $(FLAVOURS)),                                             \
+                         .target_$(arch)_$(hardware)_$(FLAVOUR),                                           \
+                        )                                                                                  \
+                     )                                                                                     \
+                   )                                                                                       \
+                 )
+endif
+else
+ifeq ($(FLAVOUR),)
+ifeq ($(__cmdline_flavour_defined),false)
+# (8) ======= loop: T,  , F; where H=const             =======
+__target_args = $(foreach arch, $(shell echo $(call toolchain,$(HARDWARE)) | sed -e 's/x86_64/x86-64/g'), \
+                  $(if $($(shell echo $(HARDWARE) | tr '[a-z]' '[A-Z]')_FLAVOURS),                        \
+                    $(foreach flavour, $($(shell echo $(HARDWARE) | tr '[a-z]' '[A-Z]')_FLAVOURS),        \
+                      .target_$(arch)_$(HARDWARE)_$(flavour)                                              \
+                     ) .target_$(arch)_$(HARDWARE),                                                       \
+                     $(if $(FLAVOURS),                                                                    \
+                       $(foreach flavour, $(FLAVOURS),                                                    \
+                         .target_$(arch)_$(HARDWARE)_$(flavour)                                           \
+                        ),                                                                                \
+                      ) .target_$(arch)_$(HARDWARE)                                                       \
+                   )                                                                                      \
+                 )
+else
+# (7) ======= loop: T,  ,  ; where H=const, F=0        =======
+__target_args = $(foreach arch, $(shell echo $(call toolchain,$(HARDWARE)) | sed -e 's/x86_64/x86-64/g'), \
+                    .target_$(arch)_$(HARDWARE)                                                           \
+                 )
+endif
+else
+# (6) ======= loop: T,  ,  ; where H=const, F=const    =======
+__target_args = $(foreach arch, $(shell echo $(call toolchain,$(HARDWARE)) | sed -e 's/x86_64/x86-64/g'), \
+                    .target_$(arch)_$(HARDWARE)_$(FLAVOUR)                                                \
+                 )
+endif
+endif
+else
+ifeq ($(HARDWARE),)
+ifeq ($(FLAVOUR),)
+ifeq ($(__cmdline_flavour_defined),false)
+# (5) ======= loop:  , H, F; where T=const             =======
+__target_args = $(foreach hardware, $($(shell echo $(TOOLCHAIN) | tr '[a-z-]' '[A-Z_]')_HARDWARE_VARIANTS),    \
+                  $(if $($(shell echo ${hardware} | tr '[a-z]' '[A-Z]')_FLAVOURS),                             \
+                    $(foreach flavour, $($(shell echo ${hardware} | tr '[a-z]' '[A-Z]')_FLAVOURS),             \
+                      .target_$(shell echo $(TOOLCHAIN) | sed -e 's/x86_64/x86-64/g')_$(hardware)_$(flavour)   \
+                     ) .target_$(shell echo $(TOOLCHAIN) | sed -e 's/x86_64/x86-64/g')_$(hardware),            \
+                    $(if $(FLAVOURS),                                                                          \
+                      $(foreach flavour, $(FLAVOURS),                                                          \
+                        .target_$(shell echo $(TOOLCHAIN) | sed -e 's/x86_64/x86-64/g')_$(hardware)_$(flavour) \
+                       ),                                                                                      \
+                     )                                                                                         \
+                     .target_$(shell echo $(TOOLCHAIN) | sed -e 's/x86_64/x86-64/g')_$(hardware)               \
+                   )                                                                                           \
+                 )
+else
+# (4) ======= loop:  , H,  ; where T=const, F=0        =======
+__target_args = $(foreach hardware, $($(shell echo $(TOOLCHAIN) | tr '[a-z-]' '[A-Z_]')_HARDWARE_VARIANTS), \
+                    .target_$(shell echo $(TOOLCHAIN) | sed -e 's/x86_64/x86-64/g')_$(hardware)             \
+                 )
+endif
+else
+# (3) ======= loop:  , H,  ; where T=const, F=const    =======
+__target_args = $(foreach hardware, $($(shell echo $(TOOLCHAIN) | tr '[a-z-]' '[A-Z_]')_HARDWARE_VARIANTS), \
+                    .target_$(shell echo $(TOOLCHAIN) | sed -e 's/x86_64/x86-64/g')_$(hardware)_$(FLAVOUR)  \
+                 )
+endif
+else
+ifeq ($(FLAVOUR),)
+ifeq ($(__cmdline_flavour_defined),false)
+# (2) ======= loop:  ,  , F; where T=const, H=const    =======
+__target_args = $(if $($(shell echo $(HARDWARE) | tr '[a-z]' '[A-Z]')_FLAVOURS),                              \
+                  $(foreach flavour, $($(shell echo $(HARDWARE) | tr '[a-z]' '[A-Z]')_FLAVOURS),              \
+                    .target_$(shell echo $(TOOLCHAIN) | sed -e 's/x86_64/x86-64/g')_$(HARDWARE)_$(flavour)    \
+                   ) .target_$(shell echo $(TOOLCHAIN) | sed -e 's/x86_64/x86-64/g')_$(HARDWARE),             \
+                   $(if $(FLAVOURS),                                                                          \
+                     $(foreach flavour, $(FLAVOURS),                                                          \
+                       .target_$(shell echo $(TOOLCHAIN) | sed -e 's/x86_64/x86-64/g')_$(HARDWARE)_$(flavour) \
+                      ) .target_$(shell echo $(TOOLCHAIN) | sed -e 's/x86_64/x86-64/g')_$(HARDWARE),          \
+                    ) .target_$(shell echo $(TOOLCHAIN) | sed -e 's/x86_64/x86-64/g')_$(HARDWARE)             \
+                 )
+else
+# (1) ======= loop:  ,  ,  ; T=const, H=const, F=0     =======
+__target_args = .target_$(shell echo $(TOOLCHAIN) | sed -e 's/x86_64/x86-64/g')_$(HARDWARE)
+endif
+else
+# (0) ======= loop:  ,  ,  ; T=const, H=const, F=const =======
+__target_args = .target_$(shell echo $(TOOLCHAIN) | sed -e 's/x86_64/x86-64/g')_$(HARDWARE)_$(FLAVOUR)
+endif
+endif
+endif
+
+__target_args := $(strip $(__target_args))
+
+
+__targets = $(filter $(__target_args), $(__available_targets))
+
+# Now we have to sort targets for that the main targets should be built before flavours!
+__targets := $(sort $(__targets))
+
+
+ifeq ($(__targets),)
+$(error Error: Selected combination [TOOLCHAIN=$(TOOLCHAIN), HARDWARE=$(HARDWARE), FLAVOUR=$(FLAVOUR)] is invalid for this Makefile)
+endif
+
+$(__targets): .setup
+
+
+#
+# NOTE:
+# ====
+#     Several FLAVOURS can require the same package, for example, base/pkgtool.
+#     To avoid concurrency problems we have to diable parallel building for Makefiles
+#     where there are FLAVOURS.
+#
+#     We have to check both HW specific and general FLAVOURS.
+#
+all-flavour-values = $(strip $(foreach flname, $(filter FLAVOURS %_FLAVOURS, $(.VARIABLES)), $($(flname))))
+
+ifneq ($(all-flavour-values),)
+.NOTPARALLEL: $(__targets)
+endif
+
+
+local_all: GOAL = local_all
+local_all: $(__targets)
+
+
+local_clean: GOAL = local_clean
+local_clean: $(__targets)
+
+
+local_dist_clean: GOAL = local_dist_clean
+local_dist_clean: $(__targets)
+
+
+local_rootfs_clean: GOAL = local_rootfs_clean
+local_rootfs_clean: $(__targets)
+
+requires_tree: GOAL = requires_tree
+requires_tree: $(__targets)
+
+packages_list: GOAL = packages_list
+packages_list: $(__targets)
+
+devices_table: GOAL = devices_table
+devices_table: $(__targets)
+
+ext4fs_image:  GOAL = ext4fs_image
+ext4fs_image:  $(__targets)
+
+products_release:  GOAL = products_release
+products_release:  $(__targets)
+
+
+.target_%: TOOLCHAIN = $(shell echo $(word 2, $(subst _, , $@)) | sed -e 's/x86-64/x86_64/g')
+.target_%: HARDWARE = $(if $(filter $(shell echo $(word 3, $(subst _, , $@))),$(HARDWARE_ALL)),$(word 3, $(subst _, , $@)))
+.target_%: FLAVOUR = $(if $(word 4, $(subst _, , $@)),$(word 4, $(subst _, , $@)),$(if $(filter $(shell echo $(word 3, $(subst _, , $@))),$(HARDWARE_ALL)),,$(word 3, $(subst _, , $@))))
+.target_%:
+	@echo ""
+	@echo -e "################################################################"
+	@echo -e "#######"
+	@echo -e "####### TOOLCHAIN=$(TOOLCHAIN) ; HARDWARE=$(HARDWARE) ; FLAVOUR=$(if $(FLAVOUR),$(FLAVOUR)) ;"
+	@echo -e "#######"
+	@__final__=true $(MAKE) TOOLCHAIN=$(TOOLCHAIN) HARDWARE=$(HARDWARE) FLAVOUR=$(FLAVOUR) $(GOAL)
+
+
+else
+#
+################################################################
+#
+# The '__final__' target is defined, run the build process.
+
+
+targetflavour = .$(TOOLCHAIN)/$(HARDWARE)$(if $(FLAVOUR),/$(FLAVOUR),)
+
+TARGET_BUILD_DIR = $(targetflavour)
+
+ifeq ($(filter %_clean,$(MAKECMDGOALS)),)
+ifneq ($(shell pwd),$(TOP_BUILD_DIR_ABS))
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+$(shell mkdir -p .$(TOOLCHAIN)/$(HARDWARE)$(if $(FLAVOUR),/$(FLAVOUR)))
+endif
+endif
+endif
+
+ifneq ($(NO_CREATE_DIST_FILES),true)
+local_all: CREATE_DIST_FILES = 1
+endif
+
+
+ifeq ($(BUILD_TREE),true)
+_tree := .tree_all
+else
+_tree := .requires_makefile
+endif
+
+#
+local_all: .toolchain $(_tree) _install
+
+
+ifeq ($(CLEAN_TREE),true)
+local_clean: .tree_clean
+else
+local_clean:
+endif
+
+ifeq ($(DIST_CLEAN_TREE),true)
+local_dist_clean: .tree_dist_clean
+else
+local_dist_clean:
+endif
+
+ifeq ($(ROOTFS_CLEAN_TREE),true)
+local_rootfs_clean: .tree_rootfs_clean
+else
+local_rootfs_clean:
+endif
+
+.toolchain:
+ifneq ($(TOOLCHAIN_PATH),)
+ifeq ($(wildcard $(TOOLCHAIN_PATH)),)
+	@echo -e "################################################################"
+	@echo -e "#######"
+	@echo -e "####### Start of downloading toolchain '$(shell basename $(TOOLCHAIN_TARBALL))':"
+	@echo -e "#######"
+	@if [ -d $(TOOLCHAINS_BASE_PATH) -a -w $(TOOLCHAINS_BASE_PATH) ] ; then \
+	  ( cd $(TOOLCHAINS_BASE_PATH) ; \
+	    $(BUILDSYSTEM)/download-toolchain "$(DOWNLOAD_SERVER)/$(TOOLCHAIN_TARBALL)" ; \
+	  ) ; \
+	 else \
+	   echo -e "#" ; \
+	   echo -e "#" ; \
+	   echo -e "# Please create '$(TOOLCHAINS_BASE_PATH)' directory" ; \
+	   echo -e "# and give write permissions to '$(shell echo "`id -u -n`")':" ; \
+	   echo -e "#" ; \
+	   echo -e "#    # sudo mkdir -p $(TOOLCHAINS_BASE_PATH)" ; \
+	   echo -e "#    # sudo chown -R $(shell echo "`id -u -n`"):$(shell echo "`id -g -n`") $(TOOLCHAINS_BASE_PATH)" ; \
+	   echo -e "#" ; \
+	   echo -e "#" ; \
+	   echo -e "# ERROR: $(TOOLCHAINS_BASE_PATH): Permission denied. Stop." ; \
+	   echo -e "#" ; \
+	   exit 1 ; \
+	 fi
+	@echo -e "#######"
+	@echo -e "####### End of downloading toolchain '$(shell basename $(TOOLCHAIN_TARBALL))'."
+	@echo -e "#######"
+	@echo -e "################################################################"
+endif
+endif
+
+
+.tree_all: BUILD_TREE := false
+
+.tree_all: $(TARGET_BUILD_DIR)/.requires
+ifneq ($(shell pwd),$(TOP_BUILD_DIR_ABS))
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+	@echo -e "################################################################"
+	@echo -e "#######"
+ifeq ($(shell pwd),$(BUILDSYSTEM))
+	@echo -e "####### Start of building requires for '$(subst $(TOP_BUILD_DIR_ABS)/,,$(CURDIR))':"
+else
+	@echo -e "####### Start of building requires for TOOLCHAIN=$(TOOLCHAIN) HARDWARE=$(HARDWARE) FLAVOUR=$(FLAVOUR) in '$(subst $(TOP_BUILD_DIR_ABS)/,,$(CURDIR))':"
+endif
+	@echo -e "#######"
+ifeq ($(shell pwd),$(BUILDSYSTEM))
+	@__final__=true TREE_RULE=local_all $(MAKE) TOOLCHAIN=$(TOOLCHAIN_BUILD_MACHINE) HARDWARE=$(HARDWARE_BUILD) FLAVOUR= -f $(TARGET_BUILD_DIR)/.requires
+else
+	@__final__=true TREE_RULE=local_all $(MAKE) TOOLCHAIN=$(TOOLCHAIN) HARDWARE=$(HARDWARE) FLAVOUR= -f $(TARGET_BUILD_DIR)/.requires
+endif
+	@echo -e "#######"
+	@echo -e "####### End of building requires for '$(subst $(TOP_BUILD_DIR_ABS)/,,$(CURDIR))'."
+	@echo -e "#######"
+	@echo -e "################################################################"
+endif
+endif
+
+
+# We always build requires Makeile '.requires_makefile' (for both local and tree build processes).
+# This is needed to cover all tree. In other words we want to have '$(TARGET_BUILD_DIR)/.requires'
+# file in the each directory to be able run 'make requires_tree' command.
+#
+
+.requires_makefile: $(TARGET_BUILD_DIR)/.requires
+
+
+#######
+####### Build directory dependencies into $(TARGET_BUILD_DIR)/.requires
+####### file which is used as a Makefile for tree builds.
+#######
+
+$(TARGET_BUILD_DIR)/.requires_depend: $(TARGET_BUILD_DIR)/.requires ;
+
+$(TARGET_BUILD_DIR)/.requires: .makefile
+ifeq ($(filter %_clean,$(MAKECMDGOALS)),)
+ifneq ($(shell pwd),$(TOP_BUILD_DIR_ABS))
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+ifeq ($(shell pwd),$(BUILDSYSTEM))
+	@$(BUILDSYSTEM)/build_requires $(TOP_BUILD_DIR_ABS) $(TOOLCHAIN_BUILD_MACHINE) $(HARDWARE_BUILD) ; wait
+else
+	@$(BUILDSYSTEM)/build_requires $(TOP_BUILD_DIR_ABS) $(TOOLCHAIN) $(HARDWARE) $(FLAVOUR) ; wait
+endif
+endif
+endif
+endif
+
+
+
+
+################################################################
+#######
+####### Tree Clean up rules:
+#######
+
+.tree_clean: CLEAN_TREE := false
+
+.tree_clean: $(TARGET_BUILD_DIR)/.requires
+ifneq ($(shell pwd),$(TOP_BUILD_DIR_ABS))
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+ifneq ($(wildcard $(TARGET_BUILD_DIR)/.requires),)
+ifeq ($(shell pwd),$(BUILDSYSTEM))
+	@__final__=true TREE_RULE=local_clean $(MAKE) TOOLCHAIN=$(TOOLCHAIN_BUILD_MACHINE) HARDWARE=$(HARDWARE_BUILD) FLAVOUR= -f $(TARGET_BUILD_DIR)/.requires
+else
+	@__final__=true TREE_RULE=local_clean $(MAKE) TOOLCHAIN=$(TOOLCHAIN) HARDWARE=$(HARDWARE) FLAVOUR= -f $(TARGET_BUILD_DIR)/.requires
+endif
+endif
+endif
+endif
+
+
+.tree_dist_clean: DIST_CLEAN_TREE := false
+
+.tree_dist_clean: $(TARGET_BUILD_DIR)/.requires
+ifneq ($(shell pwd),$(TOP_BUILD_DIR_ABS))
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+ifneq ($(shell pwd),$(BUILDSYSTEM))
+	@__final__=true TREE_RULE=local_dist_clean $(MAKE) TOOLCHAIN=$(TOOLCHAIN) HARDWARE=$(HARDWARE) FLAVOUR= -f $(TARGET_BUILD_DIR)/.requires
+endif
+endif
+endif
+
+
+.tree_rootfs_clean: ROOTFS_CLEAN_TREE := false
+
+.tree_rootfs_clean: $(TARGET_BUILD_DIR)/.requires
+ifneq ($(shell pwd),$(TOP_BUILD_DIR_ABS))
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+ifneq ($(shell pwd),$(BUILDSYSTEM))
+	@__final__=true TREE_RULE=local_rootfs_clean $(MAKE) TOOLCHAIN=$(TOOLCHAIN) HARDWARE=$(HARDWARE) FLAVOUR= -f $(TARGET_BUILD_DIR)/.requires
+endif
+endif
+endif
+
+
+#######
+####### End of Tree Clean up rules.
+#######
+################################################################
+
+
+
+################################################################
+#######
+####### Clean up default rules:
+#######
+
+
+#######
+####### Clean:
+#######
+
+#
+# CLEANUP_FILES can be placed outside $(TARGET_BUILD_DIR) directory,
+# the '.$(TOOLCHAIN)' directory can be removed if it is empty  ONLY.
+#
+
+local_clean: .local_clean
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+ifneq ($(wildcard .$(TOOLCHAIN)),)
+	@rm -rf $(CLEANUP_FILES)
+ifneq ($(wildcard $(TARGET_BUILD_DIR)),)
+	@rm -rf $(TARGET_BUILD_DIR)
+endif
+	@if [ "`find .$(TOOLCHAIN) -maxdepth 0 -empty`" ] ; then rm -rf .$(TOOLCHAIN) ; fi
+endif
+endif
+
+.local_clean:
+ifneq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+	@echo -e "####### Cleaning in '`basename $(CURDIR)`' directory is not supported."
+else
+	@echo -e "####### Local Cleaning in '`basename $(CURDIR)`' directory..."
+endif
+
+
+#######
+####### Destination Clean:
+#######
+
+#
+# dist & rootfs cleaning perform only if *.dist, *.rootfs file exists
+# For the product packages, BIN & SCRIPT ..._TARGETS we create *.dist
+# files for each hardware:
+#
+#   .$(HARDWARE).dist
+#
+# Rootfs target have to be alone because we install into root fs only
+# main package (flavour package we copy only into dist/products/...)
+#
+#   .$(HARDWARE).rootfs
+#
+
+local_dist_clean: .local_dist_clean
+ifneq ($(shell pwd),$(BUILDSYSTEM))
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+ifeq ($(wildcard $(TARGET_BUILD_DIR)/.dist),)
+	@echo -e "   (nothing to be done)."
+else
+	@if [ -f $(TARGET_BUILD_DIR)/.dist ] ; then \
+	  $(BUILDSYSTEM)/dist_clean --destination=$(DEST_DIR) \
+	                            --toolchain=$(TOOLCHAIN) --hardware=$(HARDWARE) --flavour=$(FLAVOUR)  ; \
+	  rm -f $(TARGET_BUILD_DIR)/.dist ; \
+	fi
+	@rm -rf $(TARGET_BUILD_DIR)/.dist*
+	@echo -e "   (done)."
+endif
+endif
+endif
+
+.local_dist_clean:
+ifeq ($(shell pwd),$(BUILDSYSTEM))
+	@echo -e "####### Destination cleaning in '`basename $(CURDIR)`' directory is not supported."
+else
+ifneq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+	@echo -e "####### Destination cleaning in '`basename $(CURDIR)`' directory is not supported."
+else
+	@echo -n -e "####### Destination cleaning in '`basename $(CURDIR)`' directory..."
+endif
+endif
+
+
+#######
+####### Root File System Clean:
+#######
+
+local_rootfs_clean: .local_rootfs_clean
+ifneq ($(shell pwd),$(BUILDSYSTEM))
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+ifeq ($(wildcard $(TARGET_BUILD_DIR)/.rootfs),)
+	@echo -e "####### Root File System cleaning...   (nothing to be done)."
+else
+	@if [ -f $(TARGET_BUILD_DIR)/.rootfs ]; then \
+	  REMOVE_PACKAGE="$(REMOVE_PACKAGE)" $(BUILDSYSTEM)/rootfs_clean \
+	                                                    --destination=$(DEST_DIR) \
+	                                                    --toolchain=$(TOOLCHAIN)  \
+	                                                    --hardware=$(HARDWARE)    \
+	                                                    --flavour=$(FLAVOUR)    ; \
+	else \
+	  echo -e "B####### ... Nothing to be done (there are no installed packages)." ; \
+	fi
+	@rm -rf $(TARGET_BUILD_DIR)/.rootfs
+endif
+endif
+endif
+
+.local_rootfs_clean:
+ifeq ($(shell pwd),$(BUILDSYSTEM))
+	@echo -e "####### Root file system cleaning in '`basename $(CURDIR)`' directory is not supported."
+else
+ifneq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+	@echo -e "####### Root file system cleaning in '`basename $(CURDIR)`' directory is not supported."
+else
+	@echo -e "#######"
+	@echo -e "####### Remove packages from 'dist/rootfs/$(TOOLCHAIN)/$(HARDWARE)/...' file system..."
+	@echo -e "#######"
+endif
+endif
+
+
+#######
+####### End of Clean up default rules.
+#######
+################################################################
+
+
+################################################################
+#######
+####### Build REQUIRES tree:
+#######
+
+#
+# $(HARDWARE).html - is a main target of `make requires_tree' procedure:
+#
+requires_tree: $(TARGET_BUILD_DIR)/$(HARDWARE).html
+
+#
+# Requires Tree perform only if goal 'all' is done and all packages installed
+# into root filesystem or into products directory.
+#
+# NOTE:
+#   GNU Make `wildcard' function doesn't work with files which created
+#   during Makefile works. For normal work all tested files should be
+#   created before the Makefile starting my make command.
+#
+$(TARGET_BUILD_DIR)/$(HARDWARE).html:
+ifneq ($(shell pwd),$(BUILDSYSTEM))
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+ifeq ($(shell pwd),$(TOP_BUILD_DIR_ABS))
+	@echo -e "#######"
+	@echo -e "####### Requires Tree creation in the top of '`basename $(CURDIR)`' directory is not supported."
+	@echo -e "#######"
+else
+ifeq ($(wildcard $(TARGET_BUILD_DIR)/.requires),)
+	@echo -e "   (nothing to be done)."
+	@echo -e "#######"
+	@echo -e "####### Before creating a dependency tree all goals have to be made."
+	@echo -e "#######"
+else
+	@echo -e "################################################################"
+	@echo -e "#######"
+	@echo -e "####### Start of building Requires Tree in '`echo $(CURDIR) | sed 's,$(TOP_BUILD_DIR_ABS)/,,'`' directory..."
+	@echo -e "#######"
+	@JSMIN=$(JSMIN) $(BUILDSYSTEM)/build_requires_tree $(TOP_BUILD_DIR_ABS) $(TOOLCHAIN) $(HARDWARE) $(FLAVOUR)
+	@echo -e "#######"
+	@echo -e "####### End of building Requires Tree in '`echo $(CURDIR) | sed 's,$(TOP_BUILD_DIR_ABS)/,,'`' directory."
+	@echo -e "#######"
+	@echo -e "################################################################"
+endif
+endif
+endif
+endif
+
+#######
+####### End of Build REQUIRES tree.
+#######
+################################################################
+
+
+################################################################
+#######
+####### Build PACKAGES list:
+#######
+
+#
+# $(HARDWARE).pkglist - is a main target of `make packages_list' procedure:
+#
+packages_list: $(TARGET_BUILD_DIR)/$(HARDWARE).pkglist
+
+#
+# Packages List perform only if goal 'all' is done and all packages installed
+# into root filesystem or into products directory.
+#
+# NOTE:
+#   GNU Make `wildcard' function doesn't work with files which created
+#   during Makefile works. For normal work all tested files should be
+#   created before the Makefile starting my make command.
+#
+$(TARGET_BUILD_DIR)/$(HARDWARE).pkglist:
+ifneq ($(shell pwd),$(BUILDSYSTEM))
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+ifeq ($(shell pwd),$(TOP_BUILD_DIR_ABS))
+	@echo -e "#######"
+	@echo -e "####### Packages List creation in the top of '`basename $(CURDIR)`' directory is not supported."
+	@echo -e "#######"
+else
+ifeq ($(wildcard $(TARGET_BUILD_DIR)/.requires),)
+	@echo -e "   (nothing to be done)."
+	@echo -e "#######"
+	@echo -e "####### Before creating a dependency tree all goals have to be made."
+	@echo -e "#######"
+else
+	@echo -e "################################################################"
+	@echo -e "#######"
+	@echo -e "####### Start of building Packages List in '`echo $(CURDIR) | sed 's,$(TOP_BUILD_DIR_ABS)/,,'`' directory..."
+	@echo -e "#######"
+	@$(BUILDSYSTEM)/build_packages_list $(TOP_BUILD_DIR_ABS) $(TOOLCHAIN) $(HARDWARE) $(FLAVOUR)
+	@echo -e "#######"
+	@echo -e "####### End of building Packages List in '`echo $(CURDIR) | sed 's,$(TOP_BUILD_DIR_ABS)/,,'`' directory."
+	@echo -e "#######"
+	@echo -e "################################################################"
+endif
+endif
+endif
+endif
+
+#######
+####### End of Build PACKAGES list.
+#######
+################################################################
+
+
+################################################################
+#######
+####### Build Devices Table:
+#######
+
+devices_table: $(TARGET_BUILD_DIR)/.DEVTABLE
+
+$(TARGET_BUILD_DIR)/.DEVTABLE: $(TARGET_BUILD_DIR)/$(HARDWARE).pkglist
+ifneq ($(shell pwd),$(BUILDSYSTEM))
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+ifeq ($(shell pwd),$(TOP_BUILD_DIR_ABS))
+	@echo -e "#######"
+	@echo -e "####### Devices Table creation in the top of '`basename $(CURDIR)`' directory is not supported."
+	@echo -e "#######"
+else
+	@echo -e "################################################################"
+	@echo -e "#######"
+	@echo -e "####### Start of building Devices Table in '`echo $(CURDIR) | sed 's,$(TOP_BUILD_DIR_ABS)/,,'`' directory..."
+	@echo -e "#######"
+	@SYSTEM_VERSION=$(SYSTEM_VERSION) \
+	 DISTRO_VERSION=$(DISTRO_VERSION) \
+	 DISTRO_NAME=$(DISTRO_NAME)       \
+	  $(BUILDSYSTEM)/build_devices_table $(TOP_BUILD_DIR_ABS) $(TOOLCHAIN) $(HARDWARE) $(FLAVOUR)
+	@echo -e "#######"
+	@echo -e "####### End of building Devices Table in '`echo $(CURDIR) | sed 's,$(TOP_BUILD_DIR_ABS)/,,'`' directory."
+	@echo -e "#######"
+	@echo -e "################################################################"
+endif
+endif
+endif
+
+#######
+####### End of Build Devices Table.
+#######
+################################################################
+
+
+################################################################
+#######
+####### Build ext4 Root FS image:
+#######
+
+ext4fs_image: $(TARGET_BUILD_DIR)/$(HARDWARE).ext4fs
+
+$(TARGET_BUILD_DIR)/$(HARDWARE).ext4fs: $(TARGET_BUILD_DIR)/.DEVTABLE
+ifneq ($(shell pwd),$(BUILDSYSTEM))
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+ifeq ($(shell pwd),$(TOP_BUILD_DIR_ABS))
+	@echo -e "#######"
+	@echo -e "####### Ext4 Root FS Image creation in the top of '`basename $(CURDIR)`' directory is not supported."
+	@echo -e "#######"
+else
+	@echo -e "################################################################"
+	@echo -e "#######"
+	@echo -e "####### Start of building Ext4 Root FS Image in '`echo $(CURDIR) | sed 's,$(TOP_BUILD_DIR_ABS)/,,'`' directory..."
+	@echo -e "#######"
+	@( size=`echo $(MAKEFLAGS) | grep 'size=' | sed -e 's,.*size=\([0-9.]*[KMG]\?\).*,\1,'` ; \
+	   if [ -z "$$size" ] ; then \
+	     sizeoption="" ; \
+	   else \
+	     sizeoption="--size=$$size" ; \
+	   fi ; \
+	   MKEE4FS=$(MKE4FS) E4FSCK=$(E4FSCK) POPULATEFS=$(POPULATEFS) \
+	      $(BUILDSYSTEM)/build_ext4fs $$sizeoption $(TOP_BUILD_DIR_ABS) $(TOOLCHAIN) $(HARDWARE) $(FLAVOUR) ; \
+	 )
+	@echo -e "#######"
+	@echo -e "####### End of building Ext4 Root FS Image in '`echo $(CURDIR) | sed 's,$(TOP_BUILD_DIR_ABS)/,,'`' directory."
+	@echo -e "#######"
+	@echo -e "################################################################"
+endif
+endif
+endif
+
+#######
+####### End of Build ext4 Root FS image.
+#######
+################################################################
+
+
+################################################################
+#######
+####### Install $(HARDWARE).{pkglist,ext4fs,SD.MBR} into products directory:
+#######
+
+products_release: $(PRODUCTS_DEST_DIR)/$(HARDWARE).pkglist \
+                  $(PRODUCTS_DEST_DIR)/$(HARDWARE).ext4fs
+
+$(PRODUCTS_DEST_DIR)/$(HARDWARE).ext4fs: $(TARGET_BUILD_DIR)/$(HARDWARE).ext4fs
+ifneq ($(shell pwd),$(BUILDSYSTEM))
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+ifeq ($(shell pwd),$(TOP_BUILD_DIR_ABS))
+	@echo -e "#######"
+	@echo -e "####### Installation of Ext4 Root FS Image from the top of '`basename $(CURDIR)`' directory is not supported."
+	@echo -e "#######"
+else
+	@echo -e "################################################################"
+	@echo -e "#######"
+	@echo -e "####### Installing the Ext4 Root FS Image into '`echo $(PRODUCTS_DEST_DIR) | sed 's,$(TOP_BUILD_DIR_ABS)/,,'`' directory..."
+	@echo -e "#######"
+	@cp -a $(TARGET_BUILD_DIR)/$(HARDWARE).SD.MBR $(PRODUCTS_DEST_DIR)/$(HARDWARE).SD.MBR
+	@cp -a $(TARGET_BUILD_DIR)/$(HARDWARE).ext4fs $(PRODUCTS_DEST_DIR)/$(HARDWARE).ext4fs
+	@$(E4FSCK) -fy $(PRODUCTS_DEST_DIR)/$(HARDWARE).ext4fs
+	@if [ -s $(PRODUCTS_DEST_DIR)/$(HARDWARE).boot-records ] ; then \
+	  $(DD) if=$(TARGET_BUILD_DIR)/$(HARDWARE).SD.MBR \
+	        of=$(PRODUCTS_DEST_DIR)/$(HARDWARE).boot-records \
+	        bs=1 skip=446 seek=446 count=66 conv=notrunc 1> /dev/null 2> /dev/null ; \
+	 fi
+	@echo -e "#######"
+	@echo -e "####### End of installing Ext4 Root FS Image into '`echo $(PRODUCTS_DEST_DIR) | sed 's,$(TOP_BUILD_DIR_ABS)/,,'`' directory."
+	@echo -e "#######"
+	@echo -e "################################################################"
+endif
+endif
+endif
+
+$(PRODUCTS_DEST_DIR)/$(HARDWARE).pkglist: $(TARGET_BUILD_DIR)/$(HARDWARE).pkglist
+ifneq ($(shell pwd),$(BUILDSYSTEM))
+ifeq ($(shell pwd | grep $(TOP_BUILD_DIR_ABS)/$(SRC_PACKAGE_DIR))$(shell pwd | grep $(BUILDSYSTEM)/3pp/sources),)
+ifeq ($(shell pwd),$(TOP_BUILD_DIR_ABS))
+	@echo -e "#######"
+	@echo -e "####### Installation of Packages List from the top of '`basename $(CURDIR)`' directory is not supported."
+	@echo -e "#######"
+else
+	@echo -e "################################################################"
+	@echo -e "#######"
+	@echo -e "####### Installing the Packages List into '`echo $(PRODUCTS_DEST_DIR) | sed 's,$(TOP_BUILD_DIR_ABS)/,,'`' directory..."
+	@echo -e "#######"
+	@mkdir -p $(PRODUCTS_DEST_DIR)
+	@cp -a $(TARGET_BUILD_DIR)/$(HARDWARE).pkglist  \
+	       $(PRODUCTS_DEST_DIR)
+	@( cd $(PRODUCTS_DEST_DIR) ; \
+	   ln -sf $(HARDWARE).pkglist .pkglist ; \
+	 )
+	@echo -e "#######"
+	@echo -e "####### Packages List has been installed into '`echo $(PRODUCTS_DEST_DIR) | sed 's,$(TOP_BUILD_DIR_ABS)/,,'`' directory."
+	@echo -e "#######"
+	@echo -e "################################################################"
+endif
+endif
+endif
+
+#######
+####### End of Install $(HARDWARE).{pkglist,ext4fs,SD.MBR}.
+#######
+################################################################
+
+
+#######
+####### Install rules:
+#######
+
+ifdef SCRIPT_TARGETS
+_install_scripts := .install_scripts
+endif
+
+ifdef BIN_TARGETS
+_install_bins := .install_bins
+endif
+
+ifdef BUILD_TARGETS
+_install_builds := .install_builds
+endif
+
+ifdef PRODUCT_TARGETS
+_install_products := .install_products
+endif
+
+ifdef ROOTFS_TARGETS
+_install_pkgs := .install_pkgs
+endif
+
+ifdef ROOTFS_UPDATE_TARGETS
+_update_pkgs := .update_pkgs
+endif
+
+
+################################################################
+#######
+####### Waiting for build whole required tree:
+#######
+
+$(BUILD_TARGETS)          : | $(_tree)
+
+#######
+####### End of waiting for build whole required tree.
+#######
+################################################################
+
+
+$(PRODUCT_TARGETS)        : | $(BUILD_TARGETS)
+$(ROOTFS_TARGETS)         : | $(BUILD_TARGETS)
+$(ROOTFS_UPDATE_TARGETS)  : | $(BUILD_TARGETS)
+
+
+
+_install: .install
+	@if [ "$$(echo $(TARGET_BUILD_DIR)/.dist*)" != "$(TARGET_BUILD_DIR)/.dist*" ]; then \
+	     sort -o $(TARGET_BUILD_DIR)/.dist.tmp -u $(TARGET_BUILD_DIR)/.dist* ; \
+	     mv $(TARGET_BUILD_DIR)/.dist.tmp $(TARGET_BUILD_DIR)/.dist ; \
+	 fi
+	@rm -f $(TARGET_BUILD_DIR)/.dist.*
+
+
+
+.install: $(_install_scripts)
+.install: $(_install_bins)
+.install: $(_install_builds)
+.install: $(_install_products)
+.install: $(_install_pkgs)
+.install: $(_update_pkgs)
+
+
+# create files which contains the list of installed files
+.install_%: DO_CREATE_DIST_FILES = $(CREATE_DIST_FILES)
+export DO_CREATE_DIST_FILES
+
+
+#
+# Note:
+#    The check such as 'ifdef SCRIPT_TARGETS' realy doesn't need. This
+#    practice can be used in other cases, for example, if we will need
+#    to check some variables used in the following commands.
+#    As example only, we can check existence of FLAVOUR variable:
+#
+#    $(_install_scripts): $(SCRIPT_TARGETS)
+#    ifdef FLAVOUR
+#       @$(BUILDSYSTEM)/install_targets $^ $(TARGET_DEST_DIR)/bin $(HARDWARE) $(FLAVOUR)
+#    else
+#       @$(BUILDSYSTEM)/install_targets $^ $(TARGET_DEST_DIR)/bin $(HARDWARE)
+#    endif
+#
+$(_install_scripts): $(SCRIPT_TARGETS)
+ifdef SCRIPT_TARGETS
+	@$(BUILDSYSTEM)/install_targets         \
+	   --destination=$(TARGET_DEST_DIR)/bin \
+	   --toolchain=$(TOOLCHAIN)             \
+	   --hardware=$(HARDWARE)               \
+	   --flavour=$(FLAVOUR)                 \
+	   $^
+endif
+
+$(_install_bins): $(BIN_TARGETS)
+ifdef BIN_TARGETS
+	@$(BUILDSYSTEM)/install_targets         \
+	   --destination=$(TARGET_DEST_DIR)/bin \
+	   --toolchain=$(TOOLCHAIN)             \
+	   --hardware=$(HARDWARE)               \
+	   --flavour=$(FLAVOUR)                 \
+	   $^
+endif
+
+$(_install_builds): $(BUILD_TARGETS)
+ifdef BUILD_TARGETS
+# Do nothing
+endif
+
+# preserve source dir with depth=1 ; then collect installed products in the .$(HARDWARE).products file
+$(_install_products): $(PRODUCT_TARGETS)
+ifdef PRODUCT_TARGETS
+	@$(BUILDSYSTEM)/install_targets         \
+	   --preserve-source-dir=$(if $(FLAVOUR),two,one) \
+	   --destination=$(PRODUCTS_DEST_DIR)   \
+	   --toolchain=$(TOOLCHAIN)             \
+	   --hardware=$(HARDWARE)               \
+	   --flavour=$(FLAVOUR)                 \
+	   $^
+endif
+
+#
+# NOTE:
+#   We use CWD=$(CURDIR) as a directory for collect .$(HARDWARE).rootfs.* files, also
+#   to allow parallel installation the 'install_pkgs' script install packages from
+#   $(TARGET_BUILD_DIR)/$(PKG_GROUP) directory. In other words if ROOTFS_TARGETS equal to
+#
+#      ROOTFS_TARGETS = $(TARGET_BUILD_DIR)/$(PKG_GROUP)/$(pkg_basename).txz
+#
+#   then 'install_pkgs' going to $(TARGET_BUILD_DIR)/$(PKG_GROUP) directory and installs
+#   the $(pkg_basename).txz package directly from this directory to keep temporary files
+#   separately from other HARDWAREs. In this case we need to use CWD environment variable
+#   to set the directory where the .$(HARDWARE).rootfs.* files will be collected by
+#   'install_pkgs' script (see the 'install_pkgs' source code).
+#
+#   Parallel installation when ROOTFS_TARGETS presents not alone package not tested.
+#
+$(_install_pkgs): $(ROOTFS_TARGETS)
+ifdef ROOTFS_TARGETS
+	@echo -e "#######"
+	@echo -e "####### Install packages into 'dist/rootfs/$(TOOLCHAIN)/$(HARDWARE)/...' file system..."
+	@echo -e "#######"
+ifeq ($(wildcard $(TARGET_BUILD_DIR)/.rootfs),)
+	@CWD=$(CURDIR) INSTALL_PACKAGE="$(INSTALL_PACKAGE)" \
+	   $(BUILDSYSTEM)/install_pkgs --destination=$(ROOTFS_DEST_DIR) \
+	                               --toolchain=$(TOOLCHAIN)         \
+	                               --hardware=$(HARDWARE)           \
+	                               --flavour=$(FLAVOUR)             \
+	                               $^
+else
+	@echo ""
+	@for pkg in $(ROOTFS_TARGETS) ; do \
+	   echo -e "#######  ... package `basename $$pkg` is already installed." ; \
+	 done
+	@echo ""
+endif
+endif
+
+
+$(_update_pkgs): $(ROOTFS_UPDATE_TARGETS)
+ifdef ROOTFS_UPDATE_TARGETS
+	@echo -e "#######"
+	@echo -e "####### Update packages into 'dist/rootfs/$(TOOLCHAIN)/$(HARDWARE)/...' file system..."
+	@echo -e "#######"
+ifeq ($(wildcard $(TARGET_BUILD_DIR)/.rootfs),)
+	@CWD=$(CURDIR) UPDATE_PACKAGE="$(UPDATE_PACKAGE)" \
+	   $(BUILDSYSTEM)/update_pkgs --destination=$(ROOTFS_DEST_DIR) \
+	                              --toolchain=$(TOOLCHAIN)         \
+	                              --hardware=$(HARDWARE)           \
+	                              --flavour=$(FLAVOUR)             \
+	                              $^
+else
+	@echo ""
+	@for pkg in $(ROOTFS_UPDATE_TARGETS) ; do \
+	   echo -e "#######  ... package `basename $$pkg` is already installed." ; \
+	 done
+	@echo ""
+endif
+endif
+
+
+
+
+
+################################################################
+#######
+####### Generic Rules Section:
+#######
+
+# link rule, used to build binaries
+# $(target): $(objs)
+# 	$(LINK)
+#
+
+LINKER = $(if $(filter .cpp,$(suffix $(SRCS))),$(CXX_LINKER),$(CC_LINKER))
+
+ifeq ($(COMPONENT_IS_3PP),)
+LINKMAP = -Wl,-Map,$@.linkmap
+endif
+
+BASIC_LDOPTS  = $(LDFLAGS) $(LINKMAP)
+BASIC_LDOPTS += -o $@ $(filter %.o,$^)
+
+
+define cmdheader
+  @echo -e ""
+  @echo -e "======= $(1) ======="
+  $(2)
+  @echo -e ""
+endef
+
+
+LINK = $(call cmdheader,"Linking $@",$(LINKER) $(BASIC_LDOPTS))
+
+# LINK_C overrides the automatic linker selection provided with LINK
+# and always  uses gcc. Useful when building both C and C++ targets
+# in the same component:
+LINK_C = $(call cmdheader,"Linking $@",$(CC) $(BASIC_LDOPTS))
+
+LINK_SO = $(call cmdheader,"Linking $@", $(LINKER) $(BASIC_LDOPTS) -shared)
+
+LINK_A = $(call cmdheader,"Building $@",$(AR) cru $@ $^)
+
+
+#######
+####### Source dependency
+#######
+
+flatfile = $(subst /,_,$(subst ./,,$(1)))
+DEPFILE = $(patsubst %.o,%.d,$(if $(findstring $(TOOLCHAIN),$@),$(TARGET_BUILD_DIR)/$(call flatfile,$(subst $(TARGET_BUILD_DIR)/,,$@)),$(call flatfile,$@)))
+DEPSETUP = -MD -MP -MF $(DEPFILE) -MT $@
+
+####### .cpp -> .o
+%.o: %.cpp
+	@echo -e ""
+	@echo -e "======= $< -> $@ ======="
+	$(quiet)$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $(DEPSETUP) $<
+
+$(TARGET_BUILD_DIR)/%.o: %.cpp
+	@echo -e "\n======= $< -> $@ ======="
+	@mkdir -p $(dir $@)
+	$(quiet)$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $(DEPSETUP) $<
+
+####### .c -> .o
+%.o: %.c
+	@echo -e ""
+	@echo -e "======= $< -> $@ ======="
+	$(quiet)$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $(DEPSETUP) $<
+
+$(TARGET_BUILD_DIR)/%.o: %.c
+	@echo -e "======= $< -> $@ ======="
+	@mkdir -p $(dir $@)
+	$(quiet)$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $(DEPSETUP) $<
+
+#######
+####### Generic Rules Section.
+#######
+################################################################
+
+
+
+#######
+####### NOTE: Include dependencies should be in section where
+####### the symbol __final__ is defined: ifneq ($(__final__),)
+#######
+
+#######
+####### Include dependencies if they exist
+#######
+
+-include $(targetflavour)/*.d
+
+# Include HW dependencies
+-include $(TARGET_BUILD_DIR)/.requires_depend
+
+#######
+####### Include sources dependency if they exist
+#######
+
+-include .src_requires_depend
+
+
+
+################################################################
+#######
+####### HW depended macro for create PKG requires:
+#######
+    BUILD_PKG_REQUIRES = $(BUILDSYSTEM)/build_pkg_requires $(REQUIRES)
+BUILD_ALL_PKG_REQUIRES = $(BUILDSYSTEM)/build_pkg_requires --pkg-type=all $(REQUIRES)
+BUILD_BIN_PKG_REQUIRES = $(BUILDSYSTEM)/build_pkg_requires --pkg-type=bin $(REQUIRES)
+BUILD_DEV_PKG_REQUIRES = $(BUILDSYSTEM)/build_pkg_requires --pkg-type=dev $(REQUIRES)
+#######
+####### HW depended macro for create PKG requires.
+#######
+################################################################
+
+
+endif
+#
+# end of ifeq ($(__final__),)
+#
+################################################################
+
+
+
+
+# HW depended targets:
+.PHONY: .target*
+
+.PHONY: .toolchain
+
+.PHONY: $(_tree)
+.PHONY: .requires_makefile
+
+.PHONY:    .tree_all  .tree_clean  .tree_dist_clean  .tree_rootfs_clean
+.PHONY: all _install        clean        dist_clean        rootfs_clean
+.PHONY:    local_all  local_clean  local_dist_clean  local_rootfs_clean
+.PHONY:              .local_clean .local_dist_clean .local_rootfs_clean
+
+.PHONY: .install $(_install_scripts) $(_install_builds) $(_install_bins) $(_install_products)
+.PHONY:          $(_install_pkgs) $(_update_pkgs)
+
+# HW independed targets:
+.PHONY: help
+.PHONY: .setup
+.PHONY: .sources      .build_system
+.PHONY:  global_clean  downloads_clean
+.PHONY: .global_clean .downloads_clean
+
+.SUFFIXES:
+
+
+
+
+
+CORE_MK = 1
+endif
Index: build-system-1.2.3/pkgtool/change-refs
===================================================================
--- build-system-1.2.3/pkgtool/change-refs	(nonexistent)
+++ build-system-1.2.3/pkgtool/change-refs	(revision 231)
@@ -0,0 +1,211 @@
+#!/bin/sh
+
+program=`basename $0`
+
+# EXIT STATUS 92 = Cannot create '/tmp/...' directory
+
+umask 002
+if [ ! -z "$TMPDIR" ] ; then mkdir -p $TMPDIR ; fi
+TMP=$(mkdir -p /tmp/radix && mktemp -d -p /tmp/radix pkgtool.XXXXXXXX) || { echo "Cannot create '/tmp/...' directory" ; exit 92; }
+trap "rm -rf $TMP" EXIT
+
+
+usage() {
+  echo ""
+  echo "Usage: cd /SETUP_DB_PATH/packages; $program operation pkglogfile"
+  echo ""
+  echo "Where the following operations are available:"
+  echo "  inc - increment reference counters in the required package logs"
+  echo "  dec - decrement reference counters in the required package logs"
+  echo ""
+}
+
+get_pkg_name_from_logfile() {
+  logfile=$1
+  if [ -f ./$logfile ]; then
+    pkginfo --dest $TMP pkginfo $logfile
+    if [ ! -f $TMP/.PKGINFO -o ! -s $TMP/.PKGINFO ]; then
+      rm -f $TMP/.PKGINFO
+    else
+      # store current values
+      cst01=pkgname
+      cst02=pkgver
+      cst03=arch
+      cst04=distroname
+      cst05=distrover
+      cst06=group
+      cst07=short_description
+      cst08=url
+      cst09=license
+      cst10=uncompressed_size
+      cst11=total_files
+
+      . $TMP/.PKGINFO
+      rm -f $TMP/.PKGINFO
+      if [ "$pkgname" = "" ]; then
+        echo ""
+      else
+        echo "$pkgname"
+      fi
+
+      # restore current values
+      pkgname=cst01
+      pkgver=cst02
+      arch=cst03
+      distroname=cst04
+      distrover=cst05
+      group=cst06
+      short_description=cst07
+      url=cst08
+      license=cst09
+      uncompressed_size=cst10
+      total_files=cst11
+    fi
+  else
+    echo ""
+  fi
+}
+
+refcounter=
+get_ref_counter() {
+  logfile=$1
+  LINENUM_REF="`cat $logfile | grep -n -e "REFERENCE COUNTER:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_REF" = "" ]; then
+    refcounter=
+  fi
+  LINE="`sed -n "$LINENUM_REF p" $logfile`"
+  refcounter="`echo "$LINE" | sed -e 's/^REFERENCE COUNTER: //'`"
+}
+
+set_ref_counter() {
+  logfile=$1
+  refs=$2
+  LINENUM_REF="`cat $logfile | grep -n -e "REFERENCE COUNTER:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_REF" = "" ]; then
+#    echo "$program: WARNING: reference counter is not present in $logfile ."
+    return
+  fi
+  LINE="`sed -n "$LINENUM_REF p" $logfile`"
+  oldrefs="`echo "$LINE" | sed -e 's/^REFERENCE COUNTER: //'`"
+  if [ ! "$oldrefs" = "" ]; then
+    sed -i "$LINENUM_REF s/$oldrefs/$refs/" $logfile
+  fi
+}
+
+inc_ref_counter() {
+  logfile=$1
+  pkgn=$2
+  pkgv=$3
+
+  #
+  # Insert who requires this package and increment the counter in one time:
+  #
+  sed -i -re 's/(^REFERENCE COUNTER: )([0-9]+)/echo "\1$((\2+1))"/ge' -e "/^REFERENCE COUNTER:/ a\
+$pkgn=$pkgv
+" $logfile
+}
+
+dec_ref_counter() {
+  logfile=$1
+  pkgn=$2
+  pkgv=$3
+  LINENUM_RFS="`cat $logfile | grep -n -e "REFERENCE COUNTER:" | cut -f 1 -d ':'`"
+  LINENUM_RQS="`cat $logfile | grep -n -e "REQUIRES:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_RFS" = "" ]; then
+#    echo "$program: WARNING: reference counter is not present in $logfile ."
+    return
+  fi
+  LINE="`sed -n "$LINENUM_RFS p" $logfile`"
+  oldrefs="`echo "$LINE" | sed -e 's/^REFERENCE COUNTER: //'`"
+  if [ ! "$oldrefs" = "" ]; then
+    refs=$oldrefs
+    if [ ! "$refs" = "0" ]; then
+      # remove all of lines '$pkgn=$pkgv' between 'REFERENCE COUNTER:' and 'REQUIRES:' lines
+      LINENUM_FOUND=`cat $logfile | grep -n -e "^$pkgn=$pkgv" | cut -f 1 -d ':'`
+      DEL_LINES=""
+      if [ ! "$LINENUM_FOUND" = "" ] ; then
+        for LINENUM_TODEL in $LINENUM_FOUND ; do
+          if [ $LINENUM_TODEL -gt $LINENUM_RFS -a $LINENUM_TODEL -lt $LINENUM_RQS ]; then
+            let refs-=1
+            if [ "$DEL_LINES" = "" ]; then
+              DEL_LINES=$LINENUM_TODEL # first line to delete
+            fi
+          fi
+        done
+        if [ $refs -lt 0 ]; then
+          refs=0
+        fi
+        DEL_LINES=$DEL_LINES,$LINENUM_TODEL # add the last line to delete
+        sed -i "$DEL_LINES d" $logfile
+        sed -i "$LINENUM_RFS s/$oldrefs/$refs/" $logfile
+        # if we need decrement only then we can use:
+        #sed -i -re 's/(^REFERENCE COUNTER: )([0-9]+)/if [ "\2" -ne "0" ] ; then echo "\1$((\2-1))" ; else echo "\10" ; fi/e' \
+        #        -e "$DEL_LINES d" $logfile
+      fi
+    fi
+  fi
+}
+
+
+operation=$1
+shift
+if [ ! "$operation" = "inc" -a ! "$operation" = "dec" ]; then
+  usage
+  echo "$program: ERROR: invalid operation name."
+  echo
+  exit 1
+fi
+if [ "$operation" = "inc" ]; then
+  operation=inc_ref_counter
+elif [ "$operation" = "dec" ]; then
+  operation=dec_ref_counter
+fi
+
+if [ "$1" = "" ]; then
+  usage
+  echo "$program: ERROR: pkglogfile is not present in argument list."
+  echo
+  exit 1
+fi
+logfile=$1
+
+
+pkginfo --dest $TMP requires $logfile
+if [ ! -f $TMP/.REQUIRES -o ! -s $TMP/.REQUIRES ]; then
+  rm -f $TMP/.REQUIRES
+  exit 0
+fi
+
+pkginfo --dest $TMP pkginfo $logfile
+if [ ! -f $TMP/.PKGINFO -o ! -s $TMP/.PKGINFO ]; then
+  rm -f $TMP/.PKGINFO
+  exit 0
+else
+  . $TMP/.PKGINFO
+  rm -f $TMP/.PKGINFO
+  if [ "$pkgname" = "" -o "$pkgver" = "" ]; then
+    echo "$program: ERROR: pkglogfile doesn't contain necessary declarations."
+    exit 0
+  fi
+fi
+
+# read lines:
+LINENUMS=`sed -n "$=" $TMP/.REQUIRES`
+LINENUM_REQ=1
+while [ "$LINENUM_REQ" -le "$LINENUMS" ]; do
+  LINE="`sed -n "$LINENUM_REQ p" $TMP/.REQUIRES`"
+  let LINENUM_REQ+=1
+  pnam=`echo "$LINE" | cut -f 1 -d '='`
+  pver=`echo "$LINE" | cut -f 2 -d '='`
+  # NOTE: the version of found package is not checked.
+  for reqfile in `find * -type f -name "$pnam-*"` ; do
+    # cut off pkgver-arch-distroname-distroversion fields of founded file name:
+    pname_only=`get_pkg_name_from_logfile $reqfile`
+    if [ "$pname_only" = "$pnam" ]; then
+      $operation $reqfile $pkgname $pkgver
+    fi
+  done
+done
+rm -f $TMP/.REQUIRES
+
+exit 0

Property changes on: build-system-1.2.3/pkgtool/change-refs
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/pkgtool/check-package.in
===================================================================
--- build-system-1.2.3/pkgtool/check-package.in	(nonexistent)
+++ build-system-1.2.3/pkgtool/check-package.in	(revision 231)
@@ -0,0 +1,419 @@
+#!/bin/sh
+
+TAR=tar
+
+# program name:
+program=`basename $0`
+
+#  1 = tar returned error code
+#  2 = failed read package info
+#  4 = not a file
+# 11 = broken .PKGINFO
+# 12 = broken .DESCRIPTION
+# 13 = permission denied (should be root)
+# 14 = broken .pkglist or user pkglist
+# 15 = priority has not specified arter --priority option
+# 16 = root path has not specified arter --root option
+# 17 = exit if called with no arguments
+# 19 =  pre install script returns bad status
+# 20 = post install script returns bad status
+# 21 =  pre Remove script returns bad status
+# 22 = post Remove script returns bad status
+# 23 = package is not installed correctly
+# 24 = {Setup | Package} database directory doesn't exist.
+# 25 = {There are not resolved requires | Reference counter is not empty}
+# 26 = the 'pkglogfile' cannot be restored in the package data base
+# 92 = Cannot create '/tmp/...' directory
+######!# 99 = user abort from menu mode
+EXITSTATUS=0
+
+CWD=`pwd`
+
+umask 002
+if [ ! -z "$TMPDIR" ] ; then mkdir -p $TMPDIR ; fi
+TMP=$(mkdir -p /tmp/radix && mktemp -d -p /tmp/radix pkgtool.XXXXXXXX) || { echo "Cannot create '/tmp/...' directory" ; exit 92; }
+trap "rm -rf $TMP" EXIT
+
+
+usage() {
+ cat << EOF
+
+Usage: $program [options] { package_tarball | pkglogfile }
+
+$program is used to determine how the package is installed:
+   $program /packagesdir/_kxLibc-1.0.4-x86_64-glibc-radix-1.0.txz
+   $program /SETUP_DB_PATH/packages/_kxLibc-1.0.4-x86_64-glibc-radix-1.0
+
+returns:
+   30 - Package is installed correctly;
+   31 - Package is not installed;
+   32 - Package is installed but not correct.
+
+options:
+   --root /dest    - install someplace else, like /dest;
+   --dark          - do not output log messages into stdout.
+                     no afect if an error;
+   --print-list    - print the list of brocken links and
+                     files to stdout.
+                     no afect if '--dark' option is used;
+   --skip-requires - skip checking required packages.
+
+EOF
+}
+
+refcounter=
+get_ref_counter() {
+  logfile=$1
+  LINENUM_REF="`cat $logfile | grep -n -e "REFERENCE COUNTER:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_REF" = "" ]; then
+    refcounter=
+  fi
+  LINE="`sed -n "$LINENUM_REF p" $logfile`"
+  refcounter="`echo "$LINE" | sed -e 's/^REFERENCE COUNTER: //'`"
+}
+
+tarball_pkginfo() {
+  xzcat $1 | $TAR -xvf - ".PKGINFO" -O  1> $TMP/.PKGINFO  2> /dev/null
+  if [ ! "$?" = "0" ]; then
+    echo "ERROR: Cannot extract package info from $1"
+    EXITSTATUS=1
+    exit $EXITSTATUS
+  fi
+}
+
+extract_links() {
+ sed -n 's,^( *cd \([^ ;][^ ;]*\) *; *rm -rf \([^ )][^ )]*\) *) *$,\1/\2,p'
+}
+
+strip_description() {
+  infile=$1
+  outfile=$2
+  echo " " > $outfile
+  LINENUMS="`cat $infile | grep -n -e "^$pkgname:" | cut -f 1 -d ':'`"
+  if [ "$LINENUMS" = "" ]; then
+    echo "WARNING: Description is empty or corrupted."
+    return
+  fi
+  for LINENUM in $LINENUMS ; do
+    LINE="`sed -n "$LINENUM p" $infile | sed -e "s/^$pkgname://"`"
+    if [ "$LINE" = "" ]; then
+       LINE=" "
+    else
+       LINE="`echo "$LINE" | sed -e "s/ $//g"`"
+    fi
+    echo "$LINE" >> $outfile
+  done
+}
+
+
+#
+# Parse options:
+#
+while [ 0 ]; do
+  if [ "$1" = "-h" -o "$1" = "--help" ]; then
+    usage
+    exit 0
+  elif [ "$1" = "--dark" ]; then
+    DARK="yes"
+    shift 1
+  elif [ "$1" = "--print-list" ]; then
+    PRINTLIST="yes"
+    shift 1
+  elif [ "$1" = "--skip-requires" ]; then
+    SKIPREQUIRES="yes"
+    shift 1
+  elif [ "$1" = "--root" ]; then
+    if [ "$2" = "" ]; then
+      usage
+      echo "ERROR: Target root path has not specified. Check --root option."
+      EXITSTATUS=16
+      exit $EXITSTATUS
+    fi
+    TARGET_ROOT_PATH="$2"
+    shift 2
+  else
+    break
+  fi
+done
+
+#
+# usage(), exit if called with no arguments:
+#
+if [ $# = 0 ]; then
+  usage
+  echo "ERROR: arguments were not specified. Check options."
+  EXITSTATUS=17
+  exit $EXITSTATUS
+fi
+
+if [ "$TARGET_ROOT_PATH" = "" ]; then
+  TARGET_ROOT_PATH="/"
+else
+  TARGET_ROOT_PATH="`echo "$TARGET_ROOT_PATH" | sed -e "s/\/$//"`/"
+fi
+
+if [ "$TARGET_ROOT_PATH" = "/" ]; then
+  if [ ! $UID = "0" ]; then
+    echo "ERROR: Trying to install into root directory: permission denied"
+    EXITSTATUS=13
+    exit $EXITSTATUS
+  fi
+fi
+
+SETUP_DB_PATH=${TARGET_ROOT_PATH}var/log/@DISTRO@
+if [ ! -d $SETUP_DB_PATH ]; then
+  echo "ERROR: Setup database directory doesn't exist."
+  EXITSTATUS=24
+  exit $EXITSTATUS
+fi
+
+PKG_DB_PATH=$SETUP_DB_PATH/packages
+if [ ! -d $PKG_DB_PATH ]; then
+  echo "ERROR: Packages database directory doesn't exist."
+  EXITSTATUS=24
+  exit $EXITSTATUS
+fi
+
+for PKG_DB_DIR in removed_packages setup ; do
+  if [ ! -d $SETUP_DB_PATH/$PKG_DB_DIR ]; then
+    rm -rf $SETUP_DB_PATH/$PKG_DB_DIR # make sure it's not a link
+    mkdir -p $SETUP_DB_PATH/$PKG_DB_DIR
+    chmod 755 $SETUP_DB_PATH/$PKG_DB_DIR
+  fi
+done
+
+REMOVED_PKG_DB_PATH=$SETUP_DB_PATH/removed_packages
+LOG_PATH=$SETUP_DB_PATH/setup
+LOG_FILE=$LOG_PATH/setup.log
+
+file_counter=0
+check_files() {
+  while read FILE ; do
+    if [ ! -d "${TARGET_ROOT_PATH}$FILE" ]; then
+      if [ ! -r "${TARGET_ROOT_PATH}$FILE" ]; then
+        let file_counter+=1
+        if [ ! "$DARK" = "yes" -a "$PRINTLIST" = "yes" ];then
+          echo " ===> ${TARGET_ROOT_PATH}$FILE no longer exists."
+        fi
+      fi
+    fi
+  done
+}
+
+link_counter=0
+check_links() {
+  while read LINK ; do
+    if [ ! -L "${TARGET_ROOT_PATH}$LINK" ]; then
+      let link_counter+=1
+      if [ ! "$DARK" = "yes" -a "$PRINTLIST" = "yes" ];then
+        echo " ===> ${TARGET_ROOT_PATH}$LINK (symlink) no longer exists."
+      fi
+    fi
+  done
+}
+
+
+################################################################
+# Main:
+#
+PKGFILE=$1
+
+log_is_restored=0
+
+# Simple package integrity check:
+if [ ! -f $PKGFILE ]; then
+  EXITSTATUS=4
+  echo "ERROR: $PKGFILE: is not a regular file"
+  exit $EXITSTATUS
+fi
+
+pkgfile_name="`basename $PKGFILE`"
+pkgfile_noext_name="`basename $PKGFILE .txz`"
+pkgfile_src_dir="`dirname $PKGFILE`"
+
+if [ "$pkgfile_name" = "$pkgfile_noext_name" ]; then
+  logfile="$PKGFILE"
+  tarball=""
+else
+  logfile=""
+  tarball="$PKGFILE"
+fi
+
+# getting .PKGINFO file:
+if [ ! "$logfile" = "" ]; then
+  pkginfo --dest $TMP pkginfo $logfile
+  if [ ! -f $TMP/.PKGINFO -o ! -s $TMP/.PKGINFO ]; then
+    rm -f $TMP/.PKGINFO
+    echo "ERROR: There is no package info in $1"
+    EXITSTATUS=2
+    exit $EXITSTATUS
+  fi
+elif [ ! "$tarball" = "" ]; then
+  tarball_pkginfo $tarball
+  if [ ! -f $TMP/.PKGINFO -o ! -s $TMP/.PKGINFO ]; then
+    rm -f $TMP/.PKGINFO
+    echo "ERROR: There is no package info in $1"
+    EXITSTATUS=2
+    exit $EXITSTATUS
+  fi
+fi
+
+if [ -f $TMP/.PKGINFO ]; then
+  . $TMP/.PKGINFO
+  # check variables:
+  if [ "$pkgname" = "" -o "$pkgver" = "" -o "$arch" = "" -o "$distroname" = "" -o "$distrover" = "" ]; then
+    echo "ERROR: The file '.PKGINFO' doesn't contain necessary declarations."
+    EXITSTATUS=11
+    exit $EXITSTATUS 
+  fi
+fi
+rm -f $TMP/.PKGINFO
+
+# check installed pkglog file:
+if [ ! -f $PKG_DB_PATH/$pkgname-$pkgver-$arch-$distroname-$distrover ]; then
+  if [ ! "$tarball" = "" ]; then
+    # try to create new logfile from pkg tarball in the current directory.
+    xzcat $tarball | $TAR -C $TMP -xf - .PKGINFO .INSTALL .FILELIST .REQUIRES .DESCRIPTION .RESTORELINKS  2> /dev/null
+    # do not check ret code because not all of .* files should be present in tarball
+    if [ -f "$TMP/.PKGINFO" ]; then
+      pkglog $TMP/.PKGINFO $TMP > /dev/null 2>&1
+    fi
+    rm -f $TMP/.PKGINFO $TMP/.INSTALL $TMP/.FILELIST $TMP/.REQUIRES $TMP/.DESCRIPTION $TMP/.RESTORELINKS
+    if [ -f $TMP/$pkgname-$pkgver-$arch-$distroname-$distrover ]; then
+      mv -f $TMP/$pkgname-$pkgver-$arch-$distroname-$distrover $PKG_DB_PATH
+      log_is_restored=1
+    else
+      echo "ERROR: The '$PKG_DB_PATH/$pkgname-$pkgver-$arch-$distroname-$distrover' file cannot be restored."
+      EXITSTATUS=26
+      exit $EXITSTATUS
+    fi
+  elif [ ! "$logfile" = "" ]; then
+    if [ ! "$logfile" = "$pkgname-$pkgver-$arch-$distroname-$distrover" ]; then
+      cp -f $logfile $PKG_DB_PATH/$pkgname-$pkgver-$arch-$distroname-$distrover
+    else
+      cp -f $logfile $PKG_DB_PATH
+    fi
+    log_is_restored=1
+  else
+    echo "ERROR: The '$PKG_DB_PATH/$pkgname-$pkgver-$arch-$distroname-$distrover' file cannot be restored."
+    EXITSTATUS=26
+    exit $EXITSTATUS
+  fi
+fi
+# So continue with logfile
+logfile=$PKG_DB_PATH/$pkgname-$pkgver-$arch-$distroname-$distrover
+
+# Checking process:
+echo -n "[`LANG=en LANGUAGE=en date +'%d-%b-%Y %H:%M:%S'`] " >> $LOG_FILE
+echo -n "Checking: `basename $logfile`: "                    >> $LOG_FILE
+
+# Getting saved links:
+pkginfo --dest $TMP restore_links $logfile
+if [ ! -f $TMP/.RESTORELINKS -o ! -s $TMP/.RESTORELINKS ]; then
+  rm -f $TMP/.RESTORELINKS
+else
+  cat $TMP/.RESTORELINKS | extract_links | sort -u > $TMP/links$$
+  rm -f $TMP/.RESTORELINKS
+fi
+# Getting files:
+pkginfo --dest $TMP filelist $logfile
+if [ ! -f $TMP/.FILELIST -o ! -s $TMP/.FILELIST ]; then
+  rm -f $TMP/.FILELIST
+else
+  cat $TMP/.FILELIST | sort -u > $TMP/files$$
+  rm -f $TMP/.FILELIST
+fi
+
+pkginfo --dest $TMP description $logfile
+strip_description "$TMP/.DESCRIPTION" "$TMP/msg$$"
+rm -f $TMP/.DESCRIPTION
+
+echo " Uncompressed Size: $uncompressed_size" >> $TMP/msg$$
+echo "       Total Files: $total_files"       >> $TMP/msg$$
+
+if [ ! "$DARK" = "yes" ];then
+  echo ""
+  echo "Checking package $pkgname... "
+  ####  |---handy-ruler--------------------------------------------------------|
+  echo "|======================================================================|"
+  echo "`cat $TMP/msg$$`"
+  echo "|======================================================================|"
+  echo ""
+fi
+rm -f $TMP/msg$$
+
+not_installed=0
+
+if [ -f $TMP/links$$ -a -s $TMP/links$$ ]; then
+  link_counter=0
+  line_counter=`sed -n "$=" $TMP/links$$`
+  check_links < $TMP/links$$
+  if [ ! "$link_counter" = "0" ] ; then
+    if [ $link_counter -lt $line_counter ] ; then
+      # not correct
+      if [ ! "$DARK" = "yes" ] ; then
+        echo " ERROR: There {is|are} $link_counter not resolved symbolic link[s]."
+        echo ""
+      fi
+    else
+      # not installed
+      let not_installed+=1
+    fi
+  fi
+fi
+rm -f $TMP/links$$
+
+if [ -f $TMP/files$$ -a -s $TMP/files$$ ]; then
+  file_counter=0
+  line_counter=`sed -n "$=" $TMP/files$$`
+  check_files < $TMP/files$$
+  if [ ! "$file_counter" = "0" ] ; then
+    if [ $file_counter -lt $line_counter ] ; then
+      # not correct
+      if [ ! "$DARK" = "yes" ] ; then
+        echo " ERROR: There {is|are} $file_counter not resolved file[s]."
+        echo ""
+      fi
+    else
+      # not installed
+      let not_installed+=1
+    fi
+  fi
+fi
+rm -f $TMP/files$$
+
+if [ ! "$link_counter" = "0" -o ! "$file_counter" = "0" ]; then
+  if [ $not_installed -lt 1 ]; then
+    # leave restored log if pakage installed not correctly
+    if [ ! "$DARK" = "yes" ];then
+      echo " ERROR: Package is istalled but not correct."
+      echo ""
+    fi
+    echo "ERROR: Package is istalled but not correct." >> $LOG_FILE
+    EXITSTATUS=32
+  else
+    # rmove restored log if package is not correct or not installed
+    if [ ! "$log_is_restored" = "0" ]; then
+      rm -f $logfile
+    fi
+    if [ ! "$DARK" = "yes" ];then
+      echo " SUCCESS: Package is not installed."
+      echo ""
+    fi
+    echo "SUCCESS: Package is not installed." >> $LOG_FILE
+    EXITSTATUS=31
+  fi
+else
+  # leave restored log if pakage installed correctly
+  if [ ! "$DARK" = "yes" ];then
+    echo " SUCCESS: Package is installed correctly."
+    echo ""
+  fi
+  echo "SUCCESS: Package is installed correctly." >> $LOG_FILE
+  EXITSTATUS=30
+fi
+#
+# End of Main loop.
+################################################################
+
+exit $EXITSTATUS
Index: build-system-1.2.3/pkgtool/check-requires.in
===================================================================
--- build-system-1.2.3/pkgtool/check-requires.in	(nonexistent)
+++ build-system-1.2.3/pkgtool/check-requires.in	(revision 231)
@@ -0,0 +1,285 @@
+#!/bin/sh
+
+TAR=tar
+
+# program name:
+program=`basename $0`
+
+#  1 = tar returned error code (or caannot get .REQUIRES file)
+#  2 = failed read package info
+#  4 = not a file
+# 16 = root path has not specified arter --root option
+# 17 = exit if called with no arguments
+# 24 = {Setup | Package} database directory doesn't exist.
+# 92 = Cannot create '/tmp/...' directory
+EXITSTATUS=0
+
+CWD=`pwd`
+
+umask 022
+if [ ! -z "$TMPDIR" ] ; then mkdir -p $TMPDIR ; fi
+TMP=$(mkdir -p /tmp/radix && mktemp -d -p /tmp/radix pkgtool.XXXXXXXX) || { echo "Cannot create '/tmp/...' directory" ; exit 92; }
+trap "rm -rf $TMP" EXIT
+
+
+usage() {
+ cat << EOF
+
+Usage: $program [options] {package_tarball | instll_log_file}
+
+$program is used to determine which packages are required for this package:
+   $program /pkgsdir/_kxLibc-1.0.4-x86_64-glibc-radix-1.0.txz  1>humanreadable 2>formatted
+   $program /SETUP_DB_PATH/packages/_kxLibc-1.0.4-x86_64-glibc-radix-1.0
+
+options:
+   --root /dest - root path to finding packaged database
+                  Note that 'path' should be absolute, like '/dest';
+
+stderr (format):
+   pkgname:reqver:ERRCODE
+where:
+   pkgname - required package name;
+   reqver  - required version;
+   ERRCODE - {OLD | NOTINSTALLED}
+                    ------------
+                    NOTINSTALLED - the required package is not installed,
+              ---
+              OLD                - the required package is installed but too old.
+
+stdout is human readable.
+
+EOF
+}
+
+
+tarball_requires() {
+  xzcat $1 | $TAR -xvf - ".REQUIRES" -O  1> $TMP/.REQUIRES  2> /dev/null
+  if [ ! "$?" = "0" ]; then
+    echo "ERROR: Cannot extract package requires from $1"
+    EXITSTATUS=1
+    exit $EXITSTATUS
+  fi
+}
+
+
+#
+# Compare two VERSION present in X.X.X.X format, where X - is a number
+# ====================================================================
+#
+# RETURNS: 0 if '='; 1 if '>'; 2 if '<';
+#
+# Trailing symbols are compared (lexicographically) if versions are equal.
+#
+vcmp() {
+  local v1=`echo $1 | sed 's/\([0-9.]*\)\([-a-zA-Z].*\)/\1/'`
+  local t1=`echo $1 | sed 's/\([0-9.]*\)\([-a-zA-Z].*\)/\2/'`
+  local v2=`echo $2 | sed 's/\([0-9.]*\)\([-a-zA-Z].*\)/\1/'`
+  local t2=`echo $2 | sed 's/\([0-9.]*\)\([-a-zA-Z].*\)/\2/'`
+  if [[ $v1 == $v2 ]] ; then
+    if [ "$t1" = "$t2" ] ; then
+      echo "="
+      return 0
+    fi
+    if [ "$t1" \< "$t2" ] ; then
+      echo "<"
+      return 2
+    fi
+    if [ "$t1" \> "$t2" ] ; then
+      echo ">"
+      return 1
+    fi
+  fi
+  local IFS=.
+  local i ver1=($v1) ver2=($v2)
+  # fill empty fields in ver1 with zeros
+  for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)) ; do
+    ver1[i]=0
+  done
+  for ((i=0; i<${#ver1[@]}; i++)) ; do
+    if [[ -z ${ver2[i]} ]]
+    then
+      # fill empty fields in ver2 with zeros
+      ver2[i]=0
+    fi
+    if ((10#${ver1[i]} > 10#${ver2[i]}))
+    then
+      echo ">"
+      return 1
+    fi
+    if ((10#${ver1[i]} < 10#${ver2[i]}))
+    then
+      echo "<"
+      return 2
+    fi
+  done
+  echo "="
+  return 0
+}
+
+
+print_candidates() {
+  local path=$1
+  local pkgname=$2
+
+  local maxver=0
+
+  local list=
+  local li=`find $path -type f -name "$pkgname-[0-9]*" | sed "s/$pkgname-\([0-9.]*\)[-a-zA-Z].*/\1/"`
+  for l in $li ; do
+    list="$list `basename $l`"
+  done
+  for ver in $list ; do
+    if [ "`vcmp $maxver $ver`" = "<" ] ; then
+      maxver=$ver
+    fi
+  done
+
+  local rlist=
+  for f in `find $path -type f -name "$pkgname-$maxver*" | sort -r` ; do
+    rlist="$rlist $f"
+  done
+
+  echo "$rlist"
+}
+
+
+#
+# Parse options:
+#
+while [ 0 ]; do
+  if [ "$1" = "-h" -o "$1" = "--help" ]; then
+    usage
+    exit 0
+  elif [ "$1" = "--root" ]; then
+    if [ "$2" = "" ]; then
+      usage
+      echo "ERROR: Target root path has not specified. Check --root option."
+      EXITSTATUS=16
+      exit $EXITSTATUS
+    fi
+    TARGET_ROOT_PATH="$2"
+    shift 2
+  else
+    break
+  fi
+done
+
+#
+# usage(), exit if called with no arguments:
+#
+if [ $# = 0 ]; then
+  usage
+  echo "ERROR: arguments were not specified. Check options."
+  EXITSTATUS=17
+  exit $EXITSTATUS
+fi
+
+if [ "$TARGET_ROOT_PATH" = "" ]; then
+  TARGET_ROOT_PATH="/"
+else
+  TARGET_ROOT_PATH="`echo "$TARGET_ROOT_PATH" | sed -e "s/\/$//"`/"
+fi
+
+SETUP_DB_PATH=${TARGET_ROOT_PATH}var/log/@DISTRO@
+if [ ! -d $SETUP_DB_PATH ]; then
+  echo "ERROR: Setup database directory doesn't exist."
+  EXITSTATUS=24
+  exit $EXITSTATUS
+fi
+
+PKG_DB_PATH=$SETUP_DB_PATH/packages
+if [ ! -d $PKG_DB_PATH ]; then
+  echo "ERROR: Packages database directory doesn't exist."
+  EXITSTATUS=24
+  exit $EXITSTATUS
+fi
+
+
+################################################################
+# Main loop:
+#
+PKGFILE=$1
+
+# Simple package integrity check:
+if [ ! -f $PKGFILE ]; then
+  EXITSTATUS=4
+  echo "ERROR: $PKGFILE: is not a regular file"
+  exit $EXITSTATUS
+fi
+
+pkgfile_name="`basename $PKGFILE`"
+pkgfile_noext_name="`basename $PKGFILE .txz`"
+pkgfile_src_dir="`dirname $PKGFILE`"
+
+if [ "$pkgfile_name" = "$pkgfile_noext_name" ]; then
+  logfile="$PKGFILE"
+  tarball=""
+else
+  logfile=""
+  tarball="$PKGFILE"
+fi
+
+# getting .REQUIRES file:
+if [ ! "$logfile" = "" ]; then
+  pkginfo --dest $TMP requires $logfile
+  if [ ! -f $TMP/.REQUIRES -o ! -s $TMP/.REQUIRES ]; then
+    rm -f $TMP/.REQUIRES
+    exit 1
+  fi
+elif [ ! "$tarball" = "" ]; then
+  tarball_requires $tarball
+  if [ ! -f $TMP/.REQUIRES -o ! -s $TMP/.REQUIRES ]; then
+    rm -f $TMP/.REQUIRES
+    exit 1
+  fi
+fi
+
+echo ""
+echo "Requires of `basename $PKGFILE`:"
+echo ""
+
+# read lines:
+LINENUMS=`sed -n "$=" $TMP/.REQUIRES`
+LINENUM_REQ=1
+while [ "$LINENUM_REQ" -le "$LINENUMS" ]; do
+  LINE="`sed -n "$LINENUM_REQ p" $TMP/.REQUIRES`"
+  let LINENUM_REQ+=1
+  reqname=`echo "$LINE" | cut -f 1 -d '='`
+  reqver=`echo "$LINE" | cut -f 2 -d '='`
+  if [ ! -z "$reqname" ]; then
+    if [ "`find $PKG_DB_PATH -type f -name "$reqname-[0-9.]*"`" = "" ]; then
+      echo "$reqname:$reqver:NOTINSTALLED" >&2
+      echo "Package '$reqname' version: $reqver: Is not installed."
+    fi
+    for reqfile in `print_candidates $PKG_DB_PATH $reqname` ; do
+      pkginfo --dest $TMP pkginfo $reqfile
+      if [ -f "$TMP/.PKGINFO" ]; then
+        unset pkgname
+        unset pkgver
+
+        . $TMP/.PKGINFO
+
+        if [ "`vcmp $pkgver $reqver`" = "=" -o "`vcmp $pkgver $reqver`" = ">" ]; then
+          rm -f $TMP/.PKGINFO
+          break
+        elif [ "`vcmp $pkgver $reqver`" = "<" ]; then
+          echo "$pkgname:$reqver:OLD" >&2
+          echo "Package '$pkgname' version: $reqver: Too old."
+        fi
+        rm -f $TMP/.PKGINFO
+      else
+        EXITSTATUS=2
+        echo "$pkgname:$reqver:NOTINSTALLED" >&2
+        echo "Package '$pkgname' version: $reqver: Is not installed."
+      fi
+    done
+  fi
+done
+rm -f $TMP/.REQUIRES
+#
+# End of Main loop.
+################################################################
+echo ""
+
+exit $EXITSTATUS
+
Index: build-system-1.2.3/pkgtool/install-package.in
===================================================================
--- build-system-1.2.3/pkgtool/install-package.in	(nonexistent)
+++ build-system-1.2.3/pkgtool/install-package.in	(revision 231)
@@ -0,0 +1,665 @@
+#!/bin/sh
+: ${DIALOG=dialog}
+
+TAR=tar
+
+# program name:
+program=`basename $0`
+
+#  1 = tar returned error code
+#  2 = failed read package info
+#  3 = does not end in .txz
+#  4 = not a file
+# 11 = broken .PKGINFO
+# 12 = broken .DESCRIPTION
+# 13 = permission denied (should be root)
+# 14 = broken .pkglist or user pkglist
+# 15 = priority has not specified arter --priority option
+# 16 = root path has not specified arter --root option
+# 17 = exit if called with no arguments
+# 19 =  pre install script returns bad status
+# 20 = post install script returns bad status
+# 21 =  pre Remove script returns bad status
+# 22 = post Remove script returns bad status
+# 23 = package is not installed correctly
+# 24 = {Setup | Package} database directory doesn't exist.
+# 25 = There are not resolved requires
+# 92 = Cannot create '/tmp/...' directory
+# 99 = user abort from menu mode
+EXITSTATUS=0
+
+CWD=`pwd`
+
+#
+# The system TMP directory can be changed by TMPDIR variable:
+# ----------------------------------------------------------
+#  - If TMPDIR is not set then following command creates /tmp/radix/pkgtool.XXXXXXXX directories;
+#  - if TMPDIR is defined then following command creates $TMPDIR/pkgtool.XXXXXXXX directories.
+#
+umask 002
+if [ ! -z "$TMPDIR" ] ; then mkdir -p $TMPDIR ; fi
+TMP=$(mkdir -p /tmp/radix && mktemp -d -p /tmp/radix pkgtool.XXXXXXXX) || { echo "Cannot create '/tmp/...' directory" ; exit 92; }
+trap "rm -rf $TMP" EXIT
+
+
+usage() {
+ cat << EOF
+
+Usage: $program [options] package_tarball[s]
+
+$program is used to install a *.txz package like this:
+   $program /packagesdir/pkgtool-0.0.1-x86_64-glibc-radix-1.0.txz
+
+options:
+   --root /dest    - install someplace else, like /dest;
+   --skip-requires - skip checking required packages;
+   --infodialog    - use dialog to draw an info box;
+   --menudialog    - confirm package installation with a menu, unless
+                     the priority is [required];
+   --always-ask    - used with menudialog mode: always ask if a package should be
+                     installed regardless of what the package's priority is;
+   --priority {required|recommended|optional|skip} -
+                     provide a priority for the entire package list
+                     to use instead of the priority in the .pkglist file;
+   --pkglist /path/file -
+                     specify a different file to use for package priorities.
+                     The default is ".pkglist" in the package's directory.
+
+EOF
+}
+
+package_info() {
+  xzcat $1 | $TAR -xvf - ".PKGINFO" -O  1> $TMP/pkginfo$$  2> /dev/null
+  if [ ! "$?" = "0" ]; then
+    echo "ERROR: Cannot extract package info from $1"
+    EXITSTATUS=1
+    exit $EXITSTATUS
+  fi
+  if [ -f "$TMP/pkginfo$$" ]; then
+    . $TMP/pkginfo$$
+    # check variables:
+    if [ "$pkgname" = "" -o "$pkgver" = "" -o "$arch" = "" -o "$distroname" = "" -o "$distrover" = "" ]; then
+      echo "ERROR: The file '.PKGINFO' doesn't contain necessary declarations."
+      EXITSTATUS=11
+      exit $EXITSTATUS
+    fi
+  else
+    echo "ERROR: There is no package info in $1"
+    EXITSTATUS=2
+    exit $EXITSTATUS
+  fi
+  rm -f $TMP/pkginfo$$
+  compressed_size=$(du -s -h "$1" | sed 's/[\t].*$//')
+}
+
+package_description() {
+  # do not forget to remove $TMP/description$$ after using.
+  xzcat $1 | $TAR -xvf - ".DESCRIPTION" -O  1> $TMP/description$$  2> /dev/null
+  if [ ! "$?" = "0" ]; then
+    echo "ERROR: Cannot extract package description from $1"
+    EXITSTATUS=1
+    exit $EXITSTATUS
+  fi
+  if [ -f "$TMP/description$$" ]; then
+    if [ ! -s "$TMP/description$$" ]; then
+      echo "ERROR: The file '.DESCRIPTION' doesn't contain necessary information."
+      EXITSTATUS=11
+      exit $EXITSTATUS 
+    fi
+  else
+    echo "ERROR: There is no package description in $1"
+    EXITSTATUS=2
+    exit $EXITSTATUS
+  fi
+}
+
+strip_description() {
+  infile=$1
+  outfile=$2
+  echo " " > $outfile
+  LINENUMS="`cat $infile | grep -n -e "^$pkgname:" | cut -f 1 -d ':'`"
+  if [ "$LINENUMS" = "" ]; then
+    echo "WARNING: Description is empty or corrupted."
+    return
+  fi
+  for LINENUM in $LINENUMS ; do
+    LINE="`sed -n "$LINENUM p" $infile | sed -e "s/^$pkgname://"`"
+    if [ "$LINE" = "" ]; then
+       LINE=" "
+    else
+       LINE="`echo "$LINE" | sed -e "s/ $//g"`"
+    fi
+    echo "$LINE" >> $outfile
+  done
+}
+
+
+pkglist_get_priority() {
+  listfile=$1
+  # check only first accurence in this procedure
+  LINENUM="`cat $listfile | grep -m 1 -n -e "^$pkgname:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM" = "" ]; then
+    ret=""
+    return 1
+  fi
+  LINE="`sed -n "$LINENUM p" $listfile`"
+  ret="`echo "$LINE" | cut -f 6 -d ':'`"
+  if   [ "$ret" = "required"    -o "$ret" = "req" -o "$ret" = "REQUIRED"    -o "$ret" = "REQ" ]; then
+    ret="REQUIRED"
+  elif [ "$ret" = "recommended" -o "$ret" = "rec" -o "$ret" = "RECOMMENDED" -o "$ret" = "REC" ]; then
+    ret="RECOMMENDED"
+  elif [ "$ret" = "optional"    -o "$ret" = "opt" -o "$ret" = "OPTIONAL"    -o "$ret" = "OPT" ]; then
+    ret="OPTIONAL"
+  elif [ "$ret" = "skip"        -o "$ret" = "skp" -o "$ret" = "SKIP"        -o "$ret" = "SKP" ]; then
+    ret="SKIP"
+  fi
+  if [ ! "$ret" = "REQUIRED" -a ! "$ret" = "RECOMMENDED" -a ! "$ret" = "OPTIONAL" -a ! "$ret" = "SKIP" ]; then
+    ret=""
+    return 1
+  fi
+  return 0
+}
+
+
+
+#
+# Parse options:
+#
+MODE=console # standard text-mode
+while [ 0 ]; do
+  if [ "$1" = "-h" -o "$1" = "--help" ]; then
+    usage
+    exit 0
+  elif [ "$1" = "--skip-requires" ]; then
+    SKIPREQUIRES="yes"
+    shift 1
+  elif [ "$1" = "--infodialog" ]; then
+    MODE=infodialog
+    shift 1
+  elif [ "$1" = "--menudialog" ]; then
+    MODE=menudialog
+    shift 1
+  elif [ "$1" = "--always-ask" ]; then
+    ALWAYSASK="yes"
+    shift 1
+  elif [ "$1" = "--pkglist" ]; then
+    if [ -r "$2" ]; then
+      USERPKGLIST="$2"
+    elif [ -r "$CWD/$2" ]; then
+      USERPKGLIST="$CWD/$2"
+    else
+      usage
+      echo "ERROR: Wrong pkglist file. Check --pkglist option."
+      EXITSTATUS=14
+      exit $EXITSTATUS
+    fi
+    shift 2
+  elif [ "$1" = "--priority" ]; then
+    if [ "$2" = "" ]; then
+      usage
+      echo "ERROR: Priority has not specified. Check --priority option."
+      EXITSTATUS=15
+      exit $EXITSTATUS
+    fi
+    USERPRIORITY="$2"
+    if   [ "$USERPRIORITY" = "required"    -o "$USERPRIORITY" = "req" -o "$USERPRIORITY" = "REQUIRED"    -o "$USERPRIORITY" = "REQ" ]; then
+      USERPRIORITY="REQUIRED"
+    elif [ "$USERPRIORITY" = "recommended" -o "$USERPRIORITY" = "rec" -o "$USERPRIORITY" = "RECOMMENDED" -o "$USERPRIORITY" = "REC" ]; then
+      USERPRIORITY="RECOMMENDED"
+    elif [ "$USERPRIORITY" = "optional"    -o "$USERPRIORITY" = "opt" -o "$USERPRIORITY" = "OPTIONAL"    -o "$USERPRIORITY" = "OPT" ]; then
+      USERPRIORITY="OPTIONAL"
+    elif [ "$USERPRIORITY" = "skip"        -o "$USERPRIORITY" = "skp" -o "$USERPRIORITY" = "SKIP"        -o "$USERPRIORITY" = "SKP" ]; then
+      USERPRIORITY="SKIP"
+    fi
+    if [ ! "$USERPRIORITY" = "REQUIRED" -a ! "$USERPRIORITY" = "RECOMMENDED" -a ! "$USERPRIORITY" = "OPTIONAL" -a ! "$USERPRIORITY" = "SKIP" ]; then
+      usage
+      echo "ERROR: Invalid priority. Check --priority option."
+      EXITSTATUS=15
+      exit $EXITSTATUS
+    fi
+    shift 2
+  elif [ "$1" = "--root" ]; then
+    if [ "$2" = "" ]; then
+      usage
+      echo "ERROR: Target root path has not specified. Check --root option."
+      EXITSTATUS=16
+      exit $EXITSTATUS
+    fi
+    TARGET_ROOT_PATH="$2"
+    shift 2
+  else
+    break
+  fi
+done
+
+#
+# usage(), exit if called with no arguments:
+#
+if [ $# = 0 ]; then
+  usage
+  echo "ERROR: arguments were not specified. Check options."
+  EXITSTATUS=17
+  exit $EXITSTATUS
+fi
+
+if [ "$TARGET_ROOT_PATH" = "" ]; then
+  TARGET_ROOT_PATH="/"
+else
+  TARGET_ROOT_PATH="`echo "$TARGET_ROOT_PATH" | sed -e "s/\/$//"`/"
+fi
+
+if [ "$TARGET_ROOT_PATH" = "/" ]; then
+  if [ ! $UID = "0" ]; then
+    echo "ERROR: Trying to install into root directory: permission denied"
+    EXITSTATUS=13
+    exit $EXITSTATUS
+  fi
+fi
+
+SETUP_DB_PATH=${TARGET_ROOT_PATH}var/log/@DISTRO@
+if [ ! -d $SETUP_DB_PATH ]; then
+  rm -rf $SETUP_DB_PATH # make sure it's not a link
+  mkdir -p $SETUP_DB_PATH
+  chmod 755 $SETUP_DB_PATH
+fi
+
+for PKG_DB_DIR in packages removed_packages setup ; do
+  if [ ! -d $SETUP_DB_PATH/$PKG_DB_DIR ]; then
+    rm -rf $SETUP_DB_PATH/$PKG_DB_DIR # make sure it's not a link
+    mkdir -p $SETUP_DB_PATH/$PKG_DB_DIR
+    chmod 755 $SETUP_DB_PATH/$PKG_DB_DIR
+  fi
+done
+
+LOG_PATH=$SETUP_DB_PATH/setup
+LOG_FILE=$LOG_PATH/setup.log
+
+
+extract_links() {
+ sed -n 's,^( *cd \([^ ;][^ ;]*\) *; *rm -rf \([^ )][^ )]*\) *) *$,\1/\2,p'
+}
+
+delete_files() {
+  while read FILE ; do
+    if [ ! -d "${TARGET_ROOT_PATH}$FILE" ]; then
+      if [ -r "${TARGET_ROOT_PATH}$FILE" ]; then
+        # "-nt" is "newer than"; "-ot" is "older than":
+        if [ "${TARGET_ROOT_PATH}$FILE" -nt "$logfile" ]; then
+          if [ "$VERBOSE" == "yes" ] ; then
+            echo "WARNING: ${TARGET_ROOT_PATH}$FILE changed after package installation."
+          fi
+        fi
+        if [ "$VERBOSE" == "yes" ] ; then
+          echo " ===> Deleting ${TARGET_ROOT_PATH}$FILE"
+        fi
+        rm -f "${TARGET_ROOT_PATH}$FILE"
+        echo "`dirname $FILE`" >> $TMP/not_sorted_dirs$$
+      else
+        echo " ===> ${TARGET_ROOT_PATH}$FILE no longer exists. Skipping."
+      fi
+    else
+      if [ "$VERBOSE" == "yes" ] ; then
+        echo " ===> ${TARGET_ROOT_PATH}$FILE is a directory. Skipping."
+      fi
+      echo "$FILE" >> $TMP/not_sorted_dirs$$
+    fi
+  done
+}
+
+delete_links() {
+  while read LINK ; do
+    if [ -L "${TARGET_ROOT_PATH}$LINK" ]; then
+      if [ "$VERBOSE" == "yes" ] ; then
+        echo " ===> Deleting symlink ${TARGET_ROOT_PATH}$LINK"
+      fi
+      rm -f ${TARGET_ROOT_PATH}$LINK
+      echo "`dirname $LINK`" >> $TMP/not_sorted_dirs$$
+    else
+      if [ "$VERBOSE" == "yes" ] ; then
+        echo " ===> ${TARGET_ROOT_PATH}$LINK (symlink) no longer exists. Skipping."
+      fi
+    fi
+  done
+}
+
+delete_dirs() {
+  while read DIR ; do
+    if [ -d "${TARGET_ROOT_PATH}$DIR" ]; then
+      if [ `ls -a "${TARGET_ROOT_PATH}$DIR" | wc -l` -eq 2 ]; then
+        if [ "$VERBOSE" == "yes" ] ; then
+          echo " ===> Deleting empty directory ${TARGET_ROOT_PATH}$DIR"
+        fi
+        rmdir "${TARGET_ROOT_PATH}$DIR"
+      else
+        if [ "$VERBOSE" == "yes" ] ; then
+          echo " ===> Preserving non empty directory ${TARGET_ROOT_PATH}$DIR"
+        fi
+      fi
+    fi
+  done
+}
+
+
+remove_installed_files_on_error() {
+  if [ -f $TMP/.RESTORELINKS -a -s $TMP/.RESTORELINKS ]; then
+    cat $TMP/.RESTORELINKS | extract_links | sort -u > $TMP/links$$
+  fi
+
+  if [ -f $TMP/.FILELIST -a -s $TMP/.FILELIST ]; then
+    cat $TMP/.FILELIST | sort -u > $TMP/files$$
+  fi
+
+  rm -f $TMP/not_sorted_dirs$$
+  if [ -f $TMP/links$$ -a -s $TMP/links$$ ]; then
+    delete_links < $TMP/links$$
+  fi
+  rm -f $TMP/links$$
+
+  if [ -f $TMP/files$$ -a -s $TMP/files$$ ]; then
+    delete_files < $TMP/files$$
+  fi
+  rm -f $TMP/files$$
+
+  if [ -f $TMP/not_sorted_dirs$$ -a -s $TMP/not_sorted_dirs$$ ]; then
+    sort -u -r < $TMP/not_sorted_dirs$$ > $TMP/dirs$$
+    rm -f $TMP/not_sorted_dirs$$
+    delete_dirs < $TMP/dirs$$
+    rm -f $TMP/dirs$$
+  fi
+  rm -f $TMP/not_sorted_dirs$$
+}
+
+################################################################
+# Main loop:
+#
+for pkgtarball in $* ; do
+  # If someone left off the '.txz', try to figure that out:
+  if [ ! -r "$pkgtarball" -a -r "$pkgtarball.txz" ]; then
+    pkgtarball=$pkgtarball.txz
+  fi
+
+  tarball_noext_name="`basename $pkgtarball .txz`"
+  tarball_src_dir="`dirname $pkgtarball`"
+
+  # Reject package if it does not end in '.txz':
+  if [ ! -r "$tarball_src_dir/$tarball_noext_name.txz" ]; then
+    EXITSTATUS=3
+    if [ "$MODE" = "console" ]; then
+      echo "ERROR: Cannot install $pkgtarball: tarball does not end in .txz"
+    fi
+    continue;
+  fi
+
+  # Simple package integrity check:
+  if [ ! -f $pkgtarball ]; then
+    EXITSTATUS=4
+    if [ "$MODE" = "console" ]; then
+      echo "ERROR: Cannot install $pkgtarball: tarball is not a regular file"
+    fi
+    continue;
+  fi
+
+  # getting pkgname, etc... variables from tarball:
+  package_info $pkgtarball
+
+  # Determine package's priority:
+  unset PRIORITY
+  if [ "$USERPKGLIST" = "" ]; then
+    PKGLIST="$tarball_src_dir/.pkglist"
+  else
+    PKGLIST="$USERPKGLIST"
+  fi
+  if [ ! -r "$PKGLIST" ]; then
+    PKGLIST=/dev/null
+  fi
+
+  # USERPRIORITY overrides .pkglist priority
+  if [ "$USERPRIORITY" = "" ]; then
+    pkglist_get_priority "$PKGLIST"
+    PRIORITY=$ret
+  else
+    PRIORITY=$USERPRIORITY
+  fi
+
+  if   [ "$PRIORITY" = "REQUIRED" ]; then
+    PMSG="[required]"
+  elif [ "$PRIORITY" = "RECOMMENDED" ]; then
+    PMSG="[recommended]"
+  elif [ "$PRIORITY" = "OPTIONAL" ]; then
+    PMSG="[optional]"
+  elif [ "$PRIORITY" = "SKIP" ]; then
+    PMSG="[skip]"
+  else
+    PMSG=""
+  fi
+
+  package_description $pkgtarball
+  strip_description "$TMP/description$$" "$TMP/msg$$"
+  rm -f $TMP/description$$
+
+  echo " Uncompressed Size: $uncompressed_size" >> $TMP/msg$$
+  echo "   Compressed Size: $compressed_size"   >> $TMP/msg$$
+
+  # Emit information to the console:
+  if [ "$MODE" = "console" -a ! "$PRIORITY" = "SKIP" ]; then
+    echo ""
+    if [ "$PMSG" = "" ]; then
+      echo " Installing package $pkgname... "
+    else
+      echo " Installing package $pkgname $PMSG... "
+    fi
+    ####  |---handy-ruler--------------------------------------------------------|
+    echo "|======================================================================|"
+    echo "`cat $TMP/msg$$`"
+    echo "|======================================================================|"
+    echo ""
+  elif [ "$MODE" = "infodialog" -a ! "$PRIORITY" = "SKIP" ]; then
+    # install non-SKIP package:
+    $DIALOG --colors \
+            --backtitle "\Z7Radix\Zn \Z1Pro\Zn\Z7, Ltd.\Zn" \
+            --title " \Z4Installing package ==>\Zn\Z1$pkgname\Zn\Z4<== $PMSG\Zn " \
+            --infobox "`cat $TMP/msg$$`" 16 74
+  elif [ "$MODE" = "menudialog" -a "$PRIORITY" = "REQUIRED" -a ! "$ALWAYSASK" = "yes" ]; then
+    # REQUIRED overrides menu mode unless -ask was used
+    $DIALOG --colors \
+            --backtitle "\Z7Radix\Zn \Z1Pro\Zn\Z7, Ltd.\Zn" \
+            --title " \Z4Installing package ==>\Zn\Z1$pkgname\Zn\Z4<== $PMSG\Zn " \
+            --infobox "`cat $TMP/msg$$`" 16 74
+  elif [ "$MODE" = "menudialog" -a "$PRIORITY" = "SKIP" -a ! "$ALWAYSASK" = "yes" ]; then
+    # SKIP overrides menu mode unless -ask used
+    rm -f $TMP/msg$$
+    continue # next package
+  elif [ "$MODE" = "infodialog" -a "$PRIORITY" = "SKIP" ]; then
+    # SKIP overrides infobox mode, too
+    rm -f $TMP/msg$$
+    continue # next package
+  elif [ "$MODE" = "console" -a "$PRIORITY" = "SKIP" ]; then
+    # SKIP overrides console mode, too
+    rm -f $TMP/msg$$
+    continue # next package
+  else # we must need a full menu:
+    $DIALOG --colors \
+            --backtitle "\Z7Radix\Zn \Z1Pro\Zn\Z7, Ltd.\Zn" \
+            --title " \Z4Package Name: ==>\Zn\Z1$pkgname\Zn\Z4<== $PMSG\Zn " \
+            --menu "`cat $TMP/msg$$`" 0 0 3 \
+    "Yes" "Install package $pkg_name" \
+    "No" "Do not install package $pkg_name" \
+    "Quit" "Abort software installation completely" 2> $TMP/reply$$
+    if [ ! $? = 0 ]; then
+      echo "No" > $TMP/reply$$
+    fi
+    REPLY="`cat $TMP/reply$$`"
+    rm -f $TMP/reply$$ $TMP/msg$$
+    if [ "$REPLY" = "Quit" ]; then
+      rm -f $TMP/msg$$
+      exit 99 # ABORT!
+    elif [ "$REPLY" = "No" ]; then
+      rm -f $TMP/msg$$
+      continue # skip the package
+    fi
+    # Waiting info dialog
+    $DIALOG --sleep 1 --colors \
+            --backtitle "\Z7Radix\Zn \Z1Pro\Zn\Z7, Ltd.\Zn" \
+            --title " \Z4Installing package ==>\Zn\Z1$pkgname\Zn\Z4<== $PMSG\Zn " \
+            --infobox "\nPlease wait till package is installed.\n" 5 74
+  fi
+  rm -f $TMP/msg$$
+
+  # Check how the package is installed:
+  # ==================================
+  check-package --dark --root $TARGET_ROOT_PATH $pkgtarball
+  ret=$?
+  if [ $ret -eq 30 ]; then
+    # package is installed correctly
+    if [ ! "$MODE" = "console" ]; then
+      $DIALOG --sleep 1 --colors \
+              --backtitle "\Z7Radix\Zn \Z1Pro\Zn\Z7, Ltd.\Zn" \
+              --title " \Z4Installing package ==>\Zn\Z1$pkgname\Zn\Z4<== $PMSG\Zn " \
+              --infobox "\nPackage is already installed and corect.\n" 5 74
+    else
+      echo "Package is already installed and corect."
+    fi
+    continue
+  elif [ $ret -eq 32 ]; then
+    # package is installed but not correct
+    if [ ! "$MODE" = "console" ]; then
+      cat > $TMP/bad_package$$ << EOF
+
+\Z1NOTE:\Zn \Z4Package is already installed but not corect.\Zn
+
+Delete the package using 'remove-package' utility, and then try
+to install again.
+
+EOF
+      $DIALOG --sleep 1 --colors \
+              --backtitle "\Z1Radix\Zn \Z7Pro\Zn\Z1, Ltd.\Zn" \
+              --title " \Z4Installing package ==>\Zn\Z1$pkgname\Zn\Z4<== $PMSG\Zn " \
+              --infobox "`cat $TMP/bad_package$$`" 8 74
+      rm -f $TMP/bad_package$$
+    else
+      echo "Package is already installed but not corect."
+      echo ""
+      echo "Delete the package using 'remove-package' utility, and then try"
+      echo "to install again."
+    fi
+    continue
+  fi
+
+  # Install process:
+  echo -n "[`LANG=en LANGUAGE=en date +'%d-%b-%Y %H:%M:%S'`] " >> $LOG_FILE
+  echo -n "Installing: `basename $pkgtarball`: "               >> $LOG_FILE
+
+  DEST=$TARGET_ROOT_PATH
+
+  # Check requires:
+  # ==============
+  if [ ! "$SKIPREQUIRES" = "yes" ]; then
+    check-requires --root $DEST $pkgtarball 2> $TMP/freqs$$ 1> $TMP/hreqs$$
+    if [ -s $TMP/freqs$$ ]; then
+      echo "ERROR: There are not resolved requires." >> $LOG_FILE
+      if [ "$MODE" = "console" ]; then
+        echo "ERROR: There are not resolved requires."
+        cat $TMP/hreqs$$
+      else
+        cat > $TMP/not_resolved_reqs$$ << EOF
+
+\Z1ERROR:\Zn \Z4There are not resolved requires.\Zn
+
+Check the missing packages using the 'check-requires' utility and,
+if necessary, install them.
+
+EOF
+        $DIALOG --sleep 3 --colors \
+                --backtitle "\Z1Radix\Zn \Z7Pro\Zn\Z1, Ltd.\Zn" \
+                --title " \Z4Installing package ==>\Zn\Z1$pkgname\Zn\Z4<== $PMSG\Zn " \
+                --infobox "`cat $TMP/not_resolved_reqs$$`" 8 74
+        rm -f $TMP/not_resolved_reqs$$
+      fi
+      rm -f $TMP/freqs$$ $TMP/hreqs$$
+      EXITSTATUS=22
+      exit $EXITSTATUS
+    fi
+    rm -f $TMP/freqs$$ $TMP/hreqs$$
+  fi
+
+  # unpack package service files:
+  cat << EOF > $TMP/pkg.service.files$$
+.DESCRIPTION
+.FILELIST
+.INSTALL
+.PKGINFO
+.REQUIRES
+.RESTORELINKS
+EOF
+  xzcat $pkgtarball | $TAR -C $TMP --files-from=$TMP/pkg.service.files$$ -xf -  > /dev/null 2>&1
+  ( cd $DEST
+    if [ -x $TMP/.INSTALL ]; then
+      $TMP/.INSTALL pre_install $pkgver > /dev/null 2>&1
+      if [ ! "$?" = "0" ]; then
+        echo "ERROR: Pre Install script returns bad status."
+        echo "ERROR: Pre Install script returns bad status." >> $LOG_FILE
+        EXITSTATUS=19
+        exit $EXITSTATUS
+      fi
+    fi
+  )
+  EXITSTATUS=$?
+  if [ ! "$EXITSTATUS" = "0" ]; then
+    break
+  fi
+  # unpack archive excluding service files:
+  xzcat $pkgtarball | $TAR -C $DEST --exclude-from=$TMP/pkg.service.files$$ -xpf -  > /dev/null 2>&1
+  if [ ! "$?" = "0" ]; then
+    echo "ERROR: $TAR has returned error code."
+    echo "ERROR: $TAR has returned error code." >> $LOG_FILE
+    EXITSTATUS=1
+    break
+  fi
+  ( cd $DEST
+    if [ -f $TMP/.RESTORELINKS ]; then
+      sh $TMP/.RESTORELINKS
+    fi
+    pkglog $TMP/.PKGINFO $SETUP_DB_PATH/packages  > /dev/null 2>&1
+    if [ ! "$?" = "0" ]; then
+      echo "ERROR: Log file has not been created."
+      echo "ERROR: Log file has not been created." >> $LOG_FILE
+      remove_installed_files_on_error
+      ( . $TMP/.PKGINFO
+        cd $SETUP_DB_PATH/packages; rm -f "$pkgname-$pkgver-$arch-$distroname-$distrover"
+      )
+      EXITSTATUS=23
+      exit $EXITSTATUS
+    fi
+    if [ -x $TMP/.INSTALL ]; then
+      $TMP/.INSTALL post_install $pkgver > /dev/null 2>&1
+      if [ ! "$?" = "0" ]; then
+        echo "ERROR: Post Install script returns bad status."
+        echo "ERROR: Post Install script returns bad status." >> $LOG_FILE
+        remove_installed_files_on_error
+        ( . $TMP/.PKGINFO
+          cd $SETUP_DB_PATH/packages; rm -f "$pkgname-$pkgver-$arch-$distroname-$distrover"
+        )
+        EXITSTATUS=20
+        exit $EXITSTATUS
+      fi
+    fi
+    # Increase REFERENCE COUNTER in the required packages:
+    ( . $TMP/.PKGINFO
+      cd $SETUP_DB_PATH/packages; change-refs inc "$pkgname-$pkgver-$arch-$distroname-$distrover"
+    )
+    # check deprecated log file:
+    ( . $TMP/.PKGINFO
+      cd $SETUP_DB_PATH/removed_packages; rm -f "$pkgname-$pkgver-$arch-$distroname-$distrover"
+    )
+  )
+  EXITSTATUS=$?
+  if [ ! "$EXITSTATUS" = "0" ]; then
+    break
+  fi
+  echo "SUCCESS: Package has been installed." >> $LOG_FILE
+done
+#
+# End of Main loop.
+################################################################
+
+exit $EXITSTATUS
Index: build-system-1.2.3/pkgtool/install-pkglist
===================================================================
--- build-system-1.2.3/pkgtool/install-pkglist	(nonexistent)
+++ build-system-1.2.3/pkgtool/install-pkglist	(revision 231)
@@ -0,0 +1,270 @@
+#!/bin/sh
+: ${DIALOG=dialog}
+
+TAR=tar
+
+# program name:
+program=`basename $0`
+
+# 13 = permission denied (should be root)
+# 14 = there is no '.pkglist' file
+# 16 = root path has not specified arter --root option
+# 92 = Cannot create '/tmp/...' directory
+# 99 = user abort from checklist mode
+EXITSTATUS=0
+
+CWD=`pwd`
+
+umask 002
+if [ ! -z "$TMPDIR" ] ; then mkdir -p $TMPDIR ; fi
+TMP=$(mkdir -p /tmp/radix && mktemp -d -p /tmp/radix pkgtool.XXXXXXXX) || { echo "Cannot create '/tmp/...' directory" ; exit 92; }
+trap "rm -rf $TMP" EXIT
+
+
+usage() {
+ cat << EOF
+
+Usage: cd /pkg_tarballs_dir; $program
+
+$program is used to install the set of packages using using '.pkglist' file
+which placed  in the current directory.  The file '.pkglist' may be created
+by make-pkglist utility.
+
+options:
+   --root /dest    - install someplace else, like /dest .
+   --skip-requires - skip checking required packages;
+
+EOF
+}
+
+
+#
+# Parse options:
+#
+while [ 0 ]; do
+  if [ "$1" = "-h" -o "$1" = "--help" ]; then
+    usage
+    exit 0
+  elif [ "$1" = "--skip-requires" ]; then
+    SKIPREQUIRES="yes"
+    shift 1
+  elif [ "$1" = "--root" ]; then
+    if [ "$2" = "" ]; then
+      usage
+      echo "ERROR: Target root path has not specified. Check --root option."
+      EXITSTATUS=16
+      exit $EXITSTATUS
+    fi
+    TARGET_ROOT_PATH="$2"
+    shift 2
+  else
+    break
+  fi
+done
+
+if [ "$TARGET_ROOT_PATH" = "" ]; then
+  TARGET_ROOT_PATH="/"
+else
+  TARGET_ROOT_PATH="`echo "$TARGET_ROOT_PATH" | sed -e "s/\/$//"`/"
+fi
+
+if [ "$TARGET_ROOT_PATH" = "/" ]; then
+  if [ ! $UID = "0" ]; then
+    echo "ERROR: Trying to install into root directory: permission denied"
+    EXITSTATUS=13
+    exit $EXITSTATUS
+  fi
+fi
+
+if [ ! -f $CWD/.pkglist ]; then
+  echo "ERROR: There is no '.pkglist' file in the current directory."
+  EXITSTATUS=14
+  exit $EXITSTATUS
+else
+  PKGLIST=$CWD/.pkglist
+fi
+
+probe=`find $CWD -name "*.txz" > /dev/null 2>&1`
+if [ ! "$?" = "0" ]; then
+  usage
+  echo "WARNING: There are not package tarballs in current directory."
+  echo ""
+  exit 0
+fi
+
+cat > $TMP/pkglst$$ << EOF
+--colors \\
+--backtitle "\Z7Radix\Zn \Z1Pro\Zn\Z7, Ltd.\Zn" \\
+--title " \Z4SELECTING PACKAGES TO INSTALL\Zn " \\
+--checklist "\\n\\
+Please confirm the packages  you wish to install.  Use the UP/DOWN\\n\\
+keys to scroll through the list, and the SPACE key to deselect any\\n\\
+items you don't want to install.\\n\\n\\
+Press ENTER when you are done." \\
+15 74 3 \\
+EOF
+
+# read lines from '$PKGLIST' file in original order:
+LINENUMS=`sed -n "$=" $PKGLIST`
+LINENUM_REQ=1
+while [ "$LINENUM_REQ" -le "$LINENUMS" ]; do
+  LINE="`sed -n "$LINENUM_REQ p" $PKGLIST`"
+  let LINENUM_REQ+=1
+  if [ ! -z "$LINE" -a -z "`echo $LINE | grep -n -e '^#' | cut -f 1 -d ':'`" ]; then
+    pnam=`echo "$LINE" | cut -f 1 -d ':'`
+    pver=`echo "$LINE" | cut -f 2 -d ':'`
+    pdir=`dirname $(echo "$LINE" | cut -f 4 -d ':')`
+    proc=`echo "$LINE" | cut -f 5 -d ':'`
+    # version    - is used to avoid errors related equal substring in packagenames
+    # packagedir - is used to recognize same packages in different directories
+    if [ ! -z "$pdir" -a "$pdir" != "." ] ; then
+      pkgtarball=`find $CWD/$pdir -name "$pnam-$pver-*.txz"`
+    else
+      pkgtarball=`find $CWD -name "$pdir/$pnam-$pver-*.txz"`
+    fi
+    pkgtarball=`echo $pkgtarball | sed s,$CWD/,,`
+    if [ ! -z "$pnam" -a -f $pkgtarball ]; then
+      desc="`echo $LINE | cut -f 3 -d ':'`"
+      prio="`echo $LINE | cut -f 6 -d ':'`"
+      if   [ "$prio" = "required"    -o "$prio" = "req" -o "$prio" = "REQUIRED"    -o "$prio" = "REQ" ]; then
+        ret="REQUIRED"
+      elif [ "$prio" = "recommended" -o "$prio" = "rec" -o "$prio" = "RECOMMENDED" -o "$prio" = "REC" ]; then
+        ret="RECOMMENDED"
+      elif [ "$prio" = "optional"    -o "$prio" = "opt" -o "$prio" = "OPTIONAL"    -o "$prio" = "OPT" ]; then
+        ret="OPTIONAL"
+      elif [ "$prio" = "skip"        -o "$prio" = "skp" -o "$prio" = "SKIP"        -o "$prio" = "SKP" ]; then
+        prio="SKIP"
+      fi
+      if [ ! "$prio" = "REQUIRED" -a ! "$prio" = "RECOMMENDED" -a ! "$prio" = "OPTIONAL" -a ! "$prio" = "SKIP" ]; then
+        prio="SKIP"
+      fi
+      if [ "$prio" = "SKIP" ]; then
+        continue
+      fi
+
+      if [ "$proc" = "update" ] ; then
+        echo -n "\"$pnam UPDATE\" " >> $TMP/pkglst$$
+      else
+        echo -n "\"$pnam\" " >> $TMP/pkglst$$
+      fi
+      echo -n "\"$desc\" " >> $TMP/pkglst$$
+      if [ "$prio" = "OPTIONAL" ]; then
+        echo "off \\" >> $TMP/pkglst$$
+      else
+        echo "on  \\" >> $TMP/pkglst$$
+      fi
+
+    fi
+  fi
+done
+
+# remove last '\' symbol
+cat $TMP/pkglst$$ | sed -e "$ s/[\\]//" > $TMP/pkglist$$
+
+$DIALOG --file $TMP/pkglist$$ 2> $TMP/setofpkgs$$
+if [ $? = 1 -o $? = 255 ]; then
+  > $TMP/newpkglist$$
+  # read lines from '$PKGLIST' file in original order:
+  LINENUMS=`sed -n "$=" $PKGLIST`
+  LINENUM_REQ=1
+  while [ "$LINENUM_REQ" -le "$LINENUMS" ]; do
+    LINE="`sed -n "$LINENUM_REQ p" $PKGLIST"
+    let LINENUM_REQ+=1
+    if [ ! -z "$LINE" -a -z "`echo $LINE | grep -n -e '^#' | cut -f 1 -d ':'`" ]; then
+      pnam="`echo "$LINE" | cut -f 1 -d ':'`"
+      pver="`echo "$LINE" | cut -f 2 -d ':'`"
+      desc="`echo "$LINE" | cut -f 3 -d ':'`"
+      ball="`echo "$LINE" | cut -f 4 -d ':'`"
+      proc="`echo "$LINE" | cut -f 5 -d ':'`"
+      echo -n "$pnam:$pver:$desc:$ball:$proc:" >> $TMP/newpkglist$$
+      echo "SKIP" >> $TMP/newpkglist$$
+    fi
+  done
+else
+  > $TMP/newpkglist$$
+  # read lines from '$PKGLIST' file in original order:
+  LINENUMS=`sed -n "$=" $PKGLIST`
+  LINENUM_REQ=1
+  while [ "$LINENUM_REQ" -le "$LINENUMS" ]; do
+    LINE="`sed -n "$LINENUM_REQ p" $PKGLIST`"
+    let LINENUM_REQ+=1
+    if [ ! -z "$LINE" -a -z "`echo $LINE | grep -n -e '^#' | cut -f 1 -d ':'`" ]; then
+      pnam="`echo "$LINE" | cut -f 1 -d ':'`"
+      pver="`echo "$LINE" | cut -f 2 -d ':'`"
+      desc="`echo "$LINE" | cut -f 3 -d ':'`"
+      ball="`echo "$LINE" | cut -f 4 -d ':'`"
+      proc="`echo "$LINE" | cut -f 5 -d ':'`"
+      echo -n "$pnam:$pver:$desc:$ball:$proc:" >> $TMP/newpkglist$$
+      if [ "$proc" = "update" ] ; then
+        if grep -e "\"$pnam UPDATE\"$" -e "\"$pnam UPDATE\"[[:space:]]" $TMP/setofpkgs$$ 1> /dev/null 2> /dev/null ; then
+          echo "REQUIRED" >> $TMP/newpkglist$$
+        else
+          echo "SKIP" >> $TMP/newpkglist$$
+        fi
+      else
+        if grep -e "$pnam$" -e "$pnam[[:space:]]" $TMP/setofpkgs$$ 1> /dev/null 2> /dev/null ; then
+          echo "REQUIRED" >> $TMP/newpkglist$$
+        else
+          echo "SKIP" >> $TMP/newpkglist$$
+        fi
+      fi
+    fi
+  done
+fi
+rm -f $TMP/setofpkgs$$
+rm -f $TMP/pkglist$$
+rm -f $TMP/pkglst$$
+
+# Exit if nothing was requested:
+if grep REQUIRED $TMP/newpkglist$$ 1> /dev/null 2> /dev/null ; then
+  true
+else
+  rm -f $TMP/newpkglist$$
+  exit 99 # ABORT (there are not sellected packeges)!
+fi
+
+OPTIONS=
+if [ "$SKIPREQUIRES" = "yes" ]; then
+  OPTIONS="--skip-requires $OPTIONS"
+fi
+
+# tarballs from '$PKGLIST' file in original order:
+PKGS=
+LINENUMS=`sed -n "$=" $TMP/newpkglist$$`
+LINENUM_REQ=1
+while [ "$LINENUM_REQ" -le "$LINENUMS" ]; do
+  LINE="`sed -n "$LINENUM_REQ p" $TMP/newpkglist$$`"
+  let LINENUM_REQ+=1
+  if [ ! -z "$LINE" -a -z "`echo $LINE | grep -n -e '^#' | cut -f 1 -d ':'`" ]; then
+    pnam=`echo "$LINE" | cut -f 1 -d ':'`
+    pver=`echo "$LINE" | cut -f 2 -d ':'`
+    pdir=`dirname $(echo "$LINE" | cut -f 4 -d ':')`
+    proc=`echo "$LINE" | cut -f 5 -d ':'`
+    # version    - is used to avoid errors related equal substring in packagenames
+    # packagedir - is used to recognize same packages in different directories
+    if [ ! -z "$pdir" -a "$pdir" != "." ] ; then
+      pkgtarball=`find $CWD/$pdir -name "$pnam-$pver-*.txz"`
+    else
+      pkgtarball=`find $CWD -name "$pdir/$pnam-$pver-*.txz"`
+    fi
+    pkgtarball=`echo $pkgtarball | sed s,$CWD/,,`
+    if [ ! -z "$pnam" -a -f $pkgtarball ]; then
+      # newpkglist required only for saving order of installation,
+      # package priority will be set directly by command line arguments:
+      if [ "$proc" = "update" ] ; then
+        update-package $OPTIONS --root $TARGET_ROOT_PATH --infodialog --priority REQUIRED $pkgtarball
+      else
+        install-package $OPTIONS --root $TARGET_ROOT_PATH --infodialog --priority REQUIRED $pkgtarball
+      fi
+    fi
+  fi
+done
+
+rm -f $TMP/newpkglist$$
+
+$DIALOG --sleep 1 --colors \
+        --backtitle "\Z7Radix\Zn \Z1Pro\Zn\Z7, Ltd.\Zn" \
+        --title " \Z4Installing packages\Zn " \
+        --infobox "\nInstalling packages is completed.\n" 5 74
+
+exit $EXITSTATUS

Property changes on: build-system-1.2.3/pkgtool/install-pkglist
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/pkgtool/make-package.in
===================================================================
--- build-system-1.2.3/pkgtool/make-package.in	(nonexistent)
+++ build-system-1.2.3/pkgtool/make-package.in	(revision 231)
@@ -0,0 +1,409 @@
+#!/bin/sh
+
+TAR=tar
+
+program=`basename $0`
+
+# 92 = Cannot create '/tmp/...' directory
+
+umask 002
+if [ ! -z "$TMPDIR" ] ; then mkdir -p $TMPDIR ; fi
+TMP=$(mkdir -p /tmp/radix && mktemp -d -p /tmp/radix pkgtool.XXXXXXXX) || { echo "Cannot create '/tmp/...' directory" ; exit 92; }
+trap "rm -rf $TMP" EXIT
+
+VERSION=@MKPKGVERSION@
+
+check_link_permissions() {
+  ERRCOUNT=0
+  for link in `find . -type l` ; do
+    user_name="`ls -l $link | grep -e "^l" | cut -f 3 -d ' '`"
+    LINK_UID="`cat /etc/passwd | grep -e "^$user_name" | cut -f 3 -d ':'`"
+    if [ ! "$LINK_UID" = "$UID" -a ! "$UID" = "0" ]; then
+      # only root have permissions for all links
+      # user chould have only his own links
+      let ERRCOUNT+=1
+    fi
+  done
+  if [ "$ERRCOUNT" = "0" ]; then
+    return 1
+  else
+    return 0
+  fi
+}
+
+make_install_script() {
+  COUNT=1
+  LINE="`sed -n "$COUNT p" $1`"
+  while [ ! "$LINE" = "" ]; do
+   LINKGOESIN="`echo "$LINE" | cut -f 1 -d " "`" 
+   LINKGOESIN="`dirname $LINKGOESIN`" 
+   LINKNAMEIS="`echo "$LINE" | cut -f 1 -d ' '`"
+   LINKNAMEIS="`basename "$LINKNAMEIS"`"
+   LINKPOINTSTO="`echo "$LINE" | cut -f 3 -d ' '`"
+   echo "( cd $LINKGOESIN ; rm -rf $LINKNAMEIS )"
+   echo "( cd $LINKGOESIN ; ln -sf $LINKPOINTSTO $LINKNAMEIS )"
+   COUNT=`expr $COUNT + 1`
+   LINE="`sed -n "$COUNT p" $1`"
+  done
+}
+
+create_file_list() {
+  if [ -z "$1" ]; then
+    param="."
+  else
+    param="$1"
+  fi
+
+  # zero length file
+  > .FILELIST
+
+  list=`ls -Rla $param | grep "./" | sed -e "s/://g"`
+
+  FCOUNT=0
+  DCOUNT=0
+  for dir in $list;
+  do
+    if [ -d "$dir" ]; then
+      let DCOUNT+=1
+      for file in `ls $dir`;
+      do
+        if [ -f "$dir/$file" ]; then
+          echo "$dir/$file" | sed -e "s/^\.\///" | sed -e "s/\.new$//g" >> .FILELIST
+          let FCOUNT+=1 
+        fi
+      done
+    fi
+  done
+
+  usize="`du -s -h . | cut -f 1 -d $'\t'`"
+  total_size="`echo -n "$usize"`"
+
+  echo "uncompressed_size=$total_size" >> .PKGINFO
+  echo "total_files=$FCOUNT" >> .PKGINFO
+}
+
+strip_description() {
+  outfile=$1
+  infile="./.DESCRIPTION"
+  > $outfile
+  LINENUMS="`cat $infile | grep -n -e "^$pkgname:" | cut -f 1 -d ':'`"
+  if [ "$LINENUMS" = "" ]; then
+    echo "WARNING: Description is empty or corrupted."
+    return
+  fi
+  for LINENUM in $LINENUMS ; do
+     LINE="`sed -n "$LINENUM p" $infile`"
+     echo "$LINE" >> $outfile
+  done
+}
+
+text_description() {
+  outfile=$1
+  infile="./.DESCRIPTION"
+
+  echo ""  > $outfile
+  echo "/* begin *" >> $outfile
+  echo " " >> $outfile
+
+  LINENUMS="`cat $infile | grep -n -e "^$pkgname:" | cut -f 1 -d ':'`"
+  if [ "$LINENUMS" = "" ]; then
+    echo "WARNING: Description is empty or corrupted."
+    return
+  fi
+  for LINENUM in $LINENUMS ; do
+     LINE="`sed -n "$LINENUM p" $infile | sed -e "s/^$pkgname:/  /" | sed -e "s/ $//g"`"
+     echo "$LINE" >> $outfile
+  done
+
+  echo " * end */" >> $outfile
+}
+
+
+usage() {
+  cat << EOF
+
+Usage: $program [options] DESTDIR
+
+Makes a "*.txz" package containing the contents of the current and 
+all subdirectories. If symbolic links exist, they will be removed
+and an '.RESTORELINKS' script will be made to recreate them later.
+
+The '$program' utility should be run in the PKG directory which contains
+installed package by 'make DESTDIR=/pkg install', for example.
+Before running the '$program' utility the install script ('.INSTALL')
+and '.PKGINFO' files should be copyed into PKG directory.
+
+Optionally current directory may contants '.DESCRIPTION' and
+'.REQUIRES' files. The '$program' utility will add 'uncompressed_size' and
+'total_files' variables (calculated at runtime) into .PKGINFO file.
+Available options:
+
+   -l, --linkadd {y|n}   - moves symlinks into .RESTORELINKS scrypt
+                           ( recommended );
+  -fl, --flavour FLAVOUR - name of additional subdirectory in GROUP
+                           directory for created package.
+
+EOF
+}
+
+show_version() {
+  echo "$VERSION"
+}
+
+remove_size_info() {
+  infile="./.PKGINFO"
+  sed -i '/uncompressed_size/d' $infile
+  sed -i '/total_files/d' $infile
+}
+
+remove_backslash_info() {
+  infile="./.PKGINFO"
+  sed -i '/^short_description=/ s/[\]\(.\)/\1/g' $infile
+}
+
+
+# Parse options
+#while [ 0 ]; do
+#  if [ "$1" = "--linkadd" -o "$1" = "-l" ]; then
+#    if [ "$2" = "yes" -o "$2" = "y" ]; then
+#      LINKADD=y
+#    elif [ "$2" = "no" -o "$2" = "n" ]; then
+#      LINKADD=n
+#    else
+#      usage
+#      exit 2
+#    fi
+#    shift 2
+#  elif [ "$1" = "-h" -o "$1" = "--help" -o $# = 0 ]; then
+#    usage
+#    exit 0
+#  else
+#    break
+#  fi
+#done
+
+while [[ $# > 0 ]] ; do
+  arg=$1
+  case $arg in
+    -l|--linkadd)
+      if [ "$2" = "yes" -o "$2" = "y" ]; then
+        LINKADD=y
+        shift
+      elif [ "$2" = "no" -o "$2" = "n" ]; then
+        LINKADD=n
+        shift
+      else
+        usage
+        exit 2
+      fi
+      ;;
+
+    --linkadd=*)
+      if [ "${arg#*=}" = "yes" -o "${arg#*=}" = "y" ]; then
+        LINKADD=y
+      elif [ "${arg#*=}" = "no" -o "${arg#*=}" = "n" ]; then
+        LINKADD=n
+      else
+        usage
+        exit 2
+      fi
+      ;;
+
+    -fl|--flavour)
+      FLAVOUR="$2"
+      shift
+      ;;
+
+    --flavour=*)
+      FLAVOUR="${arg#*=}"
+      ;;
+
+    -h|--help)
+      usage
+      exit 0
+      ;;
+
+    -v|--version)
+      show_version
+      exit 0
+      ;;
+    *)
+      TARGET_DIR_NAME=$arg
+      ;;
+  esac
+  shift
+done
+
+
+# Check needed files and variables:
+if [ -r "./.PKGINFO" ]; then
+  # if .PKGINFO contains size variables then remove its.
+  # create_file_list() will add them later.
+  remove_size_info
+  # if .PKGINFO short_description contains backslashes then remove its.
+  remove_backslash_info
+  . ./.PKGINFO
+else
+  usage
+  echo "ERROR: The file './.PKGINFO' is required for creating package."
+  echo
+  exit 1 
+fi
+
+if [ "$pkgname" = "" -o "$pkgver" = "" -o "$arch" = "" -o "$distroname" = "" -o "$distrover" = "" ]; then
+  usage
+  echo "ERROR: The file './.PKGINFO' should contains the declarations"
+  echo "       of following variables:"
+  echo "  pkgname    - name of package;"
+  echo "  pkgver     - version such as 1.0.4, for example;"
+  echo "  arch       - architecture of target machine {x86_64|i686|mipsel|arm|...};"
+  echo "  distroname - name of distributive {radix|...};"
+  echo "  distrover  - distributive version {1.0|...};"
+  echo ""
+  echo "Also optional variables are available:"
+  echo "  group             - package group name {app|libs|dev|...};"
+  echo "  short_description - package description. \"Package Tool\", for example;"
+  echo "  url               - package home site. @BUGURL@, for example;"
+  echo "  license           - LICENSE type {GPLv2|LGPL|BSD|MIT|...}."
+  echo ""
+  exit 1 
+fi
+
+if [ ! -e "./.INSTALL" ]; then
+  usage
+  echo "ERROR: The file './.INSTALL' is required for creating package."
+  echo
+  exit 1 
+fi
+
+echo
+echo "Package maker, version $VERSION."
+PACKAGE_NAME="$pkgname-$pkgver-$arch-$distroname-$distrover.txz"
+PACKAGE_TEXT="$pkgname-$pkgver-$arch-$distroname-$distrover.txt"
+SHA_SUM_NAME="$pkgname-$pkgver-$arch-$distroname-$distrover.sha256"
+if [ "$TARGET_DIR_NAME" = "" ]; then
+  TARGET_DIR_NAME="."
+  echo "WARNING: DESTDIR is not defined. Use current directory."
+fi
+# add group directory to target dir:
+if [ ! "$TARGET_DIR_NAME" = "." ]; then
+  if [ ! "$group" = "" ]; then
+    TARGET_DIR_NAME="$TARGET_DIR_NAME/$group"
+  fi
+fi
+# add FLAVOUR subdirectory to group directory in the target dir:
+if [ ! "$TARGET_DIR_NAME" = "." ]; then
+  if [ ! "$FLAVOUR" = "" ]; then
+    TARGET_DIR_NAME="$TARGET_DIR_NAME/$FLAVOUR"
+  fi
+fi
+PACKAGE_NAME="`basename $PACKAGE_NAME`"
+TAR_NAME="`basename $PACKAGE_NAME .txz`"
+echo
+echo -n "Search for symbolic links: "
+# Get rid of possible pre-existing trouble:
+INST=`mktemp $TMP/makepkg.XXXXXX`
+# This requires the ls from coreutils-5.0 (or newer):
+find . -type l -exec ls -l --time-style=long-iso {} \; | while read foo ; do echo $foo ; done | cut -f 8- -d ' ' | cut -b3- > $INST
+if [ ! "`cat $INST`" = "" ]; then
+  echo
+  echo
+  cat $INST
+  echo
+  echo "Restore symbolic links script:"
+  make_install_script $INST | tee .RESTORELINKS
+fi
+if [ ! "`cat $INST`" = "" ]; then
+  if [ ! "$LINKADD" ]; then
+    echo
+    echo "It is recommended to remove symbolic links and create the '.RESTORELINKS' script."
+    echo
+    echo "Do you want create the '.RESTORELINKS' script for this package"
+    echo -n "and remove symbolic links from the package archive ([y]es, [n]o)? "
+    read LINKADD;
+  fi
+  if [ "$LINKADD" = "y" ]; then
+    check_link_permissions
+    if [ ! $? = 1 ]; then
+      echo "ERROR: Removing links: Permission denied."
+      exit 1
+    fi
+    echo
+    echo "Removing symbolic links:"
+    find . -type l -exec rm -v {} \;
+    echo
+  else
+    rm -f .RESTORELINKS
+  fi
+else
+  echo "... symbolic links were not found, .RESTORELINKS script is not needed."
+fi
+rm -f $INST
+
+
+create_file_list
+
+# Strip comments in description file:
+if [ -f .DESCRIPTION ]; then
+  strip_description .description.tmp
+  if [ -s .description.tmp ]; then
+    mv .description.tmp .DESCRIPTION
+  else
+    rm -f .DESCRIPTION
+  fi
+fi
+
+
+echo
+echo "Creating tar file $TAR_NAME.tar..."
+echo
+$TAR --exclude="$TAR_NAME.tar" -cvf $TAR_NAME.tar `ls -A | tr '\n' ' '`
+
+# Warn of zero-length files IS NOT OUR STYLE!:
+#find . -type f -size 0c | while read file ; do
+#  echo "WARNING: zero length file $(echo $file | cut -b3-)"
+#done
+
+# Warn of corrupt or empty gzip files:
+find . -type f -name '*.gz' | while read file ; do
+  if ! gzip -t $file 1> /dev/null 2> /dev/null ; then
+    echo "WARNING: gzip test failed on $(echo $file | cut -b3-)"
+  else
+    if [ $(gzip -l $file | tail -n 1 | tr -s ' ' | cut -f 3 -d ' ') -eq 0 ]; then
+      echo "WARNING: $(echo $file | cut -b3-) is an empty gzipped file"
+    fi
+  fi
+done
+
+
+echo
+echo "Compress $TAR_NAME.tar..."
+xz -9 $TAR_NAME.tar
+echo
+echo "Renaming $TAR_NAME.tar.xz to $PACKAGE_NAME..."
+mv $TAR_NAME.tar.xz $PACKAGE_NAME
+
+text_description $PACKAGE_TEXT
+sha256sum -b $PACKAGE_NAME > $SHA_SUM_NAME
+
+if [ ! "$TARGET_DIR_NAME" = "." ]; then
+  # $TMP/errmsg$$ - is a unique temporary file
+  mkdir -p "$TARGET_DIR_NAME" 2> $TMP/errmsg$$
+  if [ "$?" = "1" ]; then
+    echo
+    echo "ERROR: `cat ./errmsg$$`"
+    echo "Find package in the current directory."
+    echo
+    rm -f $TMP/errmsg$$
+    exit 1
+  fi
+  rm -f $TMP/errmsg$$
+  echo
+  echo "Moving $PACKAGE_NAME to $TARGET_DIR_NAME directory..."
+  mv $PACKAGE_NAME $TARGET_DIR_NAME
+  mv $PACKAGE_TEXT $TARGET_DIR_NAME
+  mv $SHA_SUM_NAME $TARGET_DIR_NAME
+fi
+echo
+echo "Package creation complete."
+echo
Index: build-system-1.2.3/pkgtool/pkglog
===================================================================
--- build-system-1.2.3/pkgtool/pkglog	(nonexistent)
+++ build-system-1.2.3/pkgtool/pkglog	(revision 231)
@@ -0,0 +1,152 @@
+#!/bin/sh
+
+# EXIT STATUS 92 = Cannot create '/tmp/...' directory
+
+umask 002
+if [ ! -z "$TMPDIR" ] ; then mkdir -p $TMPDIR ; fi
+TMP=$(mkdir -p /tmp/radix && mktemp -d -p /tmp/radix pkgtool.XXXXXXXX) || { echo "Cannot create '/tmp/...' directory" ; exit 92; }
+trap "rm -rf $TMP" EXIT
+
+
+pkginfo=$1
+shift
+TARGET_DIR_NAME=$1
+
+pkginfo_src_dir="`dirname $pkginfo`"
+
+usage() {
+  echo ""
+  echo "Usage: $0 .PKGINFO [DESTDIR]"
+  echo ""
+}
+
+get_info() {
+  . $pkginfo
+}
+
+if [ "$pkginfo" = "" ]; then
+  usage
+  exit 1
+fi
+
+get_info
+
+if [ "$TARGET_DIR_NAME" = "" ]; then
+  TARGET_DIR_NAME="."
+fi
+
+if [ "$pkgname" = "" -o "$pkgver" = "" -o "$arch" = "" -o "$distroname" = "" -o "$distrover" = "" ]; then
+  echo "ERROR: The file './.PKGINFO' should contains the declarations"
+  echo "       of following variables:"
+  echo "  pkgname    - name of package;"
+  echo "  pkgver     - version such as 1.0.4, for example;"
+  echo "  arch       - architecture of target machine {x86_64|i686|mipsel|arm|...};"
+  echo "  distroname - name of distributive {slamd64|...};"
+  echo "  distrover  - distributive version {12.2|...}"
+  echo ""
+  echo "Also optional variables are available:"
+  echo "  group      - package group name {applications|libs|...};"
+  echo "  url        - package home site. http://www.pkg.com, for example;"
+  echo "  license    - LICENSE type {GPL|LGPL|BSD|Proprietary}."
+  echo ""
+  usage
+  exit 1
+fi
+
+if [ ! -r "$pkginfo_src_dir/.INSTALL" -o ! -r "$pkginfo_src_dir/.FILELIST" ]; then
+  echo "ERROR: The current directory should contains following files:"
+  echo "  .INSTALL   - installation script;"
+  echo "  .FILELIST  - list of presented files in the created package."
+  echo ""
+  echo "It seems like that package is not created yet."
+  echo ""
+  usage
+  exit 1
+fi
+
+strip_description() {
+  outfile=$1
+  infile="$pkginfo_src_dir/.DESCRIPTION"
+  > $outfile
+  LINENUMS="`cat $infile | grep -n -e "^$pkgname:" | cut -f 1 -d ':'`"
+  if [ "$LINENUMS" = "" ]; then
+    echo "WARNING: Description is empty or corrupted."
+    return
+  fi
+  for LINENUM in $LINENUMS ; do
+     LINE="`sed -n "$LINENUM p" $infile`"
+     echo "$LINE" >> $outfile
+  done
+}
+
+
+logfile="$pkgname-$pkgver-$arch-$distroname-$distrover"
+
+echo
+echo "Creating Install log file $logfile..."
+
+echo "PACKAGE NAME: $pkgname"                   > $logfile
+echo "PACKAGE VERSION: $pkgver"                >> $logfile
+echo "ARCH: $arch"                             >> $logfile
+echo "DISTRO: $distroname"                     >> $logfile
+echo "DISTRO VERSION: $distrover"              >> $logfile
+if [ ! "$group" = "" ]; then
+echo "GROUP: $group"                           >> $logfile
+fi
+if [ ! "$url" = "" ]; then
+  echo "URL: $url"                             >> $logfile
+fi
+if [ ! "$license" = "" ]; then
+  echo "LICENSE: $license"                     >> $logfile
+fi
+if [ ! "$uncompressed_size" = "" ]; then
+  echo "UNCOMPRESSED SIZE: $uncompressed_size" >> $logfile
+fi
+if [ ! "$total_files" = "" ]; then
+  echo "TOTAL FILES: $total_files"             >> $logfile
+fi
+echo "REFERENCE COUNTER: 0"                    >> $logfile
+if [ -f "$pkginfo_src_dir/.REQUIRES" ]; then
+  echo "REQUIRES:"                             >> $logfile
+  cat $pkginfo_src_dir/.REQUIRES               >> $logfile
+fi
+if [ -f "$pkginfo_src_dir/.DESCRIPTION" ]; then
+  strip_description $TMP/description$$
+  echo "PACKAGE DESCRIPTION:"                  >> $logfile
+  cat $TMP/description$$                       >> $logfile
+  rm -f $TMP/description$$
+fi
+echo "RESTORE LINKS:"                          >> $logfile
+if [ -f "$pkginfo_src_dir/.RESTORELINKS" ]; then
+  cat $pkginfo_src_dir/.RESTORELINKS           >> $logfile
+fi
+if [ ! -f "$pkginfo_src_dir/.INSTALL" ]; then
+  echo "ERROR: Install script '.INSTALL' is not present."
+  exit 1
+fi
+echo "INSTALL SCRIPT:"                         >> $logfile
+cat $pkginfo_src_dir/.INSTALL                  >> $logfile
+if [ ! -f "$pkginfo_src_dir/.FILELIST" ]; then
+  echo "ERROR: File list '.FILELIST' is not present."
+  exit 1
+fi
+echo "FILE LIST:"                              >> $logfile
+cat $pkginfo_src_dir/.FILELIST                 >> $logfile
+
+if [ ! "$TARGET_DIR_NAME" = "." ]; then
+  # $TMP/errmsg$$ - is a unique temporary file
+  mkdir -p "$TARGET_DIR_NAME" 2> $TMP/errmsg$$
+  if [ "$?" = "1" ]; then
+    echo
+    echo "ERROR: `cat $TMP/errmsg$$`"
+    echo "Find the $logfile in the current directory."
+    echo
+    exit 1
+  fi
+  echo
+  echo "Moving $logfile to $TARGET_DIR_NAME directory..."
+  mv $logfile $TARGET_DIR_NAME
+fi
+echo
+echo "Install log file creation complete."
+echo

Property changes on: build-system-1.2.3/pkgtool/pkglog
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/pkgtool/remove-package.in
===================================================================
--- build-system-1.2.3/pkgtool/remove-package.in	(nonexistent)
+++ build-system-1.2.3/pkgtool/remove-package.in	(revision 231)
@@ -0,0 +1,441 @@
+#!/bin/sh
+
+TAR=tar
+
+# program name:
+program=`basename $0`
+
+#  1 = tar returned error code
+#  2 = failed read package info
+#  4 = not a file
+# 11 = broken .PKGINFO
+# 12 = broken .DESCRIPTION
+# 13 = permission denied (should be root)
+# 14 = broken .pkglist or user pkglist
+# 15 = priority has not specified arter --priority option
+# 16 = root path has not specified arter --root option
+# 17 = exit if called with no arguments
+# 19 =  pre install script returns bad status
+# 20 = post install script returns bad status
+# 21 =  pre Remove script returns bad status
+# 22 = post Remove script returns bad status
+# 23 = package is not installed
+# 24 = {Setup | Package} database directory doesn't exist.
+# 25 = {There are not resolved requires | Reference counter is not empty}
+# 92 = Cannot create '/tmp/...' directory
+######!# 99 = user abort from menu mode
+EXITSTATUS=0
+
+CWD=`pwd`
+
+umask 002
+if [ ! -z "$TMPDIR" ] ; then mkdir -p $TMPDIR ; fi
+TMP=$(mkdir -p /tmp/radix && mktemp -d -p /tmp/radix pkgtool.XXXXXXXX) || { echo "Cannot create '/tmp/...' directory" ; exit 92; }
+trap "rm -rf $TMP" EXIT
+
+
+usage() {
+ cat << EOF
+
+Usage: $program [options] { package_tarball[s] | pkglogfile[s] }
+
+$program is used to remove a *.txz package like this:
+   $program /packagesdir/_kxLibc-1.0.4-x86_64-glibc-radix-1.0.txz
+   $program /SETUP_DB_PATH/packages/_kxLibc-1.0.4-x86_64-glibc-radix-1.0
+
+options:
+   --root /dest - install someplace else, like /dest;
+   --skip-refs  - skip checking the reference counter;
+
+EOF
+}
+
+refcounter=
+get_ref_counter() {
+  logfile=$1
+  LINENUM_REF="`cat $logfile | grep -n -e "REFERENCE COUNTER:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_REF" = "" ]; then
+    refcounter=
+  fi
+  LINE="`sed -n "$LINENUM_REF p" $logfile`"
+  refcounter="`echo "$LINE" | sed -e 's/^REFERENCE COUNTER: //'`"
+}
+
+tarball_pkginfo() {
+  xzcat $1 | $TAR -xvf - ".PKGINFO" -O  1> $TMP/.PKGINFO  2> /dev/null
+  if [ ! "$?" = "0" ]; then
+    echo "ERROR: Cannot extract package pkginfo from $1"
+    EXITSTATUS=1
+    exit $EXITSTATUS
+  fi
+}
+
+extract_links() {
+ sed -n 's,^( *cd \([^ ;][^ ;]*\) *; *rm -rf \([^ )][^ )]*\) *) *$,\1/\2,p'
+}
+
+strip_description() {
+  infile=$1
+  outfile=$2
+  echo " " > $outfile
+  LINENUMS="`cat $infile | grep -n -e "^$pkgname:" | cut -f 1 -d ':'`"
+  if [ "$LINENUMS" = "" ]; then
+    if [ "$VERBOSE" == "yes" ] ; then
+      echo "WARNING: Description is empty or corrupted."
+    fi
+    return
+  fi
+  for LINENUM in $LINENUMS ; do
+    LINE="`sed -n "$LINENUM p" $infile | sed -e "s/^$pkgname://"`"
+    if [ "$LINE" = "" ]; then
+       LINE=" "
+    else
+       LINE="`echo "$LINE" | sed -e "s/ $//g"`"
+    fi
+    echo "$LINE" >> $outfile
+  done
+}
+
+
+#
+# Parse options:
+#
+while [ 0 ]; do
+  if [ "$1" = "-h" -o "$1" = "--help" ]; then
+    usage
+    exit 0
+  elif [ "$1" = "--verbose" ]; then
+    VERBOSE="yes"
+    shift 1
+  elif [ "$1" = "--dark" ]; then
+    DARKMODE="yes"
+    shift 1
+  elif [ "$1" = "--without-logs" ]; then
+    WITHOUTLOGS="yes"
+    shift 1
+  elif [ "$1" = "--skip-refs" ]; then
+    SKIPREFERENCES="yes"
+    shift 1
+  elif [ "$1" = "--root" ]; then
+    if [ "$2" = "" ]; then
+      usage
+      echo "ERROR: Target root path has not specified. Check --root option."
+      EXITSTATUS=16
+      exit $EXITSTATUS
+    fi
+    TARGET_ROOT_PATH="$2"
+    shift 2
+  else
+    break
+  fi
+done
+
+#
+# usage(), exit if called with no arguments:
+#
+if [ $# = 0 ]; then
+  usage
+  echo "ERROR: arguments were not specified. Check options."
+  EXITSTATUS=17
+  exit $EXITSTATUS
+fi
+
+if [ "$TARGET_ROOT_PATH" = "" ]; then
+  TARGET_ROOT_PATH="/"
+else
+  TARGET_ROOT_PATH="`echo "$TARGET_ROOT_PATH" | sed -e "s/\/$//"`/"
+fi
+
+if [ "$TARGET_ROOT_PATH" = "/" ]; then
+  if [ ! $UID = "0" ]; then
+    echo "ERROR: Trying to install into root directory: permission denied"
+    EXITSTATUS=13
+    exit $EXITSTATUS
+  fi
+fi
+
+SETUP_DB_PATH=${TARGET_ROOT_PATH}var/log/@DISTRO@
+if [ ! -d $SETUP_DB_PATH ]; then
+  echo "ERROR: Setup database directory doesn't exist."
+  EXITSTATUS=24
+  exit $EXITSTATUS
+fi
+
+PKG_DB_PATH=$SETUP_DB_PATH/packages
+if [ ! -d $PKG_DB_PATH ]; then
+  echo "ERROR: Packages database directory doesn't exist."
+  EXITSTATUS=24
+  exit $EXITSTATUS
+fi
+
+for PKG_DB_DIR in removed_packages setup ; do
+  if [ ! -d $SETUP_DB_PATH/$PKG_DB_DIR ]; then
+    rm -rf $SETUP_DB_PATH/$PKG_DB_DIR # make sure it's not a link
+    mkdir -p $SETUP_DB_PATH/$PKG_DB_DIR
+    chmod 755 $SETUP_DB_PATH/$PKG_DB_DIR
+  fi
+done
+
+REMOVED_PKG_DB_PATH=$SETUP_DB_PATH/removed_packages
+LOG_PATH=$SETUP_DB_PATH/setup
+if [ "$WITHOUTLOGS" != "yes" ] ; then
+  LOG_FILE=$LOG_PATH/setup.log
+else
+  LOG_FILE=/dev/null
+fi
+
+delete_files() {
+  while read FILE ; do
+    if [ ! -d "${TARGET_ROOT_PATH}$FILE" ]; then
+      if [ -r "${TARGET_ROOT_PATH}$FILE" ]; then
+        # "-nt" is "newer than"; "-ot" is "older than":
+        if [ "${TARGET_ROOT_PATH}$FILE" -nt "$logfile" ]; then
+          if [ "$VERBOSE" == "yes" ] ; then
+            echo "WARNING: ${TARGET_ROOT_PATH}$FILE changed after package installation."
+          fi
+        fi
+        if [ "$VERBOSE" == "yes" ] ; then
+          echo " ===> Deleting ${TARGET_ROOT_PATH}$FILE"
+        fi
+        rm -f "${TARGET_ROOT_PATH}$FILE"
+        echo "`dirname $FILE`" >> $TMP/not_sorted_dirs$$
+      else
+        if [ "$VERBOSE" == "yes" ] ; then
+          echo " ===> ${TARGET_ROOT_PATH}$FILE no longer exists. Skipping."
+        fi
+      fi
+    else
+      if [ "$VERBOSE" == "yes" ] ; then
+        echo " ===> ${TARGET_ROOT_PATH}$FILE is a directory. Skipping."
+      fi
+      echo "$FILE" >> $TMP/not_sorted_dirs$$
+    fi
+  done
+}
+
+delete_links() {
+  while read LINK ; do
+    if [ -L "${TARGET_ROOT_PATH}$LINK" ]; then
+      if [ "$VERBOSE" == "yes" ] ; then
+        echo " ===> Deleting symlink ${TARGET_ROOT_PATH}$LINK"
+      fi
+      rm -f ${TARGET_ROOT_PATH}$LINK
+      echo "`dirname $LINK`" >> $TMP/not_sorted_dirs$$
+    else
+      if [ "$VERBOSE" == "yes" ] ; then
+        echo " ===> ${TARGET_ROOT_PATH}$LINK (symlink) no longer exists. Skipping."
+      fi
+    fi
+  done
+}
+
+delete_dirs() {
+  while read DIR ; do
+    if [ -d "${TARGET_ROOT_PATH}$DIR" ]; then
+      if [ `ls -a "${TARGET_ROOT_PATH}$DIR" | wc -l` -eq 2 ]; then
+        if [ "$VERBOSE" == "yes" ] ; then
+          echo " ===> Deleting empty directory ${TARGET_ROOT_PATH}$DIR"
+        fi
+        rmdir "${TARGET_ROOT_PATH}$DIR"
+      else
+        if [ "$VERBOSE" == "yes" ] ; then
+          echo " ===> Preserving non empty directory ${TARGET_ROOT_PATH}$DIR"
+        fi
+      fi
+    fi
+  done
+}
+
+################################################################
+# Main loop:
+#
+for PKGFILE in $* ; do
+  # Simple package integrity check:
+  if [ ! -f $PKGFILE ]; then
+    EXITSTATUS=4
+    echo "ERROR: $PKGFILE: is not a regular file"
+    exit $EXITSTATUS
+  fi
+
+  pkgfile_name="`basename $PKGFILE`"
+  pkgfile_noext_name="`basename $PKGFILE .txz`"
+  pkgfile_src_dir="`dirname $PKGFILE`"
+
+  if [ "$pkgfile_name" = "$pkgfile_noext_name" ]; then
+    logfile="$PKGFILE"
+    tarball=""
+  else
+    logfile=""
+    tarball="$PKGFILE"
+  fi
+
+  # getting .PKGINFO file:
+  if [ ! "$logfile" = "" ]; then
+    pkginfo --dest $TMP pkginfo $logfile
+    if [ ! -f $TMP/.PKGINFO -o ! -s $TMP/.PKGINFO ]; then
+      rm -f $TMP/.PKGINFO
+      echo "ERROR: There is no package info in $1"
+      EXITSTATUS=2
+      exit $EXITSTATUS
+    fi
+  elif [ ! "$tarball" = "" ]; then
+    tarball_pkginfo $tarball
+    if [ ! -f $TMP/.PKGINFO -o ! -s $TMP/.PKGINFO ]; then
+      rm -f $TMP/.PKGINFO
+      echo "ERROR: There is no package info in $1"
+      EXITSTATUS=2
+      exit $EXITSTATUS
+    fi
+  fi
+
+  if [ -f $TMP/.PKGINFO ]; then
+    . $TMP/.PKGINFO
+    # check variables:
+    if [ "$pkgname" = "" -o "$pkgver" = "" -o "$arch" = "" -o "$distroname" = "" -o "$distrover" = "" ]; then
+      echo "ERROR: The file '.PKGINFO' doesn't contain necessary declarations."
+      EXITSTATUS=11
+      exit $EXITSTATUS 
+    fi
+  fi
+  rm -f $TMP/.PKGINFO
+
+  # check installed pkglog file:
+  if [ ! -f $PKG_DB_PATH/$pkgname-$pkgver-$arch-$distroname-$distrover ]; then
+    echo "ERROR: The package '$pkgname-$pkgver-$arch-$distroname-$distrover' is not installed."
+    EXITSTATUS=23
+    exit $EXITSTATUS 
+  fi
+  # So continue with logfile
+  logfile=$PKG_DB_PATH/$pkgname-$pkgver-$arch-$distroname-$distrover
+
+  # Removing process:
+  echo -n "[`LANG=en LANGUAGE=en date +'%d-%b-%Y %H:%M:%S'`] " >> $LOG_FILE
+  echo -n "Removing: `basename $logfile`: "                    >> $LOG_FILE
+
+  # check REFERENCE COUNTER: if non zero then exit.
+  if [ ! "$SKIPREFERENCES" = "yes" ]; then
+    get_ref_counter $logfile
+    if [ ! "$refcounter" = "0" ]; then
+      echo "ERROR: Reference counter is not empty."
+      echo "ERROR: Reference counter is not empty." >> $LOG_FILE
+      EXITSTATUS=25
+      exit $EXITSTATUS
+    fi
+  fi
+
+  # pre remove script:
+  pkginfo --dest $TMP install_script $logfile
+  if [ ! -x $TMP/.INSTALL -o ! -s $TMP/.INSTALL ]; then
+    rm -f $TMP/.INSTALL
+  else
+    ( cd $TARGET_ROOT_PATH
+      $TMP/.INSTALL pre_remove $pkgver > /dev/null 2>&1
+      if [ ! "$?" = "0" ]; then
+        echo "ERROR: Pre Remove script returns bad status."
+        echo "ERROR: Pre Remove script returns bad status." >> $LOG_FILE
+        rm -f $TMP/.INSTALL
+        EXITSTATUS=21
+        exit $EXITSTATUS
+      fi
+      rm -f $TMP/.INSTALL
+    )
+    EXITSTATUS=$?
+    rm -f $TMP/.INSTALL
+    if [ ! "$EXITSTATUS" = "0" ] ; then
+      break
+    fi
+  fi
+
+  # Getting saved links:
+  pkginfo --dest $TMP restore_links $logfile
+  if [ ! -f $TMP/.RESTORELINKS -o ! -s $TMP/.RESTORELINKS ]; then
+    rm -f $TMP/.RESTORELINKS
+  else
+    cat $TMP/.RESTORELINKS | extract_links | sort -u > $TMP/links$$
+    rm -f $TMP/.RESTORELINKS
+  fi
+  # Getting files:
+  pkginfo --dest $TMP filelist $logfile
+  if [ ! -f $TMP/.FILELIST -o ! -s $TMP/.FILELIST ]; then
+    rm -f $TMP/.FILELIST
+  else
+    cat $TMP/.FILELIST | sort -u > $TMP/files$$
+    rm -f $TMP/.FILELIST
+  fi
+
+  pkginfo --dest $TMP description $logfile
+  strip_description "$TMP/.DESCRIPTION" "$TMP/msg$$"
+  rm -f $TMP/.DESCRIPTION
+
+  echo " Uncompressed Size: $uncompressed_size" >> $TMP/msg$$
+  echo "       Total Files: $total_files"       >> $TMP/msg$$
+
+  if [ "$DARKMODE" != "yes" ] ; then
+    echo ""
+    echo "Removing package $pkgname... "
+    ####  |---handy-ruler--------------------------------------------------------|
+    echo "|======================================================================|"
+    echo "`cat $TMP/msg$$`"
+    echo "|======================================================================|"
+    echo ""
+  fi
+  rm -f $TMP/msg$$
+
+  rm -f $TMP/not_sorted_dirs$$
+  if [ -f $TMP/links$$ -a -s $TMP/links$$ ]; then
+    delete_links < $TMP/links$$
+  fi
+  rm -f $TMP/links$$
+
+  if [ -f $TMP/files$$ -a -s $TMP/files$$ ]; then
+    delete_files < $TMP/files$$
+  fi
+  rm -f $TMP/files$$
+
+  if [ -f $TMP/not_sorted_dirs$$ -a -s $TMP/not_sorted_dirs$$ ]; then
+    sort -u -r < $TMP/not_sorted_dirs$$ > $TMP/dirs$$
+    rm -f $TMP/not_sorted_dirs$$
+    delete_dirs < $TMP/dirs$$
+    rm -f $TMP/dirs$$
+  fi
+  rm -f $TMP/not_sorted_dirs$$
+
+  # Decrease REFERENCE COUNTER in the required packages:
+  ( cd $PKG_DB_PATH; change-refs dec "$pkgname-$pkgver-$arch-$distroname-$distrover" )
+
+  # post remove script:
+  pkginfo --dest $TMP install_script $logfile
+  if [ ! -x $TMP/.INSTALL -o ! -s $TMP/.INSTALL ]; then
+    rm -f $TMP/.INSTALL
+  else
+    ( cd $TARGET_ROOT_PATH
+      $TMP/.INSTALL post_remove $pkgver > /dev/null 2>&1
+      if [ ! "$?" = "0" ]; then
+        echo "ERROR: Post Remove script returns bad status, but package has been removed."
+        echo "ERROR: Post Remove script returns bad status, but package has been removed." >> $LOG_FILE
+        # but package removed successful
+        rm -f $TMP/.INSTALL
+        EXITSTATUS=22
+        exit $EXITSTATUS
+      fi
+    )
+    EXITSTATUS=$?
+    rm -f $TMP/.INSTALL
+    if [ ! "$EXITSTATUS" = "0" ] ; then
+      # mv logfile to removed_packages/ data base directory.
+      ( cd $PKG_DB_PATH; mv -f "$pkgname-$pkgver-$arch-$distroname-$distrover" $REMOVED_PKG_DB_PATH )
+      break
+    fi
+  fi
+
+  # mv logfile to removed_packages/ data base directory.
+  ( cd $PKG_DB_PATH; mv -f "$pkgname-$pkgver-$arch-$distroname-$distrover" $REMOVED_PKG_DB_PATH )
+
+  echo "SUCCESS: Package has been removed." >> $LOG_FILE
+
+done
+#
+# End of Main loop.
+################################################################
+
+exit $EXITSTATUS
Index: build-system-1.2.3/pkgtool/update-package.in
===================================================================
--- build-system-1.2.3/pkgtool/update-package.in	(nonexistent)
+++ build-system-1.2.3/pkgtool/update-package.in	(revision 231)
@@ -0,0 +1,676 @@
+#!/bin/sh
+: ${DIALOG=dialog}
+
+TAR=tar
+
+# program name:
+program=`basename $0`
+
+#  1 = tar returned error code
+#  2 = failed read package info
+#  3 = does not end in .txz
+#  4 = not a file
+# 11 = broken .PKGINFO
+# 12 = broken .DESCRIPTION
+# 13 = permission denied (should be root)
+# 14 = broken .pkglist or user pkglist
+# 15 = priority has not specified arter --priority option
+# 16 = root path has not specified arter --root option
+# 17 = exit if called with no arguments
+# 19 =  pre update script returns bad status
+# 20 = post update script returns bad status
+# 21 =  pre Remove script returns bad status
+# 22 = post Remove script returns bad status
+# 23 = package is not installed correctly
+# 24 = {Setup | Package} database directory doesn't exist.
+# 25 = There are not resolved requires
+# 92 = Cannot create '/tmp/...' directory
+# 99 = user abort from menu mode
+EXITSTATUS=0
+
+CWD=`pwd`
+
+umask 002
+if [ ! -z "$TMPDIR" ] ; then mkdir -p $TMPDIR ; fi
+TMP=$(mkdir -p /tmp/radix && mktemp -d -p /tmp/radix pkgtool.XXXXXXXX) || { echo "Cannot create '/tmp/...' directory" ; exit 92; }
+trap "rm -rf $TMP" EXIT
+
+
+usage() {
+ cat << EOF
+
+Usage: $program [options] package_tarball[s]
+
+$program is used to update a *.txz package like this:
+   $program /packagesdir/pkgtool-0.0.1-x86_64-glibc-radix-1.0.txz
+
+options:
+   --root /dest    - install someplace else, like /dest;
+   --skip-requires - skip checking required packages;
+   --infodialog    - use dialog to draw an info box;
+   --menudialog    - confirm package installation with a menu, unless
+                     the priority is [required];
+   --always-ask    - used with menudialog mode: always ask if a package should be
+                     installed regardless of what the package's priority is;
+   --priority {required|recommended|optional|skip} -
+                     provide a priority for the entire package list
+                     to use instead of the priority in the .pkglist file;
+   --pkglist /path/file -
+                     specify a different file to use for package priorities.
+                     The default is ".pkglist" in the package's directory.
+
+EOF
+}
+
+package_info() {
+  xzcat $1 | $TAR -xvf - ".PKGINFO" -O  1> $TMP/pkginfo$$  2> /dev/null
+  if [ ! "$?" = "0" ]; then
+    echo "ERROR: Cannot extract package info from $1"
+    EXITSTATUS=1
+    exit $EXITSTATUS
+  fi
+  if [ -f "$TMP/pkginfo$$" ]; then
+    . $TMP/pkginfo$$
+    # check variables:
+    if [ "$pkgname" = "" -o "$pkgver" = "" -o "$arch" = "" -o "$distroname" = "" -o "$distrover" = "" ]; then
+      echo "ERROR: The file '.PKGINFO' doesn't contain necessary declarations."
+      EXITSTATUS=11
+      exit $EXITSTATUS
+    fi
+  else
+    echo "ERROR: There is no package info in $1"
+    EXITSTATUS=2
+    exit $EXITSTATUS
+  fi
+  rm -f $TMP/pkginfo$$
+  compressed_size=$(du -s -h "$1" | sed 's/[\t].*$//')
+}
+
+package_description() {
+  # do not forget to remove $TMP/description$$ after using.
+  xzcat $1 | $TAR -xvf - ".DESCRIPTION" -O  1> $TMP/description$$  2> /dev/null
+  if [ ! "$?" = "0" ]; then
+    echo "ERROR: Cannot extract package description from $1"
+    EXITSTATUS=1
+    exit $EXITSTATUS
+  fi
+  if [ -f "$TMP/description$$" ]; then
+    if [ ! -s "$TMP/description$$" ]; then
+      echo "ERROR: The file '.DESCRIPTION' doesn't contain necessary information."
+      EXITSTATUS=11
+      exit $EXITSTATUS 
+    fi
+  else
+    echo "ERROR: There is no package description in $1"
+    EXITSTATUS=2
+    exit $EXITSTATUS
+  fi
+}
+
+strip_description() {
+  infile=$1
+  outfile=$2
+  echo " " > $outfile
+  LINENUMS="`cat $infile | grep -n -e "^$pkgname:" | cut -f 1 -d ':'`"
+  if [ "$LINENUMS" = "" ]; then
+    echo "WARNING: Description is empty or corrupted."
+    return
+  fi
+  for LINENUM in $LINENUMS ; do
+    LINE="`sed -n "$LINENUM p" $infile | sed -e "s/^$pkgname://"`"
+    if [ "$LINE" = "" ]; then
+       LINE=" "
+    else
+       LINE="`echo "$LINE" | sed -e "s/ $//g"`"
+    fi
+    echo "$LINE" >> $outfile
+  done
+}
+
+
+pkglist_get_priority() {
+  listfile=$1
+  # check only first accurence in this procedure
+  LINENUM="`cat $listfile | grep -m 1 -n -e "^$pkgname:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM" = "" ]; then
+    ret=""
+    return 1
+  fi
+  LINE="`sed -n "$LINENUM p" $listfile`"
+  ret="`echo "$LINE" | cut -f 6 -d ':'`"
+  if   [ "$ret" = "required"    -o "$ret" = "req" -o "$ret" = "REQUIRED"    -o "$ret" = "REQ" ]; then
+    ret="REQUIRED"
+  elif [ "$ret" = "recommended" -o "$ret" = "rec" -o "$ret" = "RECOMMENDED" -o "$ret" = "REC" ]; then
+    ret="RECOMMENDED"
+  elif [ "$ret" = "optional"    -o "$ret" = "opt" -o "$ret" = "OPTIONAL"    -o "$ret" = "OPT" ]; then
+    ret="OPTIONAL"
+  elif [ "$ret" = "skip"        -o "$ret" = "skp" -o "$ret" = "SKIP"        -o "$ret" = "SKP" ]; then
+    ret="SKIP"
+  fi
+  if [ ! "$ret" = "REQUIRED" -a ! "$ret" = "RECOMMENDED" -a ! "$ret" = "OPTIONAL" -a ! "$ret" = "SKIP" ]; then
+    ret=""
+    return 1
+  fi
+  return 0
+}
+
+
+set_references() {
+  logfile=$1
+  references=$2
+
+  cat $references | sed '/^\s*$/d' > $TMP/refsfile$$
+
+  refs="`cat $TMP/refsfile$$ | wc -l`"
+  LINENUM_REF="`cat $logfile | grep -n -e "REFERENCE COUNTER:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_REF" = "" ]; then
+    echo "$program: WARNING: reference counter is not present in $logfile ."
+    return
+  fi
+  LINE="`sed -n "$LINENUM_REF p" $logfile`"
+  oldrefs="`echo "$LINE" | sed -e 's/^REFERENCE COUNTER: //'`"
+  if [ ! "$oldrefs" = "" ]; then
+    sed -i "$LINENUM_REF s/$oldrefs/$refs/" $logfile
+  fi
+
+  sed -i "/^REFERENCE COUNTER:/r $TMP/refsfile$$" $logfile
+}
+
+
+#
+# Parse options:
+#
+MODE=console # standard text-mode
+while [ 0 ]; do
+  if [ "$1" = "-h" -o "$1" = "--help" ]; then
+    usage
+    exit 0
+  elif [ "$1" = "--skip-requires" ]; then
+    SKIPREQUIRES="yes"
+    shift 1
+  elif [ "$1" = "--infodialog" ]; then
+    MODE=infodialog
+    shift 1
+  elif [ "$1" = "--menudialog" ]; then
+    MODE=menudialog
+    shift 1
+  elif [ "$1" = "--always-ask" ]; then
+    ALWAYSASK="yes"
+    shift 1
+  elif [ "$1" = "--pkglist" ]; then
+    if [ -r "$2" ]; then
+      USERPKGLIST="$2"
+    elif [ -r "$CWD/$2" ]; then
+      USERPKGLIST="$CWD/$2"
+    else
+      usage
+      echo "ERROR: Wrong pkglist file. Check --pkglist option."
+      EXITSTATUS=14
+      exit $EXITSTATUS
+    fi
+    shift 2
+  elif [ "$1" = "--priority" ]; then
+    if [ "$2" = "" ]; then
+      usage
+      echo "ERROR: Priority has not specified. Check --priority option."
+      EXITSTATUS=15
+      exit $EXITSTATUS
+    fi
+    USERPRIORITY="$2"
+    if   [ "$USERPRIORITY" = "required"    -o "$USERPRIORITY" = "req" -o "$USERPRIORITY" = "REQUIRED"    -o "$USERPRIORITY" = "REQ" ]; then
+      USERPRIORITY="REQUIRED"
+    elif [ "$USERPRIORITY" = "recommended" -o "$USERPRIORITY" = "rec" -o "$USERPRIORITY" = "RECOMMENDED" -o "$USERPRIORITY" = "REC" ]; then
+      USERPRIORITY="RECOMMENDED"
+    elif [ "$USERPRIORITY" = "optional"    -o "$USERPRIORITY" = "opt" -o "$USERPRIORITY" = "OPTIONAL"    -o "$USERPRIORITY" = "OPT" ]; then
+      USERPRIORITY="OPTIONAL"
+    elif [ "$USERPRIORITY" = "skip"        -o "$USERPRIORITY" = "skp" -o "$USERPRIORITY" = "SKIP"        -o "$USERPRIORITY" = "SKP" ]; then
+      USERPRIORITY="SKIP"
+    fi
+    if [ ! "$USERPRIORITY" = "REQUIRED" -a ! "$USERPRIORITY" = "RECOMMENDED" -a ! "$USERPRIORITY" = "OPTIONAL" -a ! "$USERPRIORITY" = "SKIP" ]; then
+      usage
+      echo "ERROR: Invalid priority. Check --priority option."
+      EXITSTATUS=15
+      exit $EXITSTATUS
+    fi
+    shift 2
+  elif [ "$1" = "--root" ]; then
+    if [ "$2" = "" ]; then
+      usage
+      echo "ERROR: Target root path has not specified. Check --root option."
+      EXITSTATUS=16
+      exit $EXITSTATUS
+    fi
+    TARGET_ROOT_PATH="$2"
+    shift 2
+  else
+    break
+  fi
+done
+
+#
+# usage(), exit if called with no arguments:
+#
+if [ $# = 0 ]; then
+  usage
+  echo "ERROR: arguments were not specified. Check options."
+  EXITSTATUS=17
+  exit $EXITSTATUS
+fi
+
+if [ "$TARGET_ROOT_PATH" = "" ]; then
+  TARGET_ROOT_PATH="/"
+else
+  TARGET_ROOT_PATH="`echo "$TARGET_ROOT_PATH" | sed -e "s/\/$//"`/"
+fi
+
+if [ "$TARGET_ROOT_PATH" = "/" ]; then
+  if [ ! $UID = "0" ]; then
+    echo "ERROR: Trying to install into root directory: permission denied"
+    EXITSTATUS=13
+    exit $EXITSTATUS
+  fi
+fi
+
+SETUP_DB_PATH=${TARGET_ROOT_PATH}var/log/@DISTRO@
+if [ ! -d $SETUP_DB_PATH ]; then
+  rm -rf $SETUP_DB_PATH # make sure it's not a link
+  mkdir -p $SETUP_DB_PATH
+  chmod 755 $SETUP_DB_PATH
+fi
+
+for PKG_DB_DIR in packages removed_packages setup ; do
+  if [ ! -d $SETUP_DB_PATH/$PKG_DB_DIR ]; then
+    rm -rf $SETUP_DB_PATH/$PKG_DB_DIR # make sure it's not a link
+    mkdir -p $SETUP_DB_PATH/$PKG_DB_DIR
+    chmod 755 $SETUP_DB_PATH/$PKG_DB_DIR
+  fi
+done
+
+LOG_PATH=$SETUP_DB_PATH/setup
+LOG_FILE=$LOG_PATH/setup.log
+
+extract_links() {
+ sed -n 's,^( *cd \([^ ;][^ ;]*\) *; *rm -rf \([^ )][^ )]*\) *) *$,\1/\2,p'
+}
+
+delete_files() {
+  while read FILE ; do
+    if [ ! -d "${TARGET_ROOT_PATH}$FILE" ]; then
+      if [ -r "${TARGET_ROOT_PATH}$FILE" ]; then
+        # "-nt" is "newer than"; "-ot" is "older than":
+        if [ "${TARGET_ROOT_PATH}$FILE" -nt "$logfile" ]; then
+          if [ "$VERBOSE" == "yes" ] ; then
+            echo "WARNING: ${TARGET_ROOT_PATH}$FILE changed after package installation."
+          fi
+        fi
+        if [ "$VERBOSE" == "yes" ] ; then
+          echo " ===> Deleting ${TARGET_ROOT_PATH}$FILE"
+        fi
+        rm -f "${TARGET_ROOT_PATH}$FILE"
+        echo "`dirname $FILE`" >> $TMP/not_sorted_dirs$$
+      else
+        echo " ===> ${TARGET_ROOT_PATH}$FILE no longer exists. Skipping."
+      fi
+    else
+      if [ "$VERBOSE" == "yes" ] ; then
+        echo " ===> ${TARGET_ROOT_PATH}$FILE is a directory. Skipping."
+      fi
+      echo "$FILE" >> $TMP/not_sorted_dirs$$
+    fi
+  done
+}
+
+delete_links() {
+  while read LINK ; do
+    if [ -L "${TARGET_ROOT_PATH}$LINK" ]; then
+      if [ "$VERBOSE" == "yes" ] ; then
+        echo " ===> Deleting symlink ${TARGET_ROOT_PATH}$LINK"
+      fi
+      rm -f ${TARGET_ROOT_PATH}$LINK
+      echo "`dirname $LINK`" >> $TMP/not_sorted_dirs$$
+    else
+      if [ "$VERBOSE" == "yes" ] ; then
+        echo " ===> ${TARGET_ROOT_PATH}$LINK (symlink) no longer exists. Skipping."
+      fi
+    fi
+  done
+}
+
+delete_dirs() {
+  while read DIR ; do
+    if [ -d "${TARGET_ROOT_PATH}$DIR" ]; then
+      if [ `ls -a "${TARGET_ROOT_PATH}$DIR" | wc -l` -eq 2 ]; then
+        if [ "$VERBOSE" == "yes" ] ; then
+          echo " ===> Deleting empty directory ${TARGET_ROOT_PATH}$DIR"
+        fi
+        rmdir "${TARGET_ROOT_PATH}$DIR"
+      else
+        if [ "$VERBOSE" == "yes" ] ; then
+          echo " ===> Preserving non empty directory ${TARGET_ROOT_PATH}$DIR"
+        fi
+      fi
+    fi
+  done
+}
+
+
+remove_installed_files_on_error() {
+  if [ -f $TMP/.RESTORELINKS -a -s $TMP/.RESTORELINKS ]; then
+    cat $TMP/.RESTORELINKS | extract_links | sort -u > $TMP/links$$
+  fi
+
+  if [ -f $TMP/.FILELIST -a -s $TMP/.FILELIST ]; then
+    cat $TMP/.FILELIST | sort -u > $TMP/files$$
+  fi
+
+  rm -f $TMP/not_sorted_dirs$$
+  if [ -f $TMP/links$$ -a -s $TMP/links$$ ]; then
+    delete_links < $TMP/links$$
+  fi
+  rm -f $TMP/links$$
+
+  if [ -f $TMP/files$$ -a -s $TMP/files$$ ]; then
+    delete_files < $TMP/files$$
+  fi
+  rm -f $TMP/files$$
+
+  if [ -f $TMP/not_sorted_dirs$$ -a -s $TMP/not_sorted_dirs$$ ]; then
+    sort -u -r < $TMP/not_sorted_dirs$$ > $TMP/dirs$$
+    rm -f $TMP/not_sorted_dirs$$
+    delete_dirs < $TMP/dirs$$
+    rm -f $TMP/dirs$$
+  fi
+  rm -f $TMP/not_sorted_dirs$$
+}
+
+
+################################################################
+# Main loop:
+#
+for pkgtarball in $* ; do
+  # If someone left off the '.txz', try to figure that out:
+  if [ ! -r "$pkgtarball" -a -r "$pkgtarball.txz" ]; then
+    pkgtarball=$pkgtarball.txz
+  fi
+
+  tarball_noext_name="`basename $pkgtarball .txz`"
+  tarball_src_dir="`dirname $pkgtarball`"
+
+  # Reject package if it does not end in '.txz':
+  if [ ! -r "$tarball_src_dir/$tarball_noext_name.txz" ]; then
+    EXITSTATUS=3
+    if [ "$MODE" = "console" ]; then
+      echo "ERROR: Cannot install $pkgtarball: tarball does not end in .txz"
+    fi
+    continue;
+  fi
+
+  # Simple package integrity check:
+  if [ ! -f $pkgtarball ]; then
+    EXITSTATUS=4
+    if [ "$MODE" = "console" ]; then
+      echo "ERROR: Cannot install $pkgtarball: tarball is not a regular file"
+    fi
+    continue;
+  fi
+
+  # getting pkgname, etc... variables from tarball:
+  package_info $pkgtarball
+
+  # Determine package's priority:
+  unset PRIORITY
+  if [ "$USERPKGLIST" = "" ]; then
+    PKGLIST="$tarball_src_dir/.pkglist"
+  else
+    PKGLIST="$USERPKGLIST"
+  fi
+  if [ ! -r "$PKGLIST" ]; then
+    PKGLIST=/dev/null
+  fi
+
+  # USERPRIORITY overrides .pkglist priority
+  if [ "$USERPRIORITY" = "" ]; then
+    pkglist_get_priority "$PKGLIST"
+    PRIORITY=$ret
+  else
+    PRIORITY=$USERPRIORITY
+  fi
+
+  if   [ "$PRIORITY" = "REQUIRED" ]; then
+    PMSG="[required]"
+  elif [ "$PRIORITY" = "RECOMMENDED" ]; then
+    PMSG="[recommended]"
+  elif [ "$PRIORITY" = "OPTIONAL" ]; then
+    PMSG="[optional]"
+  elif [ "$PRIORITY" = "SKIP" ]; then
+    PMSG="[skip]"
+  else
+    PMSG=""
+  fi
+
+  package_description $pkgtarball
+  strip_description "$TMP/description$$" "$TMP/msg$$"
+  rm -f $TMP/description$$
+
+  echo " Uncompressed Size: $uncompressed_size" >> $TMP/msg$$
+  echo "   Compressed Size: $compressed_size"   >> $TMP/msg$$
+
+  # Emit information to the console:
+  if [ "$MODE" = "console" -a ! "$PRIORITY" = "SKIP" ]; then
+    echo ""
+    if [ "$PMSG" = "" ]; then
+      echo " Update package $pkgname... "
+    else
+      echo " Update package $pkgname $PMSG... "
+    fi
+    ####  |---handy-ruler--------------------------------------------------------|
+    echo "|======================================================================|"
+    echo "`cat $TMP/msg$$`"
+    echo "|======================================================================|"
+    echo ""
+  elif [ "$MODE" = "infodialog" -a ! "$PRIORITY" = "SKIP" ]; then
+    # install non-SKIP package:
+    $DIALOG --colors \
+            --backtitle "\Z7Radix\Zn \Z1Pro\Zn\Z7, Ltd.\Zn" \
+            --title " \Z4Update package ==>\Zn\Z1$pkgname\Zn\Z4<== $PMSG\Zn " \
+            --infobox "`cat $TMP/msg$$`" 16 74
+  elif [ "$MODE" = "menudialog" -a "$PRIORITY" = "REQUIRED" -a ! "$ALWAYSASK" = "yes" ]; then
+    # REQUIRED overrides menu mode unless -ask was used
+    $DIALOG --colors \
+            --backtitle "\Z7Radix\Zn \Z1Pro\Zn\Z7, Ltd.\Zn" \
+            --title " \Z4Update package ==>\Zn\Z1$pkgname\Zn\Z4<== $PMSG\Zn " \
+            --infobox "`cat $TMP/msg$$`" 16 74
+  elif [ "$MODE" = "menudialog" -a "$PRIORITY" = "SKIP" -a ! "$ALWAYSASK" = "yes" ]; then
+    # SKIP overrides menu mode unless -ask used
+    rm -f $TMP/msg$$
+    continue # next package
+  elif [ "$MODE" = "infodialog" -a "$PRIORITY" = "SKIP" ]; then
+    # SKIP overrides infobox mode, too
+    rm -f $TMP/msg$$
+    continue # next package
+  elif [ "$MODE" = "console" -a "$PRIORITY" = "SKIP" ]; then
+    # SKIP overrides console mode, too
+    rm -f $TMP/msg$$
+    continue # next package
+  else # we must need a full menu:
+    $DIALOG --colors \
+            --backtitle "\Z7Radix\Zn \Z1Pro\Zn\Z7, Ltd.\Zn" \
+            --title " \Z4Package Name: ==>\Zn\Z1$pkgname\Zn\Z4<== $PMSG\Zn " \
+            --menu "`cat $TMP/msg$$`" 0 0 3 \
+    "Yes" "Update package $pkg_name" \
+    "No" "Do not update package $pkg_name" \
+    "Quit" "Abort software installation completely" 2> $TMP/reply$$
+    if [ ! $? = 0 ]; then
+      echo "No" > $TMP/reply$$
+    fi
+    REPLY="`cat $TMP/reply$$`"
+    rm -f $TMP/reply$$ $TMP/msg$$
+    if [ "$REPLY" = "Quit" ]; then
+      rm -f $TMP/msg$$
+      exit 99 # ABORT!
+    elif [ "$REPLY" = "No" ]; then
+      rm -f $TMP/msg$$
+      continue # skip the package
+    fi
+    # Waiting info dialog
+    $DIALOG --sleep 1 --colors \
+            --backtitle "\Z7Radix\Zn \Z1Pro\Zn\Z7, Ltd.\Zn" \
+            --title " \Z4Update package ==>\Zn\Z1$pkgname\Zn\Z4<== $PMSG\Zn " \
+            --infobox "\nPlease wait till package is updated.\n" 5 74
+  fi
+  rm -f $TMP/msg$$
+
+  # Check how the package is installed:
+  # ==================================
+  logfile=`find $SETUP_DB_PATH/packages -type f -name "$pkgname-[0-9]*-$arch-$distroname-$distrover"`
+  # ================ NOTE that version always starts from some ^======^ digit
+  logfile=`basename $logfile`
+
+  # get version of installed package, set full path to logfile
+  if [ ! "$logfile" = "" ] ; then
+    oldpkgver=`echo $logfile | sed "s,$pkgname-\(.*\)-$arch-$distroname-$distrover,\1,g"`
+    logfile=$SETUP_DB_PATH/packages/$pkgname-$oldpkgver-$arch-$distroname-$distrover
+  else
+    # package is not installed
+    echo "ERROR: Package is not installed."
+    echo "ERROR: Package is not installed." >> $LOG_FILE
+    EXITSTATUS=23
+    break
+  fi
+
+  check-package --dark --root $TARGET_ROOT_PATH $logfile
+  ret=$?
+  if [ $ret -eq 30 ]; then
+    # package is installed correctly, save references into $TMP/.REFERENCES:
+    pkginfo --dest $TMP references $logfile
+  elif [ $ret -eq 32 ]; then
+    # package is installed but not correct, save references into $TMP/.REFERENCES:
+    pkginfo --dest $TMP references $logfile
+  fi
+
+  # Install process:
+  echo -n "[`LANG=en LANGUAGE=en date +'%d-%b-%Y %H:%M:%S'`] " >> $LOG_FILE
+  echo -n "Updatining: `basename $pkgtarball`: "               >> $LOG_FILE
+
+  DEST=$TARGET_ROOT_PATH
+
+  # Check requires:
+  # ==============
+  if [ ! "$SKIPREQUIRES" = "yes" ]; then
+    check-requires --root $DEST $pkgtarball 2> $TMP/freqs$$ 1> $TMP/hreqs$$
+    if [ -s $TMP/freqs$$ ]; then
+      echo "ERROR: There are not resolved requires." >> $LOG_FILE
+      if [ "$MODE" = "console" ]; then
+        echo "ERROR: There are not resolved requires."
+        cat $TMP/hreqs$$
+      else
+        cat > $TMP/not_resolved_reqs$$ << EOF
+
+\Z1ERROR:\Zn \Z4There are not resolved requires.\Zn
+
+Check the missing packages using the 'check-requires' utility and,
+if necessary, install them.
+
+EOF
+        $DIALOG --sleep 3 --colors \
+                --backtitle "\Z1Radix\Zn \Z7Pro\Zn\Z1, Ltd.\Zn" \
+                --title " \Z4Update package ==>\Zn\Z1$pkgname\Zn\Z4<== $PMSG\Zn " \
+                --infobox "`cat $TMP/not_resolved_reqs$$`" 8 74
+        rm -f $TMP/not_resolved_reqs$$
+      fi
+      rm -f $TMP/freqs$$ $TMP/hreqs$$
+      EXITSTATUS=22
+      exit $EXITSTATUS
+    fi
+    rm -f $TMP/freqs$$ $TMP/hreqs$$
+  fi
+
+  # unpack package service files:
+  cat << EOF > $TMP/pkg.service.files$$
+.DESCRIPTION
+.FILELIST
+.INSTALL
+.PKGINFO
+.REQUIRES
+.RESTORELINKS
+EOF
+  xzcat $pkgtarball | $TAR -C $TMP --files-from=$TMP/pkg.service.files$$ -xf - > /dev/null 2>&1
+  ( cd $DEST
+    if [ -x $TMP/.INSTALL ]; then
+      $TMP/.INSTALL pre_update $oldpkgver $pkgver > /dev/null 2>&1
+      if [ ! "$?" = "0" ]; then
+        echo "ERROR: Pre Update script returns bad status."
+        echo "ERROR: Pre Update script returns bad status." >> $LOG_FILE
+        EXITSTATUS=19
+        exit $EXITSTATUS
+      fi
+    fi
+    remove-package --without-logs --dark --skip-refs --root $TARGET_ROOT_PATH $logfile
+  )
+  EXITSTATUS=$?
+  if [ ! "$EXITSTATUS" = "0" ]; then
+    break
+  fi
+  # unpack archive excluding service files:
+  xzcat $pkgtarball | $TAR -C $DEST --exclude-from=$TMP/pkg.service.files$$ -xpf -  > /dev/null 2>&1
+  if [ ! "$?" = "0" ]; then
+    echo "ERROR: $TAR has returned error code."
+    echo "ERROR: $TAR has returned error code." >> $LOG_FILE
+    EXITSTATUS=1
+    exit $EXITSTATUS
+  fi
+  ( cd $DEST
+    if [ -f $TMP/.RESTORELINKS ]; then
+      sh $TMP/.RESTORELINKS
+    fi
+    pkglog $TMP/.PKGINFO $SETUP_DB_PATH/packages  > /dev/null 2>&1
+    if [ ! "$?" = "0" ]; then
+      echo "ERROR: Log file has not been created."
+      echo "ERROR: Log file has not been created." >> $LOG_FILE
+      remove_installed_files_on_error
+      ( . $TMP/.PKGINFO
+        cd $SETUP_DB_PATH/packages; rm -f "$pkgname-$pkgver-$arch-$distroname-$distrover"
+      )
+      EXITSTATUS=23
+      exit $EXITSTATUS
+    fi
+    if [ -x $TMP/.INSTALL ]; then
+      $TMP/.INSTALL post_update $oldpkgver $pkgver > /dev/null 2>&1
+      if [ ! "$?" = "0" ]; then
+        echo "ERROR: Post Update script returns bad status."
+        echo "ERROR: Post Update script returns bad status." >> $LOG_FILE
+        remove_installed_files_on_error
+        ( . $TMP/.PKGINFO
+          cd $SETUP_DB_PATH/packages; rm -f "$pkgname-$pkgver-$arch-$distroname-$distrover"
+        )
+        EXITSTATUS=20
+        exit $EXITSTATUS
+      fi
+    fi
+    # Increase REFERENCE COUNTER in the required packages:
+    ( . $TMP/.PKGINFO
+      cd $SETUP_DB_PATH/packages; change-refs inc "$pkgname-$pkgver-$arch-$distroname-$distrover"
+    )
+    # check deprecated log file:
+    ( . $TMP/.PKGINFO
+      cd $SETUP_DB_PATH/removed_packages; rm -f "$pkgname-$pkgver-$arch-$distroname-$distrover"
+    )
+    # restore references:
+    if [ -f $TMP/.REFERENCES -a -s $TMP/.REFERENCES ]; then
+      cat $TMP/.REFERENCES | sort -u > $TMP/references$$
+      ( cd $SETUP_DB_PATH/packages
+        set_references "$pkgname-$pkgver-$arch-$distroname-$distrover" $TMP/references$$
+      )
+    fi
+  )
+  EXITSTATUS=$?
+  if [ ! "$EXITSTATUS" = "0" ]; then
+    break
+  fi
+  echo "SUCCESS: Package has been updated." >> $LOG_FILE
+done
+#
+# End of Main loop.
+################################################################
+
+exit $EXITSTATUS
Index: build-system-1.2.3/pkgtool/doc/init/.INSTALL
===================================================================
--- build-system-1.2.3/pkgtool/doc/init/.INSTALL	(nonexistent)
+++ build-system-1.2.3/pkgtool/doc/init/.INSTALL	(revision 231)
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+# arg 1:  the new package version
+pre_install() {
+  /bin/true
+}
+
+# arg 1:  the new package version
+post_install() {
+  # example to replace old file by new one
+#  if [ -r usr/bin/kxLibc-config ]; then
+#    mv usr/bin/kxLibc-config usr/bin/kxLibc-config.old
+#  fi
+#  mv usr/bin/kxLibc-config.new usr/bin/kxLibc-config
+#  if [ -f usr/bin/kxLibc-config.old ]; then
+#    rm -f usr/bin/kxLibc-config.old
+#  fi
+  /bin/true
+}
+
+# arg 1:  the new package version
+# arg 2:  the old package version
+pre_update() {
+  /bin/true
+}
+
+# arg 1:  the new package version
+# arg 2:  the old package version
+post_update() {
+  post_install
+}
+
+# arg 1:  the old package version
+pre_remove() {
+  /bin/true
+}
+
+# arg 1:  the old package version
+post_remove() {
+  /bin/true
+}
+
+
+operation=$1
+shift
+
+$operation $*

Property changes on: build-system-1.2.3/pkgtool/doc/init/.INSTALL
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/pkgtool/doc/init/.PKGINFO
===================================================================
--- build-system-1.2.3/pkgtool/doc/init/.PKGINFO	(nonexistent)
+++ build-system-1.2.3/pkgtool/doc/init/.PKGINFO	(revision 231)
@@ -0,0 +1,10 @@
+pkgname=_kxLibc
+pkgver=1.0.4
+arch=x86_64
+distroname=radix
+distrover=12.2
+group=libs
+###               |---handy-ruler-------------------------------|
+short_description="Long number operations library"
+url=http://www.kxLab.com
+license=Proprietary
Index: build-system-1.2.3/pkgtool/doc/init/.DESCRIPTION
===================================================================
--- build-system-1.2.3/pkgtool/doc/init/.DESCRIPTION	(nonexistent)
+++ build-system-1.2.3/pkgtool/doc/init/.DESCRIPTION	(revision 231)
@@ -0,0 +1,19 @@
+# HOW TO EDIT THIS FILE:
+# The "handy ruler" below makes it easier to edit a package description.  Line
+# up the first '|' above the ':' following the base package name, and the '|'
+# on the right side marks the last column you can put a character in.  You must
+# make exactly 11 lines for the formatting to be correct.  It's also
+# customary to leave one space after the ':'.
+
+       |-----handy-ruler------------------------------------------------------|
+_kxLibc: _kxLibc version 1.0.4.
+_kxLibc:
+_kxLibc: The _kxLibc - is a library for long arithmetic operations.
+_kxLibc:
+_kxLibc:
+_kxLibc:
+_kxLibc:
+_kxLibc:
+_kxLibc:
+_kxLibc:
+_kxLibc:
Index: build-system-1.2.3/pkgtool/doc/init/.REQUIRES
===================================================================
--- build-system-1.2.3/pkgtool/doc/init/.REQUIRES	(nonexistent)
+++ build-system-1.2.3/pkgtool/doc/init/.REQUIRES	(revision 231)
@@ -0,0 +1,2 @@
+pth=2.0.7
+pkg=
Index: build-system-1.2.3/pkgtool/make-pkglist
===================================================================
--- build-system-1.2.3/pkgtool/make-pkglist	(nonexistent)
+++ build-system-1.2.3/pkgtool/make-pkglist	(revision 231)
@@ -0,0 +1,203 @@
+#!/bin/sh
+
+TAR=tar
+
+# program name:
+program=`basename $0`
+
+#  1 = tar returned error code
+#  2 = failed read package info
+#  3 = does not end in .txz
+#  4 = not a file
+# 11 = broken .PKGINFO
+# 14 = broken declaration of user pkglist
+# 15 = priority has not specified arter --priority option
+# 92 = Cannot create '/tmp/...' directory
+# 99 = user abort from menu mode
+EXITSTATUS=0
+
+CWD=`pwd`
+
+umask 022
+if [ ! -z "$TMPDIR" ] ; then mkdir -p $TMPDIR ; fi
+TMP=$(mkdir -p /tmp/radix && mktemp -d -p /tmp/radix pkgtool.XXXXXXXX) || { echo "Cannot create '/tmp/...' directory" ; exit 92; }
+trap "rm -rf $TMP" EXIT
+
+
+usage() {
+ cat << EOF
+
+Usage: cd /pkg_tarballs_dir; $program
+
+$program is used to create '.pkglist' file by info is presented in package
+tarballs which placed in the current directory.
+
+options:
+   --priority {required|recommended|optional|skip} -
+                  provide a priority for the entire package list.
+                  The default is "RECOMMENDED";
+   --pkglist /path/file -
+                  specify a different file to store the list.
+                  The default is ".pkglist" in the current directory.
+
+EOF
+}
+
+package_info() {
+  xzcat $1 | $TAR -xvf - ".PKGINFO" -O  1> $TMP/pkginfo$$  2> /dev/null
+  if [ ! "$?" = "0" ]; then
+    echo "ERROR: Cannot extract package info from $1"
+    EXITSTATUS=1
+    exit $EXITSTATUS
+  fi
+  if [ -f "$TMP/pkginfo$$" ]; then
+    . $TMP/pkginfo$$
+    # check variables:
+    if [ "$pkgname" = "" -o "$pkgver" = "" -o "$arch" = "" -o "$distroname" = "" -o "$distrover" = "" ]; then
+      echo "ERROR: The file '.PKGINFO' doesn't contain necessary declarations."
+      EXITSTATUS=11
+      exit $EXITSTATUS 
+    fi
+  else
+    echo "ERROR: There is no package info in $1"
+    EXITSTATUS=2
+    exit $EXITSTATUS
+  fi
+  rm -f $TMP/pkginfo$$
+}
+
+
+#
+# Parse options:
+#
+while [ 0 ]; do
+  if [ "$1" = "-h" -o "$1" = "--help" ]; then
+    usage
+    exit 0
+  elif [ "$1" = "--pkglist" ]; then
+    if [ "$2" = "" ]; then
+      usage
+      echo "ERROR: Wrong pkglist file name. Check --pkglist option."
+      EXITSTATUS=14
+      exit $EXITSTATUS
+    fi
+    PKGLIST="$2"
+    shift 2
+  elif [ "$1" = "--priority" ]; then
+    if [ "$2" = "" ]; then
+      usage
+      echo "ERROR: Priority has not specified. Check --priority option."
+      EXITSTATUS=15
+      exit $EXITSTATUS
+    fi
+    PRIORITY="$2"
+    if   [ "$PRIORITY" = "required"    -o "$PRIORITY" = "req" -o "$PRIORITY" = "REQUIRED" -o "$PRIORITY" = "REQ" ]; then
+      PRIORITY="REQUIRED"
+    elif [ "$PRIORITY" = "recommended" -o "$PRIORITY" = "rec" -o "$PRIORITY" = "RECOMMENDED" -o "$PRIORITY" = "REC" ]; then
+      PRIORITY="RECOMMENDED"
+    elif [ "$PRIORITY" = "optional"    -o "$PRIORITY" = "opt" -o "$PRIORITY" = "OPTIONAL" -o "$PRIORITY" = "OPT" ]; then
+      PRIORITY="OPTIONAL"
+    elif [ "$PRIORITY" = "skip"        -o "$PRIORITY" = "skp" -o "$PRIORITY" = "SKIP" -o "$PRIORITY" = "SKP" ]; then
+      PRIORITY="SKIP"
+    fi
+    if [ ! "$PRIORITY" = "REQUIRED" -a ! "$PRIORITY" = "RECOMMENDED" -a ! "$PRIORITY" = "OPTIONAL" -a ! "$PRIORITY" = "SKIP" ]; then
+      usage
+      echo "ERROR: Invalid priority. Check --priority option."
+      EXITSTATUS=15
+      exit $EXITSTATUS
+    fi
+    shift 2
+  else
+    break
+  fi
+done
+
+if [ "$PKGLIST" = "" ]; then
+  PKGLIST=".pkglist"
+fi
+
+if [ "$PRIORITY" = "" ]; then
+  PRIORITY="RECOMMENDED"
+fi
+
+probe=`find $CWD -name "*.txz" > /dev/null 2>&1`
+if [ ! "$?" = "0" ]; then
+  usage
+  echo "WARNING: There are not package tarballs in current directory."
+  echo ""
+  exit 0
+fi
+
+  cat > $PKGLIST << EOF
+#
+# file format:
+# ===========
+#
+# Each line contains six fields separated by colon symbol ':' like following.
+#
+# pkgname:version:description:tarball:procedure:priority
+#
+# where:
+#
+#   pkgname     - should be the same as the value of pkgname  in the '.DESCRIPTION' file;
+#   version     - package version for showing in check list  dialog box  if this file is
+#                 used to complete common check dialog for installing group  of packages;
+#   description - short description for showing in check list dialog box if this file is
+#                 used to complete common check dialog for installing  group of packages;
+#   tarball     - should end in '.txz';
+#   procedure   - installation procedure {install | update}:
+#                  * 'install' - if package requires normal installation,
+#                  * 'update'  - if already installed package should be updated by this
+#                                package archive;
+#   priority    - { REQUIRED|RECOMMENDED|OPTIONAL|SKIP }
+#                  synonims:
+#                    { REQUIRED    | required    | REQ | req }
+#                    { RECOMMENDED | recommended | REC | rec }
+#                    { OPTIONAL    | optional    | OPT | opt }
+#                    { SKIP        | skip        | SKP | skp }
+#
+EOF
+
+################################################################
+# Main loop:
+#
+for pkgtarball in `find $CWD -name "*.txz"` ; do
+
+  pkgtarball=`echo $pkgtarball | sed s,$CWD/,,`
+
+  # Simple package integrity check:
+  if [ ! -f $pkgtarball ]; then
+    EXITSTATUS=4
+    if [ "$MODE" = "console" ]; then
+      echo "ERROR: $pkgtarball: tarball is not a regular file"
+    fi
+    continue;
+  fi
+
+  # getting pkgname, etc... variables from tarball:
+  package_info $pkgtarball
+
+  # optional declaration:
+  if [ "$short_description" = "" ]; then
+    short_description="There is no description"
+  fi
+
+  #
+  # In Makefiles we have to mask characters '\', '&', '*', '(', ')' inside
+  # the new value in the assignment operator with backslash. So, for axample,
+  # the value "name & \ * ( ) end" we have to assign as follow
+  #
+  # ..._SHORT_DESCRIPTION = name \& \\ \* \( \) end
+  #
+  # Here we have to remove backslashes and fill escaped symbols as is:
+  #
+  echo -n  "$pkgname:$pkgver:"                         >> $PKGLIST
+  echo -n   $short_description | sed "s,[\]\(.\),\1,g" >> $PKGLIST
+  echo    ":$pkgtarball:install:$PRIORITY"             >> $PKGLIST
+
+done
+#
+# End of Main loop.
+################################################################
+
+exit $EXITSTATUS

Property changes on: build-system-1.2.3/pkgtool/make-pkglist
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/pkgtool/check-db-integrity.in
===================================================================
--- build-system-1.2.3/pkgtool/check-db-integrity.in	(nonexistent)
+++ build-system-1.2.3/pkgtool/check-db-integrity.in	(revision 231)
@@ -0,0 +1,306 @@
+#!/usr/bin/perl
+
+use IO::File;
+use File::Basename;
+use File::Copy;
+use DirHandle;
+use POSIX qw(tmpnam);
+
+my $TMP = "/tmp";
+
+my ( $target_root_path, $setup_db_path, $remove_deprecated_refs );
+my ( @pkglogs );
+my ( %by_pkg_name );
+
+my $program = basename( $0 );
+
+# initial values:
+$setup_db_path = $target_root_path = "";
+
+
+sub usage {
+    print <<END;
+
+Usage: $program [options]
+
+options:
+  -h, --help             display this help and exit;
+  [ --root <path> ]      destination path ( default: / ),
+                         the <path> should be absolute path;
+  --rm-dep-refs, --rm-deprecated-refs
+                         remove deprecated references if it is possible,
+                         ( default: is not set ).
+
+END
+}
+
+sub logfiles {
+  my $dir = $_[0];
+  my $dh = DirHandle->new( $dir ) or die "Cannot open dir $dir: $!\n";
+  return sort
+    grep { -f }        # regular files
+     map { "$dir/$_" } # complete full path
+    grep { !/^\./ }    # do not show hiden files
+    $dh->read();       # read all
+}
+
+sub read_requires
+{
+  my $logfile = $_[0];
+  my @requires;
+
+  open( PKGLOG, "< $logfile" ) or die "Cannot open $logfile: $!\n";
+  while( <PKGLOG> )
+  {
+    if( /REQUIRES:/ .. /PACKAGE DESCRIPTION:/ )
+    {
+      chomp;
+      push( @requires, $_ );
+    }
+  }
+  close( PKGLOG );
+
+  shift( @requires ); # delete first element without save his value
+    pop( @requires ); # delete  last element without save his value
+
+  return @requires;
+}
+
+sub read_references
+{
+  my $logfile = $_[0];
+  my @references;
+
+  open( PKGLOG, "< $logfile" ) or die "Cannot open $logfile: $!\n";
+  while( <PKGLOG> )
+  {
+    if( /REFERENCE COUNTER:/ .. /REQUIRES:/ )
+    {
+      chomp;
+      push( @references, $_ );
+    }
+  }
+  close( PKGLOG );
+
+  shift( @references ); # delete first element without save his value
+    pop( @references ); # delete  last element without save his value
+
+  return @references;
+}
+
+sub read_name
+{
+  my $logfile = $_[0];
+  my $name;
+
+  open( PKGLOG, "< $logfile" ) or die "Cannot open $logfile: $!\n";
+  while( <PKGLOG> )
+  {
+    if( /PACKAGE NAME:/ )
+    {
+      chomp;
+      s/PACKAGE NAME: //;
+      $name = $_;
+    }
+  }
+  close( PKGLOG );
+
+  return $name;
+}
+
+sub read_version
+{
+  my $logfile = $_[0];
+  my $version;
+
+  open( PKGLOG, "< $logfile" ) or die "Cannot open $logfile: $!\n";
+  while( <PKGLOG> )
+  {
+    if( /PACKAGE VERSION:/ )
+    {
+      chomp;
+      s/PACKAGE VERSION: //;
+      $version = $_;
+    }
+  }
+  close( PKGLOG );
+
+  return $version;
+}
+
+sub rm_deprecated_ref
+{
+  my $log = $_[0];
+  my $ref = $_[1];
+  my ( $lineno_ref, $lineno_counter );
+
+  $lineno_ref = $lineno_counter = 0;
+
+  open( PKGLOG, "< $log" ) or die "Cannot open $log: $!\n";
+  while( <PKGLOG> )
+  {
+    if( /REFERENCE COUNTER:/ ) { $lineno_counter = $.; }
+    if( /REFERENCE COUNTER:/ .. /REQUIRES:/ )
+    {
+      chomp;
+      if( $_ =~ m/$ref/ ) { $lineno_ref = $.; }
+    }
+  }
+  close( PKGLOG );
+
+  if( $lineno_counter != 0 && $lineno_ref != 0 )
+  {
+    my $fname, $fh;
+
+    do { $fname = tmpnam() }
+      until $fh = IO::File->new( "$fname", O_RDWR | O_CREAT | O_EXCL );
+    $fh->autoflush( 1 ); # important!
+    # we do not use unlink(): see move() at END.
+    # END { unlink( $fname ) or die "Cannot unlink $fname: $!\n"; }
+
+    open( PKGLOG, "< $log" ) or die "Cannot open $log: $!\n";
+    while( <PKGLOG> )
+    {
+      if( /REFERENCE COUNTER: (\d+)/ )
+      {
+        my ( $new_ref, $line );
+        chomp;
+        $line = $_;
+        $new_ref = $1; # $1 contains the ref counter digits: see (\d+) above.
+        if( $new_ref != 0 ) { --$new_ref; $line = "REFERENCE COUNTER: $new_ref"; }
+        print $fh "$line\n";
+      }
+      if( /REFERENCE COUNTER:/ .. /REQUIRES:/ )
+      {
+        chomp;
+        if( $lineno_ref != $. && ! (/REFERENCE COUNTER:/) ) { print $fh "$_\n"; }
+      }
+      if( ! ( /REFERENCE COUNTER:/ .. /REQUIRES:/ ) ) { print $fh "$_"; }
+    }
+    close( PKGLOG );
+    move( $fname, $log ) or die "Cannot move $fname to $log: $!\n";
+    return 1;
+  }
+  return 0;
+}
+
+while( my $arg = shift )
+{
+  for( $arg )
+  {
+    if( /^-h$/ || /^--help$/ )
+    {
+      usage;
+      exit 0;
+    }
+    elsif ( /^--rm-deprecated-refs$/ || /^--rm-dep-refs$/ )
+    {
+      $remove_deprecated_refs = "yes";
+    }
+    elsif ( /^--root$/)
+    {
+      $target_root_path = shift;
+    }
+    else
+    {
+      die "\nUnknown option: $arg\n\n";
+    }
+  }
+}
+
+if( $target_root_path eq "" ) { $target_root_path = "/"; }
+if( $target_root_path ne "/" ) # add last / if not exist:
+{
+  if( ! ($target_root_path =~ m/\/$/ ) ) { $target_root_path .= "/"; }
+}
+$setup_db_path = "$target_root_path" . "var/log/@DISTRO@/packages";
+
+
+################################################################
+# Main:
+#
+@pkglogs = logfiles( $setup_db_path );
+
+# fill %by_pkg_name hash:
+foreach my $pkglog ( @pkglogs )
+{
+  my @refs = read_references( $pkglog );
+  my @reqs = read_requires( $pkglog );
+  my $pnam = read_name( $pkglog );
+  my $pver = read_version( $pkglog );
+
+  $record =
+  {
+    NAME       => "$pnam",
+    VERSION    => "$pver",
+    PKGLOG     => "$pkglog",
+    REQUIRES   => [ "" ],
+    REFERENCES => [ "" ],
+  };
+
+  @{$record->{REQUIRES}}   = @reqs;
+  @{$record->{REFERENCES}} = @refs;
+
+  $by_pkg_name{ $record->{NAME}} = $record;
+}
+
+
+# REQUIRED PACKAGES:
+# =================
+printf "\nREQUIRED PACKAGES:\n";
+while( ($name, $rec) = each %by_pkg_name )
+{
+  my @requires;
+
+  @requires = @{$rec->{REQUIRES}};
+  foreach my $rq ( @requires )
+  {
+    my ( $nm, $nv );
+    ( $nm, $nv ) = split '=', $rq;
+    if( ! ( $ret = $by_pkg_name{ "$nm" } ) )
+    {
+      printf "  $nm-$nv: is not installed.\n";
+    }
+  }
+}
+printf "\n";
+
+# REFERENCES:
+# ==========
+printf "REFERENCES:\n";
+my $deprecated = 0;
+while( ($name, $rec) = each %by_pkg_name )
+{
+  my @references;
+
+  @references = @{$rec->{REFERENCES}};
+  foreach my $rf ( @references )
+  {
+    my ( $nm, $nv );
+    ( $nm, $nv ) = split '=', $rf;
+    if( ! ( $ret = $by_pkg_name{ "$nm" } ) )
+    {
+      ++$deprecated;
+      if( $remove_deprecated_refs eq "yes" && rm_deprecated_ref( "$rec->{PKGLOG}", "$nm" ) )
+      {
+        printf "  $name-$rec->{VERSION}: remeved deprecated reference (created by package $nm-$nv).\n";
+      }
+      else
+      {
+        printf "  $nm-$nv: is not exist but references to $name-$rec->{VERSION}.\n";
+      }
+    }
+  }
+  if( $deprecated != 0 ) { printf "\n"; }
+}
+if( $deprecated == 0 ) { printf " (none)\n\n"; }
+if( $remove_deprecated_refs ne "yes" && $deprecated != 0 )
+{
+  printf "To remove deprecated references try to run again with option '--rm-dep-refs',\n";
+  printf "like follow:\n";
+  printf "\n # $program --rm-dep-refs\n\n";
+}
+
+#
+# End of Main:
+################################################################
Index: build-system-1.2.3/pkgtool/.config
===================================================================
--- build-system-1.2.3/pkgtool/.config	(nonexistent)
+++ build-system-1.2.3/pkgtool/.config	(revision 231)
@@ -0,0 +1,15 @@
+
+PKGTOOL_PATH := $(BUILDSYSTEM)/pkgtool
+
+CHANGE_REFS        := PATH=$(PKGTOOL_PATH):$(PATH) $(PKGTOOL_PATH)/change-refs
+CHECK_DB_INTEGRITY := PATH=$(PKGTOOL_PATH):$(PATH) $(PKGTOOL_PATH)/check-db-integrity
+CHECK_PACKAGE      := PATH=$(PKGTOOL_PATH):$(PATH) $(PKGTOOL_PATH)/check-package
+CHECK_REQUIRES     := PATH=$(PKGTOOL_PATH):$(PATH) $(PKGTOOL_PATH)/check-requires
+INSTALL_PACKAGE    := PATH=$(PKGTOOL_PATH):$(PATH) $(PKGTOOL_PATH)/install-package
+INSTALL_PKGLIST    := PATH=$(PKGTOOL_PATH):$(PATH) $(PKGTOOL_PATH)/install-pkglist
+MAKE_PACKAGE       := PATH=$(PKGTOOL_PATH):$(PATH) $(PKGTOOL_PATH)/make-package
+MAKE_PKGLIST       := PATH=$(PKGTOOL_PATH):$(PATH) $(PKGTOOL_PATH)/make-pkglist
+PKGINFO            := PATH=$(PKGTOOL_PATH):$(PATH) $(PKGTOOL_PATH)/pkginfo
+PKGLOG             := PATH=$(PKGTOOL_PATH):$(PATH) $(PKGTOOL_PATH)/pkglog
+REMOVE_PACKAGE     := PATH=$(PKGTOOL_PATH):$(PATH) $(PKGTOOL_PATH)/remove-package
+UPDATE_PACKAGE     := PATH=$(PKGTOOL_PATH):$(PATH) $(PKGTOOL_PATH)/update-package
Index: build-system-1.2.3/pkgtool/dialogrc
===================================================================
--- build-system-1.2.3/pkgtool/dialogrc	(nonexistent)
+++ build-system-1.2.3/pkgtool/dialogrc	(revision 231)
@@ -0,0 +1,144 @@
+#
+# Run-time configuration file for dialog, matches Radix color scheme.
+#
+# Types of values:
+#
+# Number     -  <number>
+# String     -  "string"
+# Boolean    -  <ON|OFF>
+# Attribute  -  (foreground,background,highlight?)
+
+# Set aspect-ration.
+aspect = 0
+
+# Set separator (for multiple widgets output).
+separate_widget = ""
+
+# Set tab-length (for textbox tab-conversion).
+tab_len = 0
+
+# Make tab-traversal for checklist, etc., include the list.
+visit_items = OFF
+
+# Shadow dialog boxes? This also turns on color.
+use_shadow = ON
+
+# Turn color support ON or OFF
+use_colors = ON
+
+# Screen color
+screen_color = (WHITE,BLACK,ON)
+
+# Shadow color
+shadow_color = (BLACK,BLACK,OFF)
+
+# Dialog box color
+dialog_color = (BLACK,WHITE,OFF)
+
+# Dialog box title color
+title_color = (RED,WHITE,ON)
+
+# Dialog box border color
+border_color = (WHITE,WHITE,ON)
+
+
+# Active button color
+button_active_color = (WHITE,BLUE,ON)
+
+# Inactive button color
+button_inactive_color = (BLACK,WHITE,OFF)
+
+# Active button key color
+button_key_active_color = (YELLOW,BLUE,ON)
+
+# Inactive button key color
+button_key_inactive_color = (RED,WHITE,ON)
+
+# Active button label color
+button_label_active_color = (WHITE,BLUE,ON)
+
+# Inactive button label color
+button_label_inactive_color = (BLACK,WHITE,ON)
+
+# Input box color
+inputbox_color = (BLUE,WHITE,ON)
+
+# Input box border color
+inputbox_border_color = (WHITE,WHITE,ON)
+
+# Search box color
+searchbox_color = (YELLOW,WHITE,ON)
+
+# Search box title color
+searchbox_title_color = (WHITE,WHITE,ON)
+
+# Search box border color
+searchbox_border_color = (RED,WHITE,OFF)
+
+# File position indicator color
+position_indicator_color = (RED,WHITE,ON)
+
+# Menu box color
+menubox_color = dialog_color
+
+# Menu box border color
+menubox_border_color = border_color
+
+# Item color
+item_color = dialog_color
+
+# Selected item color
+item_selected_color = (BLUE,WHITE,ON)
+
+# Tag color
+tag_color = (BLACK,WHITE,ON)
+
+# Selected tag color
+tag_selected_color = (BLUE,WHITE,ON)
+
+# Tag key color
+tag_key_color = (MAGENTA,WHITE,ON)
+
+# Selected tag key color
+tag_key_selected_color = (RED,WHITE,ON)
+
+# Check box color
+check_color = dialog_color
+
+# Selected check box color
+check_selected_color = (RED,WHITE,ON)
+
+
+# Up arrow color
+uarrow_color = (BLUE,WHITE,ON)
+
+# Down arrow color
+darrow_color = uarrow_color
+
+
+# Item help-text color
+itemhelp_color = shadow_color
+
+# Active form text color
+form_active_text_color = inputbox_color
+
+# Form text color
+form_text_color = (BLACK,WHITE,ON)
+
+# Readonly form item color
+form_item_readonly_color = (CYAN,WHITE,ON)
+
+# Dialog box gauge color
+gauge_color = (BLUE,WHITE,ON)
+
+# Dialog box border2 color
+border2_color = dialog_color
+
+# Input box border2 color
+inputbox_border2_color = border2_color
+
+# Search box border2 color
+searchbox_border2_color = border2_color
+
+# Menu box border2 color
+menubox_border2_color = border2_color
Index: build-system-1.2.3/pkgtool/pkginfo
===================================================================
--- build-system-1.2.3/pkgtool/pkginfo	(nonexistent)
+++ build-system-1.2.3/pkgtool/pkginfo	(revision 231)
@@ -0,0 +1,343 @@
+#!/bin/sh
+
+# 17 = exit if called with no arguments
+# 26 = Destination directory has not specified
+EXITSTATUS=0
+
+usage() {
+  echo
+  echo "Usage: $0 [--dest dir] operation pkglogfile"
+  echo
+  echo "Where the following operations are available:"
+  echo "  filelist       - creates .FILELIST"
+  echo "  restore_links  - creates .RESTORELINKS"
+  echo "  install_script - creates .INSTALL"
+  echo "  requires       - creates .REQUIRES"
+  echo "  description    - creates .DESCRIPTION"
+  echo "  pkginfo        - creates .PKGINFO"
+  echo
+}
+
+DEST_DIR=. # current dir by default
+while [ 0 ]; do
+  if [ "$1" = "-h" -o "$1" = "--help" ]; then
+    usage
+    exit 0
+  elif [ "$1" = "--dest" ]; then
+    if [ "$2" = "" ]; then
+      usage
+      echo "ERROR: Destination directory has not specified. Check --dest option."
+      EXITSTATUS=26
+      exit $EXITSTATUS
+    fi
+    DEST_DIR="$2"
+    shift 2
+  else
+    break
+  fi
+done
+
+#
+# usage(), exit if called with no arguments:
+#
+if [ $# = 0 ]; then
+  usage
+  echo "ERROR: arguments were not specified. Check options."
+  EXITSTATUS=17
+  exit $EXITSTATUS
+fi
+
+
+filelist() {
+  logfile=$1
+  outfile="$DEST_DIR/.FILELIST"
+  LINENUM="`cat $logfile | grep -n -e "FILE LIST:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM" = "" ]; then
+    echo "File list is not present."
+    exit 1
+  fi
+  let LINENUM+=1
+  COUNT=1
+  # zero lenght file:
+  > $outfile
+  LINE="`sed -n "$LINENUM p" $logfile`"
+  let LINENUM+=1
+  let COUNT+=1
+  while [ ! "$LINE" = "" ]; do
+    echo "$LINE" >> $outfile
+    LINE="`sed -n "$LINENUM p" $logfile`"
+    let LINENUM+=1
+    let COUNT+=1
+  done
+}
+
+install_script() {
+  logfile=$1
+  outfile="$DEST_DIR/.INSTALL"
+  START_LINE="`cat $logfile | grep -n -e "INSTALL SCRIPT:" | cut -f 1 -d ':'`"
+  let START_LINE+=1
+  STOP_LINE="`cat $logfile | grep -n -e "FILE LIST:" | cut -f 1 -d ':'`"
+  let STOP_LINE+=1
+  if [ "$START_LINE" = "" -o "$START_LINE" = "$STOP_LINE" ]; then
+    echo "Install script is not present."
+    exit 1
+  fi
+  if [ "$STOP_LINE" = "" ]; then
+    echo "File list is not present."
+    exit 1
+  fi
+  LINENUM="$START_LINE"
+  COUNT=1
+  # zero lenght file:
+  > $outfile
+  LINE="`sed -n "$LINENUM p" $logfile`"
+  let LINENUM+=1
+  let COUNT+=1
+  while [ ! "$LINENUM" = "$STOP_LINE" ]; do
+    echo "$LINE" >> $outfile
+    LINE="`sed -n "$LINENUM p" $logfile`"
+    let LINENUM+=1
+    let COUNT+=1
+  done
+  chmod a+x $outfile
+}
+
+restore_links() {
+  logfile=$1
+  outfile="$DEST_DIR/.RESTORELINKS"
+  START_LINE="`cat $logfile | grep -n -e "RESTORE LINKS:" | cut -f 1 -d ':'`"
+  let START_LINE+=1
+  STOP_LINE="`cat $logfile | grep -n -e "INSTALL SCRIPT:" | cut -f 1 -d ':'`"
+  let STOP_LINE+=1
+  if [ "$START_LINE" = "" -o "$START_LINE" = "$STOP_LINE" ]; then
+    echo "Install script is not present."
+    exit 1
+  fi
+  if [ "$STOP_LINE" = "" ]; then
+    echo "File list is not present."
+    exit 1
+  fi
+  LINENUM="$START_LINE"
+  COUNT=1
+  # zero lenght file:
+  > $outfile
+  LINE="`sed -n "$LINENUM p" $logfile`"
+  let LINENUM+=1
+  let COUNT+=1
+  while [ ! "$LINENUM" = "$STOP_LINE" ]; do
+    echo "$LINE" >> $outfile
+    LINE="`sed -n "$LINENUM p" $logfile`"
+    let LINENUM+=1
+    let COUNT+=1
+  done
+}
+
+description() {
+  logfile=$1
+  outfile="$DEST_DIR/.DESCRIPTION"
+  START_LINE="`cat $logfile | grep -n -e "PACKAGE DESCRIPTION:" | cut -f 1 -d ':'`"
+  let START_LINE+=1
+  STOP_LINE="`cat $logfile | grep -n -e "RESTORE LINKS:" | cut -f 1 -d ':'`"
+  let STOP_LINE+=1
+  if [ "$START_LINE" = "" -o "$START_LINE" = "$STOP_LINE" ]; then
+    echo "Description is not present."
+    exit 0
+  fi
+  if [ "$STOP_LINE" = "" ]; then
+    echo "Install script is not present."
+    exit 0
+  fi
+  LINENUM="$START_LINE"
+  COUNT=1
+  # zero lenght file:
+  > $outfile
+  LINE="`sed -n "$LINENUM p" $logfile`"
+  let LINENUM+=1
+  let COUNT+=1
+  while [ ! "$LINENUM" = "$STOP_LINE" ]; do
+    echo "$LINE" >> $outfile
+    LINE="`sed -n "$LINENUM p" $logfile`"
+    let LINENUM+=1
+    let COUNT+=1
+  done
+}
+
+requires() {
+  logfile=$1
+  outfile="$DEST_DIR/.REQUIRES"
+  START_LINE="`cat $logfile | grep -n -e "REQUIRES:" | cut -f 1 -d ':'`"
+  let START_LINE+=1
+  STOP_LINE="`cat $logfile | grep -n -e "PACKAGE DESCRIPTION:" | cut -f 1 -d ':'`"
+  let STOP_LINE+=1
+  if [ "$START_LINE" = "" -o "$START_LINE" = "$STOP_LINE" ]; then
+    echo "Install script is not present."
+    exit 0
+  fi
+  if [ "$STOP_LINE" = "" ]; then
+    echo "File list is not present."
+    exit 0
+  fi
+  LINENUM="$START_LINE"
+  COUNT=1
+  # zero lenght file:
+  > $outfile
+  LINE="`sed -n "$LINENUM p" $logfile`"
+  let LINENUM+=1
+  let COUNT+=1
+  while [ ! "$LINENUM" = "$STOP_LINE" ]; do
+    echo "$LINE" >> $outfile
+    LINE="`sed -n "$LINENUM p" $logfile`"
+    let LINENUM+=1
+    let COUNT+=1
+  done
+}
+
+references() {
+  logfile=$1
+  outfile="$DEST_DIR/.REFERENCES"
+  START_LINE="`cat $logfile | grep -n -e "REFERENCE COUNTER:" | cut -f 1 -d ':'`"
+  let START_LINE+=1
+  STOP_LINE="`cat $logfile | grep -n -e "REQUIRES:" | cut -f 1 -d ':'`"
+  let STOP_LINE+=1
+  if [ "$START_LINE" = "" -o "$START_LINE" = "$STOP_LINE" ]; then
+    echo "Install script is not present."
+    exit 0
+  fi
+  if [ "$STOP_LINE" = "" ]; then
+    echo "File list is not present."
+    exit 0
+  fi
+  LINENUM="$START_LINE"
+  COUNT=1
+  # zero lenght file:
+  > $outfile
+  LINE="`sed -n "$LINENUM p" $logfile`"
+  let LINENUM+=1
+  let COUNT+=1
+  while [ ! "$LINENUM" = "$STOP_LINE" ]; do
+    echo "$LINE" >> $outfile
+    LINE="`sed -n "$LINENUM p" $logfile`"
+    let LINENUM+=1
+    let COUNT+=1
+  done
+}
+
+pkginfo() {
+  logfile=$1
+  outfile="$DEST_DIR/.PKGINFO"
+  LINENUM_PN="`cat $logfile | grep -n -e "PACKAGE NAME:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_PN" = "" ]; then
+    echo "ERROR: There is no PACKAGE NAME."
+    exit 1
+  fi
+  LINENUM_PV="`cat $logfile | grep -n -e "PACKAGE VERSION:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_PV" = "" ]; then
+    echo "ERROR: There is no PACKAGE VERSION."
+    exit 1
+  fi
+  LINENUM_A="`cat $logfile | grep -n -e "ARCH:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_A" = "" ]; then
+    echo "ERROR: There is no ARCH definition."
+    exit 1
+  fi
+  LINENUM_DN="`cat $logfile | grep -n -e "DISTRO:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_DN" = "" ]; then
+    echo "ERROR: There is no DISTRIBUTION NAME."
+    exit 1
+  fi
+  LINENUM_DV="`cat $logfile | grep -n -e "DISTRO VERSION:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_DN" = "" ]; then
+    echo "ERROR: There is no DISTRIBUTION VERSION."
+    exit 1
+  fi
+  LINENUM_GR="`cat $logfile | grep -n -e "GROUP:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_GR" = "" ]; then
+    echo "WARNING: There is no GROUP definition."
+  fi
+  LINENUM_URL="`cat $logfile | grep -n -e "URL:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_URL" = "" ]; then
+    echo "WARNING: There is no URL definition."
+  fi
+  LINENUM_L="`cat $logfile | grep -n -e "LICENSE:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_L" = "" ]; then
+    echo "WARNING: There is no LICENSE definition."
+  fi
+  LINENUM_UZ="`cat $logfile | grep -n -e "UNCOMPRESSED SIZE:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_UZ" = "" ]; then
+    echo "WARNING: There is no UNCOMPRESSED SIZE definition."
+  fi
+  LINENUM_TF="`cat $logfile | grep -n -e "TOTAL FILES:" | cut -f 1 -d ':'`"
+  if [ "$LINENUM_TF" = "" ]; then
+    echo "WARNING: There is no TOTAL numer of FILES."
+  fi
+
+  # zero lenght file:
+  > $outfile
+
+  LINE="`sed -n "$LINENUM_PN p" $logfile`"
+  pkgname="`echo "$LINE" | sed -e 's/^PACKAGE NAME: //'`"
+  echo "pkgname=$pkgname" >> $outfile
+
+  LINE="`sed -n "$LINENUM_PV p" $logfile`"
+  pkgver="`echo "$LINE" | sed -e 's/^PACKAGE VERSION: //'`"
+  echo "pkgver=$pkgver" >> $outfile
+
+  LINE="`sed -n "$LINENUM_A p" $logfile`"
+  arch="`echo "$LINE" | sed -e 's/^ARCH: //'`"
+  echo "arch=$arch" >> $outfile
+
+  LINE="`sed -n "$LINENUM_DN p" $logfile`"
+  distroname="`echo "$LINE" | sed -e 's/^DISTRO: //'`"
+  echo "distroname=$distroname" >> $outfile
+
+  LINE="`sed -n "$LINENUM_DV p" $logfile`"
+  distrover="`echo "$LINE" | sed -e 's/^DISTRO VERSION: //'`"
+  echo "distrover=$distrover" >> $outfile
+
+  if [ ! "$LINENUM_GR" = "" ]; then
+    LINE="`sed -n "$LINENUM_GR p" $logfile`"
+    group="`echo "$LINE" | sed -e 's/^GROUP: //'`"
+    echo "group=$group" >> $outfile
+  fi
+  if [ ! "$LINENUM_URL" = "" ]; then
+    LINE="`sed -n "$LINENUM_URL p" $logfile`"
+    url="`echo "$LINE" | sed -e 's/^URL: //'`"
+    echo "url=$url" >> $outfile
+  fi
+  if [ ! "$LINENUM_L" = "" ]; then
+    LINE="`sed -n "$LINENUM_L p" $logfile`"
+    license="`echo "$LINE" | sed -e 's/^LICENSE: //'`"
+    echo "license=$license" >> $outfile
+  fi
+  if [ ! "$LINENUM_UZ" = "" ]; then
+    LINE="`sed -n "$LINENUM_UZ p" $logfile`"
+    uncompressed_size="`echo "$LINE" | sed -e 's/^UNCOMPRESSED SIZE: //'`"
+    echo "uncompressed_size=$uncompressed_size" >> $outfile
+  fi
+  if [ ! "$LINENUM_TF" = "" ]; then
+    LINE="`sed -n "$LINENUM_TF p" $logfile`"
+    total_files="`echo "$LINE" | sed -e 's/^TOTAL FILES: //'`"
+    echo "total_files=$total_files" >> $outfile
+  fi
+}
+
+
+operation=$1
+shift
+
+if [ "$operation" = "" ]; then
+  usage
+  echo "ERROR: operation name is not present in argument list."
+  echo
+  exit 1
+fi
+
+if [ "$1" = "" ]; then
+  usage
+  echo "ERROR: pkglogfile is not present in argument list."
+  echo
+  exit 1
+fi
+
+
+$operation $1

Property changes on: build-system-1.2.3/pkgtool/pkginfo
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/README.md
===================================================================
--- build-system-1.2.3/README.md	(nonexistent)
+++ build-system-1.2.3/README.md	(revision 231)
@@ -0,0 +1,209 @@
+
+# [Build System](https://radix.pro/build-system/)
+
+**Build System** is a set of Makefiles and utilities organized within one directory which is mounted
+into the source tree of the developed product.
+
+> The main purpose of the **Build System** is automating all stages of software solution development,
+> from arrangement of source code from third-party developers usage to publication of own deliverable
+> distributive.
+
+The fundamental principle of **Build System** is described in the
+[Build System Internals](https://radix.pro/build-system/internals/#fundamental_principle) section and
+in the [doc/PRINCIPLE*](doc/PRINCIPLE.md) files of this repository.
+
+
+## Table of contents
+
+* [Quick start](#user-content-quick-start)
+* [Documentation](#user-content-documentation)
+* [Community](#user-content-community)
+* [Creators](#user-content-creators)
+
+
+## Quick start
+
+All steps described below are considered in the [Build System in Practice](https://radix.pro/build-system/practice/)
+section on the main [Radix.pro](https://radix.pro) site. To create first package using
+[Build System](https://radix.pro/build-system/) we have to perform following steps:
+
+* [Install CCACHE](#user-content-install-ccache)
+* [Getting Toolchains](#user-content-getting-toolchains)
+* [Create a First Package](#user-content-first-package)
+
+
+### Install CCACHE
+
+To speed up the building process we strongly recommend to set up **CCACHE**(**1**) utility. Almost all **Linux**
+distributions have this utility by default.
+
+We described **CCACHE** setup process in the [Build System Overview](https://radix.pro/build-system/overview/#ccache)
+section and here we have to notice that the directory */opt/extra/ccache* is a default place of the **CCACHE** data.
+If you want to use another directory for **CCACHE** data then you have to change the value of **CACHED_CC_OUTPUT**
+variable in the [constants.mk](constants.mk) file. Of course all developers should to have permissions to access
+this directory.
+
+Before start the first build process you have to create **CCACHE** data directory on behalf of superuser:
+
+```Bash
+$ sudo mkdir -p /opt/extra/ccache
+$ sudo chown -R developer:developers /opt/extra
+```
+
+Where **developers** - is a name your developers group and **developer** - is a name of some user who is
+a member of **developers** group.
+
+
+### Getting Toolchains
+
+First of all we have to create toolchains directory on the developer machine. The default path to toolchains
+is defined by **TOOLCHAINS_BASE_PATH** variable in the [constants.mk](constants.mk) file. The access permissions
+should be given to developers by the superuser:
+
+```Bash
+$ sudo mkdir -p /opt/toolchain
+$ sudo chown -R developer:developers /opt/toolchain
+```
+
+In principle no additional actions from the user is not required. The fact is that if before the start
+of assembly the first package the required toolchain will not be found in the appropriate directory then
+the **build system will** start downloading the needed toolchain from **FTP**-server and at the end of the
+downloading the **build system** unpacks the toolchain to the */opt/toolchain*  directory.
+
+Also the toolchains installation can be done manualy. To do this you have to perform a set of commands
+like following:
+
+```Bash
+$ cd /opt/toolchain
+$ wget ftp://ftp.radix.pro/toolchains/x86_64/1.0.9/arm-RK328X-linux-glibc-1.0.9.tar.gz
+$ tar xzf arm-RK328X-linux-glibc-1.0.9.tar.gz
+```
+
+for each needed toolchain.
+
+
+### First Package
+
+Consider the work of the **build system** on the simplest example which despite its simplicity allow us
+to explore all of main stages of creating distributable packages.
+
+Let us create a project directory:
+
+```Bash
+$ mkdir project
+$ cd project
+```
+
+Clone the **build system** repository:
+
+```Bash
+$ git clone https://github.com/radix-platform/build-system.git
+```
+
+At this stage we do not want to create a new package from scratch and consider a complete package from
+[Radix Platform](http://svn.radix.pro/wsvn/platform/) repository. Let it be **pkgtool**. The **pkgtool** -
+is a base package which does not require the downloading any sources as they already present in the
+**build system**. In addition, **pkgtool** does not depend on any packages in the system and we
+already have all needed tools presented on the developer's machine.
+
+So, to obtain the necessary files we have to check out */base* directory from repository:
+
+```Bash
+$ svn co http://svn.radix.pro/svn/platform/trunk/base base
+```
+
+Let's change current directory to *base/pkgtool*:
+
+```Bash
+$ cd base/pkgtool
+```
+
+and create our first package:
+
+
+```Bash
+$ HARDWARE=ffrk3288 make
+```
+
+At the end of build process the **build system** displays a message indicating that the **pkgtool** package
+has been successfully installed into *dist/rootfs/rk328x-glibc/ffrk3288* directory which created especially
+as the working image of the target root file system:
+
+```
+Package creation complete.
+
+#######
+####### Install packages into 'dist/rootfs/rk328x-glibc/ffrk3288/...' file system...
+#######
+
+ Installing package pkgtool... 
+|======================================================================|
+
+ pkgtool 1.1.0 (Package Tools)
+ 
+ This is a set of scripts used for package creation, install, etc.
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ 
+ Uncompressed Size: 168K
+   Compressed Sise: 24K
+|======================================================================|
+
+make[2]: Leaving directory `project/base/pkgtool'
+make[1]: Leaving directory `project/base/pkgtool'
+$
+```
+
+This process considered in more details in the [Build System in Practice](https://radix.pro/build-system/practice/#first_package)
+section at the main [Radix.pro](https://radix.pro/) site.
+
+
+## Documentation
+
+**Build System**'s documentation is present on the main [Radix.pro](https://radix.pro) site
+in the [Build System](https://radix.pro/build-system) section.
+
+
+## Community
+
+Get updates on **Build System**'s development and chat with the project maintainers and community members.
+
+* Read and subscribe to [The Official Radix.pro Blog](https://blog.radix.pro).
+* Follow [@RadixPlatform on Twitter](https://twitter.com/RadixPlatform).
+* Read and subscribe to [The Official Radix.pro Facebook page](https://www.facebook.com/RadixPlatform).
+* Join [The Official Radix.pro VKontakte group](https://vk.com/radixplatform).
+* Read and subscribe to [The Official Radix.pro Google+ page](https://plus.google.com/104378627275746652509).
+* Read and follow [The Official Radix.pro Tumblr blog](https://radix-platform.tumblr.com).
+
+
+## Versioning
+
+For transparency into our release cycle and in striving to maintain backward compatibility,
+**Build System** is maintained under [the Semantic Versioning guidelines](http://semver.org/)
+excluding additional labels such as pre-release suffixes. 
+
+See [the Versioning section](https://radix.pro/build-system/overview/#versioning) on the main
+[Radix.pro](https://radix.pro) site.
+
+Release announcement posts will be available on [the Official Radix.pro Blog](https://blog.radix.pro) and
+on the [Community](#user-content-community) sites.
+
+
+## Creators
+
+**Andrey V. Kosteltsev**
+
+* <https://twitter.com/AKosteltsev>
+* <https://www.facebook.com/andrey.kosteltsev>
+* <https://vk.com/andrey.kosteltsev>
+
+
+## Copyright and license
+
+Code and documentation copyright 2009-2017 Andrey V. Kosteltsev.
+Code and documentation released under [the **Radix.pro** License](LICENSE).
Index: build-system-1.2.3/install_targets
===================================================================
--- build-system-1.2.3/install_targets	(nonexistent)
+++ build-system-1.2.3/install_targets	(revision 231)
@@ -0,0 +1,283 @@
+#!/usr/bin/perl
+
+use FindBin;
+use lib $FindBin::Bin;
+
+use strict;
+use warnings FATAL => 'all';
+
+use File::Basename;
+use File::Temp;
+use _kxLab;
+
+
+#
+# Install file(s)
+#
+# usage:
+#   $0 [options] source[ source] destination hardware
+#
+# where:
+#        'source' - the list of source files to be installed into dest directory
+#   'destination' - is a destination directory for installation all source files
+#      'hardware' - is a HARDWARE variant
+#
+# options:
+#   --preserve-source-dir=true  - preserve source directory tree in the dest dir,
+#                                 for example, if source is foo/bar/file then we
+#                                 will have destination such as  dest/foo/bar/file.
+#
+#   --preserve-source-dir=one   - preserve source directory depth is only 1. Its
+#                                 mean that if we have source like foo/bar/file,
+#                                 then destination will be dest/bar/file.
+#
+
+# Global variables
+my $header_printed = 0;
+
+my $cleanup = $ENV{DO_CREATE_DIST_FILES} ? 0 : 1;
+my ($tempfd, $tempname);
+
+sub usage
+{
+  print <<EOF;
+
+Usage: install_targets [options] source[ source]
+Options:
+   --preserve-source-dir={true|one} - preserve source directory tree in the DEST dir.
+                                      true: If source is foo/bar/file then destination
+                                            file will be DEST/foo/bar/file.
+                                       one: depth is only one directory. If source is
+                                            fo/bar/file then destination will be
+                                            DEST/bar/file.
+   --destination=DEST               - where DEST is a destination directory.
+   --toolchain=TOOLCHAIN            - where TOOLCHAIN ia a toolchain name;
+   --hardware=HARDWARE              - where HARDWARE ia a HARDWARE name;
+   --flavour=FLAVOUR                - where FLAVOUR ia a FLAVOUR name.
+
+EOF
+  exit;
+}
+
+
+# cleanpath( path )
+sub cleanpath
+{
+  my $path = shift;
+  $path =~ s!/{2,}!/!g;
+  return $path;
+}
+
+# dist( file )
+sub dist
+{
+  my $file = cleanpath(shift);
+  $file =~ s!^.*dist/!!;
+  print $tempfd "$file\n";
+}
+
+# newer_than( file1, file2 )
+sub newer_than
+{
+  my $file1 = shift;
+  my $file2 = shift;
+  _kxLab::error( "install_targets: Source file missing: $file1" ) if ( ! -f $file1 );
+  return( ! -f $file2 or -M $file1 < -M $file2 );
+}
+
+sub dir_is_empty
+{
+  my ($path) = @_;
+  opendir DIR, $path;
+  while( my $entry = readdir DIR )
+  {
+    next if( $entry =~ /^\.\.?$/ );
+    closedir DIR;
+    return 0;
+  }
+  closedir DIR;
+  return 1;
+}
+
+# install_tree( install_dir, file, target, verbose )
+sub install_tree
+{
+  my $install_dir = cleanpath(shift);
+  my $file = shift;
+  my $target = shift;
+  my $verbose = shift;
+
+  opendir(DIR, "$target");
+  my @files = readdir(DIR);
+  closedir DIR;
+  foreach my $f ( @files )
+  {
+    next if ($f eq "." or $f eq "..");
+    if( -d "$target/$f" )
+    {
+      install_tree( "$install_dir/$f", "$file/$f", "$target/$f", $verbose );
+    }
+    elsif( newer_than( "$target/$f", "$install_dir/$f" ) )
+    {
+      if( !$header_printed )
+      {
+        print "\n======= Installing files =======\n";
+        $header_printed = 1;
+      }
+      print "Installing $f in $install_dir\n" if ( $verbose );
+      _kxLab::system( "mkdir -p \"$install_dir\"" );
+      _kxLab::system( "cp -fa \"$target/$f\" \"$install_dir\"" );
+      dist( "$install_dir/$f" );
+    }
+  }
+}
+
+
+
+
+# install( install_dir, preserve_source_dir, verbose, targets )
+sub install
+{
+  my $install_dir = cleanpath(shift);
+  my $preserve_source_dir = shift;
+  my $verbose = shift;
+  my $targets = shift;
+
+  foreach my $target ( @{$targets} )
+  {
+    my $file = basename($target);
+    my $path = "";
+    if( $preserve_source_dir eq "true" )
+    {
+      $path = dirname( $target );
+    }
+    elsif( $preserve_source_dir eq "one" )
+    {
+      $path = dirname( $target );
+      $path = basename( $path );
+    }
+    elsif( $preserve_source_dir eq "two" )
+    {
+      my ($first, $second);
+
+      $path = dirname( $target );
+      $second = basename( $path );
+      $path = dirname( $path );
+      $first = basename( $path );
+      $path = $first . "/" . $second;
+    }
+
+    if( -d $target )
+    {
+      if( dir_is_empty( $target ) )
+      {
+        _kxLab::system( "mkdir -p \"$install_dir/$path/$file\"" );
+        dist( "$install_dir/$path/$file" );
+      }
+      else
+      {
+        install_tree( "$install_dir/$path/$file", "$file", "$target", $verbose );
+      }
+    }
+    elsif( newer_than( $target, "$install_dir/$path/$file" ) )
+    {
+      if( !$header_printed )
+      {
+        print "\n======= Installing files =======\n" if ( $verbose );
+        $header_printed = 1;
+      }
+      print "Installing $file in $install_dir/$path\n" if ( $verbose );
+      _kxLab::system( "mkdir -p \"$install_dir/$path\"" );
+      _kxLab::system( "cp -fa \"$target\" \"$install_dir/$path\"" );
+      dist( "$install_dir/$path/$file" );
+    }
+  }
+}
+
+my $preserve_source_dir = "";
+my $dest_dir;
+my ($toolchain, $hardware, $flavour);
+my $target_build_dir;
+my @targets;
+my $verbose = $ENV{VERBOSE};
+my $curdir  = $ENV{CWD};
+my $fname = "";
+
+
+foreach ( @ARGV )
+{
+  if( /--preserve-source-dir=(\S*)/ )
+  {
+    $preserve_source_dir = $1;
+  }
+  elsif( /--destination=(\S*)/ )
+  {
+    $dest_dir = $1;
+  }
+  elsif( /--toolchain=(\S*)/ )
+  {
+    $toolchain = $1;
+  }
+  elsif( /--hardware=(\S*)/ )
+  {
+    $hardware = $1;
+  }
+  elsif( /--flavour=(\S*)/ )
+  {
+    $flavour = $1;
+  }
+  elsif( /--help/ )
+  {
+    usage;
+  }
+  elsif( /--/ )
+  {
+    while( <STDIN> )
+    {
+      #
+      # NOTE: arguments from STDIN should be splitted by '\n'
+      #
+      my $arg = $_;
+
+      chomp $arg;  $arg =~ s/\\040/ /g;
+
+      push @targets, $arg;
+    }
+
+    last;
+  }
+  else
+  {
+    my $arg = $_;
+
+    chomp $arg; $arg =~ s/\\040/ /g;
+
+    push @targets, $arg;
+  }
+}
+
+if( ! defined $dest_dir  or $dest_dir eq "" )  { usage; }
+if( ! defined $toolchain or $toolchain eq "" ) { usage; }
+if( ! defined $hardware  or $hardware eq "" )  { usage; }
+if( ! defined $flavour   or $flavour eq "" )
+{
+  $flavour = "";
+  $target_build_dir = "." . $toolchain . "/" . $hardware;
+}
+else
+{
+  $target_build_dir = "." . $toolchain . "/" . $hardware . "/" . $flavour;
+}
+
+if ( $curdir )
+{
+  $fname = "$curdir/" . $target_build_dir . "/.dist.XXXXXX";
+}
+else
+{
+  $fname = $target_build_dir . "/.dist.XXXXXX";
+}
+
+($tempfd, $tempname) = File::Temp::tempfile( $fname, UNLINK => $cleanup );
+
+install( $dest_dir, $preserve_source_dir, $verbose, \@targets );

Property changes on: build-system-1.2.3/install_targets
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/doc/PRINCIPLE.iso88591
===================================================================
--- build-system-1.2.3/doc/PRINCIPLE.iso88591	(nonexistent)
+++ build-system-1.2.3/doc/PRINCIPLE.iso88591	(revision 231)
@@ -0,0 +1,82 @@
+
+The fundamental principle of the build system
+=============================================
+
+Assume that we need to build the program or alienated package for working
+on the three devices with names ci20, bt01 and dm64. The first two devices
+(ci20, bt01) are based on the MIPS architecture, and the third device (dm64)
+is built on ARM-based processor. Toolchains for building our program, for
+simplicity, let's call mips and arm, respectively.
+
+The build script of the source program is the same for each of our devices
+and is written on GNU Make.
+
+If we present all available combinations of command line calls, required for
+building the program for our devices, we get:
+
+ $ TOOLCHAIN=mips HARDWARE=ci20 make
+ $ TOOLCHAIN=mips HARDWARE=bt01 make
+ $ TOOLCHAIN=arm  HARDWARE=dm64 make
+
+or (in case when the TOOLCHAIN-HARDWARE pairs are transmitted as arguments):
+
+ $ make TOOLCHAIN=mips HARDWARE=ci20
+ $ make TOOLCHAIN=mips HARDWARE=bt01
+ $ make TOOLCHAIN=arm  HARDWARE=dm64
+
+Thus, the build system must receive a TOOLCHAIN-HARDWARE pair, and then the
+build system has to determine which toolchain must be used for a particular
+device.
+
+Let us now consider how to organize the sequence of command calls (on the
+build system level) in such way that the user can do these actions by
+applying only one call:
+
+ $ make
+
+without specifying additional arguments which are responsible for selection
+of the target device and applicable toolchain.
+
+If we describe the list of valid terget devices at the beginning of our script,
+for example, as follows:
+
+COMPONENT_TARGETS  = $(HARDWARE_CI20)
+COMPONENT_TARGETS += $(HARDWARE_BT01)
+COMPONENT_TARGETS += $(HARDWARE_DM64)
+
+then the build system can automatically construct a list of possible
+TOOLCHAIN-HARDWARE combinations for a given build script, which will looks
+like following:
+
+  targets = target_mips_ci20 target_mips_bt01 target_arm_dm64
+
+With such list, the build system can restore arguments which are needed for
+each of three our calls. It is very simple to do. On the Make language we can
+do it as shown by following lines:
+
+target_%: TOOLCHAIN = $(shell echo $(word 2, $(subst _, , $@)))
+target_%: HARDWARE = $(shell echo $(word 3, $(subst _, , $@)))
+target_%:
+	$(MAKE) TOOLCHAIN=$(TOOLCHAIN) HARDWARE=$(HARDWARE)
+
+Thus, if we call the Make utility without arguments then TOOLCHAIN and HARDWARE
+variables will be undefined. In this case the build system starts to collect the
+targets list. When the targets list will be complete the build system can do the
+call
+
+	$(MAKE) TOOLCHAIN=$(TOOLCHAIN) HARDWARE=$(HARDWARE)
+
+with valid arguments.
+
+When (at the next call) the system will make sure that the TOOLCHAIN and
+HARDWARE variables are defined, the control of the build process will be passed
+to our build script without additional calculations.
+
+The described mechanism is directly derived from the GNU Make documentation.
+
+
+References
+----------
+http://www.gnu.org/software/make/manual/
+http://radix.pro/build-system/
+
Index: build-system-1.2.3/doc/PRINCIPLE.utf8
===================================================================
--- build-system-1.2.3/doc/PRINCIPLE.utf8	(nonexistent)
+++ build-system-1.2.3/doc/PRINCIPLE.utf8	(revision 231)
@@ -0,0 +1,83 @@
+
+Фундаментальный принцип работы системы сборки
+=============================================
+
+Предположим, что нам необходимо собрать программу или отчуждаемый пакет для
+работы на трех устройствах с именами ci20, bt01 и dm64. Первые два устройства
+ci20 и bt01 основаны на архитектуре MIPS, третье устройство dm64 построенно
+на базе процессора ARM. Toolchain-ы для сборки программ, для простоты, назовем
+mips и arm, соответственно.
+
+Сценарий сборки исходной программы одинаков для всех трех устройств и написан
+на языке GNU Make.
+
+Если представить все комбинации вызовов команды Make, необходимые для сборки
+программы на наши устройства, получим:
+
+ $ TOOLCHAIN=mips HARDWARE=ci20 make
+ $ TOOLCHAIN=mips HARDWARE=bt01 make
+ $ TOOLCHAIN=arm  HARDWARE=dm64 make
+
+или, при передаче имен устройств и Toolchain-ов в качестве аргументов:
+
+ $ make TOOLCHAIN=mips HARDWARE=ci20
+ $ make TOOLCHAIN=mips HARDWARE=bt01
+ $ make TOOLCHAIN=arm  HARDWARE=dm64
+
+Таким образом, система сборки должна принимать пары TOOLCHAIN-HARDWARE,
+которые определяют какой именно Toolchain необходимо использовать для того
+или иного устройства.
+
+Рассмотрим теперь, как, на уровне системы сборки, организовать последовательность
+вызовов утилиты Make для нашего сценария таким образом, чтобы пользователь мог
+осуществить данные действия с помощью лишь одного вызова:
+
+ $ make
+
+без задания дополнительных аргументов, отвечающих за выбор целевого устройства
+и связанного с ним Toolchain-а.
+
+Если включить в начало нашего сценария список допустимых целевых устройств,
+например, следующим образом:
+
+COMPONENT_TARGETS  = $(HARDWARE_CI20)
+COMPONENT_TARGETS += $(HARDWARE_BT01)
+COMPONENT_TARGETS += $(HARDWARE_DM64)
+
+то система сборки сможет автоматически построить список возможных, для данного
+сценария, комбинаций TOOLCHAIN-HARDWARE, который будет выглядеть, например,
+следующим образом:
+
+  targets = target_mips_ci20 target_mips_bt01 target_arm_dm64
+
+Имея такой список, система сборки может восстановить аргументы, которые
+необходимо передавать при каждом вызове утилиты Make, для нашего сценария.
+Сделать это нетрудно, на языке GNU Make эти действия можно описать так:
+
+target_%: TOOLCHAIN = $(shell echo $(word 2, $(subst _, , $@)))
+target_%: HARDWARE = $(shell echo $(word 3, $(subst _, , $@)))
+target_%:
+	$(MAKE) TOOLCHAIN=$(TOOLCHAIN) HARDWARE=$(HARDWARE)
+
+
+Таким образом, при вызове команды Make без аргументов, переменные TOOLCHAIN и
+HARDWARE будут не определены и, в этом случае, система сборки займется созданием
+списка targets из числа допустимых комбинаций. Когда же список будет составлен,
+система сборки сможет осуществить вызов
+
+	$(MAKE) TOOLCHAIN=$(TOOLCHAIN) HARDWARE=$(HARDWARE)
+
+с действительными аргументами.
+
+Когда же, при очередном вызове, система убедится в том, что переменные
+TOOLCHAIN и HARDWARE определены, управление будет передано нашему сценарию
+без дополнительных вычислений.
+
+Описанный здесь механизм, напрямую вытекает из возможностей утилиты Make.
+
+
+References
+----------
+http://www.gnu.org/software/make/manual/
+http://radix.pro/build-system/
+
Index: build-system-1.2.3/doc/PRINCIPLE.md
===================================================================
--- build-system-1.2.3/doc/PRINCIPLE.md	(nonexistent)
+++ build-system-1.2.3/doc/PRINCIPLE.md	(revision 231)
@@ -0,0 +1,97 @@
+
+
+The fundamental principle of the build system
+=============================================
+
+Assume that we need to build the program or alienated package for working
+on the three devices with names **ci20**, **bt01** and **dm64**. The first two devices
+(**ci20**, **bt01**) are based on the **MIPS** architecture, and the third device (**dm64**)
+is built on **ARM**-based processor. Toolchains for building our program, for
+simplicity, let's call **mips** and **arm**, respectively.
+
+The build script of the source program is the same for each of our devices
+and is written on **GNU Make**.
+
+If we present all available combinations of command line calls, required for
+building the program for our devices, we get:
+
+```bash
+ $ TOOLCHAIN=mips HARDWARE=ci20 make
+ $ TOOLCHAIN=mips HARDWARE=bt01 make
+ $ TOOLCHAIN=arm  HARDWARE=dm64 make
+```
+
+or (in case when the **TOOLCHAIN-HARDWARE** pairs are transmitted as arguments):
+
+```bash
+ $ make TOOLCHAIN=mips HARDWARE=ci20
+ $ make TOOLCHAIN=mips HARDWARE=bt01
+ $ make TOOLCHAIN=arm  HARDWARE=dm64
+```
+
+Thus, the **build system** must receive a **TOOLCHAIN-HARDWARE** pair, and then the
+**build system** has to determine which toolchain must be used for a particular
+device.
+
+Let us now consider how to organize the sequence of command calls (on the
+**build system** level) in such way that the user can do these actions by
+applying only one call:
+
+```bash
+ $ make
+```
+
+without specifying additional arguments which are responsible for selection
+of the target device and applicable toolchain.
+
+If we describe the list of valid terget devices at the beginning of our script,
+for example, as follows:
+
+```make
+COMPONENT_TARGETS  = $(HARDWARE_CI20)
+COMPONENT_TARGETS += $(HARDWARE_BT01)
+COMPONENT_TARGETS += $(HARDWARE_DM64)
+```
+
+then the **build system** can automatically construct a list of possible
+**TOOLCHAIN-HARDWARE** combinations for a given build script, which will looks
+like following:
+
+```make
+  targets = target_mips_ci20 target_mips_bt01 target_arm_dm64
+```
+
+With such list, the **build system** can restore arguments which are needed for
+each of three our calls. It is very simple to do. On the **GNU Make** language we can
+do it as shown by following lines:
+
+```make
+target_%: TOOLCHAIN = $(shell echo $(word 2, $(subst _, , $@)))
+target_%: HARDWARE = $(shell echo $(word 3, $(subst _, , $@)))
+target_%:
+	$(MAKE) TOOLCHAIN=$(TOOLCHAIN) HARDWARE=$(HARDWARE)
+```
+
+Thus, if we call the **Make** utility without arguments then **TOOLCHAIN** and **HARDWARE**
+variables will be undefined. In this case the **build system** starts to collect the
+targets list. When the **targets** list will be complete the **build system** can do the
+call
+
+```make
+	$(MAKE) TOOLCHAIN=$(TOOLCHAIN) HARDWARE=$(HARDWARE)
+```
+
+with valid arguments.
+
+When (at the next call) the system will make sure that the **TOOLCHAIN** and
+**HARDWARE** variables are defined, the control of the build process will be passed
+to our build script without additional calculations.
+
+The described mechanism is directly derived from the **GNU Make** documentation.
+
+
+References
+----------
+1. <http://www.gnu.org/software/make/manual/>
+2. <https://radix.pro/build-system/>
+
Index: build-system-1.2.3/doc/LICENSE-1.0-en_US.txt
===================================================================
--- build-system-1.2.3/doc/LICENSE-1.0-en_US.txt	(nonexistent)
+++ build-system-1.2.3/doc/LICENSE-1.0-en_US.txt	(revision 231)
@@ -0,0 +1,268 @@
+
+
+                                 Radix.pro License
+                              Version 1.0, March 2016
+                  http://radix.pro/licenses/LICENSE-1.0-en_US.txt
+
+
+1. Definitions
+
+   1.1. "License"
+
+        means the terms and conditions for use, reproduction, and distribution
+        as defined by this document.
+
+
+   1.2. "Licensor"
+
+        means the copyright owner or entity authorized by the copyright owner that is
+        granting the License.
+
+
+   1.3. "Legal Entity"
+
+        means the union of the acting entity and all other entities that control, are
+        controlled by, or are under common control with that entity. For the purposes
+        of this definition, "control" means:
+          a. the power, direct or indirect, to cause the direction or management of such
+             entity, whether by contract or otherwise, or
+          b. ownership of fifty percent (50%) or more of the outstanding shares, or
+          c. beneficial ownership of such entity.
+
+
+   1.4. "You" (or "Your")
+
+        means an individual or Legal Entity exercising permissions granted by this License.
+
+
+   1.5. “Licensable”
+
+        means having the right to grant, to the maximum extent possible, whether at the
+        time of the initial grant or subsequently, any and all of the rights conveyed
+        by this License.
+
+
+   1.6. "Source Form"
+
+        means the form of the Work preferred for making Modifications, including but not limited
+        to software source code, documentation source, and configuration files.
+
+
+   1.7. "Object Form"
+
+        means any form resulting from mechanical  transformation or translation of a Source form,
+        including but not limited to compiled object code, generated documentation, and conversions
+        to other media types.
+
+
+   1.8. "Work"
+
+        means the work of authorship, whether in Source or Object Form, made available under
+        the License, as indicated by a copyright notice that is included in or attached to the work
+        (an example is provided in the Appendix below).
+
+
+   1.9. "Derivative Works"
+
+        means any work, whether in Source or Object Form, that is based on (or derived from) the Work
+        and for which the editorial revisions, annotations, elaborations, or other modifications
+        represent, as a whole, an original work of authorship. For the purposes of this License,
+        Derivative Works shall not include works that remain separable from, or merely link
+        (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+  1.10. "Contribution"
+
+        means any work of authorship, including the original version of the Work and any modifications
+        or additions to that Work or Derivative Works thereof, that is intentionally submitted to
+        Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity
+        authorized to submit on behalf of the copyright owner. For the purposes of this definition,
+        "submitted" means any form of electronic, verbal, or written communication sent to the Licensor
+        or its representatives, including but not limited to communication on electronic mailing lists,
+        source code control systems, and issue tracking systems that are managed by, or on behalf of,
+        the Licensor for the purpose of discussing and improving the Work, but excluding communication
+        that is conspicuously marked or otherwise designated in writing by the copyright owner
+        as "Not a Contribution."
+
+
+  1.11. "Contributor"
+
+        means Licensor and any individual or Legal Entity on behalf of whom a Contribution has been
+        received by Licensor and subsequently incorporated within the Work.
+
+
+  1.12. “Patent Claims” of a Contributor
+
+        means any patent claim(s), including without limitation, method, process, and apparatus claims,
+        in any patent Licensable by such Contributor that would be infringed, but for the grant of the
+        License, by the making, using, selling, offering for sale, having made, import, or transfer
+        of either its Contributions or its Contributor Version.
+
+
+
+2. Grant of Copyright License
+
+   Subject to the terms and conditions of this License, each Contributor hereby grants to You
+   a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license
+   to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense,
+   and distribute the Work and such Derivative Works in Source or Object Form.
+
+
+3. Grant of Patent License
+
+   Subject to the terms and conditions of this License, each Contributor hereby grants
+   to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made, use, offer to
+   sell, sell, import, and otherwise transfer the Work, where such license applies only
+   to those patent claims Licensable by such Contributor that are necessarily infringed
+   by their Contribution(s) alone or by combination of their Contribution(s) with the
+   Work to which such Contribution(s) was submitted. If You institute patent litigation
+   against any entity (including a cross-claim or counterclaim in a lawsuit) alleging
+   that the Work or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses granted to You under
+   this License for that Work shall terminate as of the date such litigation is filed.
+
+
+4. Redistribution
+
+   You may reproduce and distribute copies of the Work or Derivative Works thereof
+   in any medium, with or without modifications, and in Source or Object Form, provided
+   that You meet the following conditions:
+
+     a. You must give any other recipients of the Work or  Derivative Works
+        a copy of this License; and
+     b. You must cause any modified files to carry prominent notices stating that
+        You changed the files; and
+     c. You must retain, in the Source form of any Derivative Works that You distribute,
+        all copyright, patent, trademark, and attribution notices from the Source form
+        of the Work, excluding those notices that do not pertain to any part of the
+        Derivative Works; and
+     d. If the Work includes a "PRINCIPLE" text file as part of its distribution, then
+        any Derivative Works that You distribute must include a readable copy of the
+        fundamental ideas, truths or propositions contained within such PRINCIPLE file.
+        You may add Your own fundamental ideas, truths or propositions that serves as
+        the foundation for understanding the internal structure and principles of
+        Derivative works or Contributions.
+
+   You may add Your own copyright statement to Your modifications and may provide additional
+   or different license terms and conditions for use, reproduction, or distribution of Your
+   modifications, or for any such Derivative Works as a whole, provided Your use, reproduction,
+   and distribution of the Work otherwise complies with the conditions stated in this License.
+
+
+5. Submission of Contributions
+
+   Unless You explicitly state otherwise,  any Contribution intentionally submitted for
+   inclusion in the Work by You to the Licensor shall be under the terms and conditions
+   of this License, without any additional terms or conditions. Notwithstanding the above,
+   nothing herein shall supersede or modify the terms of any separate license agreement
+   you may have executed with Licensor regarding such Contributions.
+
+
+6. Trademarks
+
+   This License does not grant permission to use the trade names, trademarks, service marks,
+   or product names of the Licensor, except as required for reasonable and customary use in
+   describing the origin of the Work and reproducing the content of the PRINCIPLE file.
+
+
+7. Disclaimer of Warranty
+
+   Unless required by applicable law or agreed to in writing, Licensor provides the Work
+   (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES
+   OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any
+   warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of
+   using or redistributing the Work and assume any risks associated with Your exercise of
+   permissions under this License.
+
+
+8. Limitation of Liability
+
+   In no event and under no legal theory, whether in tort (including negligence), contract,
+   or otherwise, unless required by applicable law (such as deliberate and grossly negligent
+   acts) or agreed to in writing, shall any Contributor be liable to You for damages, including
+   any direct, indirect, special, incidental, or consequential damages of any character arising
+   as a result of this License or out of the use or inability to use the Work (including but not
+   limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or
+   any and all other commercial damages or losses), even if such Contributor has been advised
+   of the possibility of such damages.
+
+
+9. Accepting Warranty or Additional Liability
+
+   While redistributing the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,  or other liability
+   obligations and/or rights consistent with this License. However, in accepting such
+   obligations, You may act only on Your own behalf and on Your sole responsibility, not
+   on behalf of any other Contributor, and only if You agree to indemnify, defend, and
+   hold each Contributor harmless for any liability incurred by, or claims asserted
+   against, such Contributor by reason of your accepting any such warranty or additional
+   liability.
+
+
+APPENDICES
+
+APPENDIX 1: How to apply the Radix.pro License to your work
+
+      To apply the Radix.pro License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+      Copyright [yyyy] [name of copyright owner]
+
+      Licensed under the Radix.pro License, Version 1.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://radix.pro/licenses/LICENSE-1.0-en_US.txt
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied.
+
+
+APPENDIX 2: Examples of comments
+
+/**********************************************************************
+
+  Copyright 2016 Andrey V.Kosteltsev
+
+  Licensed under the Radix.pro License, Version 1.0 (the "License");
+  you may not use this file  except  in compliance with the License.
+  You may obtain a copy of the License at
+
+     http://radix.pro/licenses/LICENSE-1.0-en_US.txt
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+  implied.
+
+ **********************************************************************/
+
+
+#!/bin/sh
+#######################################################################
+#
+# Copyright 2016 Andrey V.Kosteltsev
+#
+# Licensed under the Radix.pro License, Version 1.0 (the "License");
+# you may not use this file  except  in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://radix.pro/licenses/LICENSE-1.0-en_US.txt
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+#  implied.
+#
+#######################################################################
+
Index: build-system-1.2.3/doc/LICENSE-1.0-ru_RU.txt
===================================================================
--- build-system-1.2.3/doc/LICENSE-1.0-ru_RU.txt	(nonexistent)
+++ build-system-1.2.3/doc/LICENSE-1.0-ru_RU.txt	(revision 231)
@@ -0,0 +1,280 @@
+
+
+                                 Radix.pro License
+                              Версия 1.0, март 2016 г.
+                  http://radix.pro/licenses/LICENSE-1.0-ru_RU.txt
+
+
+1. Определения
+
+   1.1. «Лицензия»
+
+        это настоящий документ, пердставляющий собой Лицензионный договор, определяющий
+        условия использования, воспроизведения и распространения Работы, заключаемый
+        в упрощенном порядке и являющийся договором присоединения, вступающим в силу
+        в момент начала использования Работы.
+
+
+   1.2. «Лицензиар»
+
+        это владелец авторского права или лицо, уполномоченное владельцем авторских прав,
+        предоставляющие Лицензию.
+
+
+   1.3. «Юридическое лицо»
+
+        это объединение действующих лиц и остальных лиц, которые контролируют,
+        контролируются или находятся под общим контролем с действующими лицами.
+        Для целей данного определения, «контроль» означает:
+          a) силу, прямую или косвенную, определяющую развитие или управление такого лица
+             согласно договорённостям или иным образом, или
+          b) собственность пятидесяти процентов (50%) или более находящихся в обращении
+             акций, или
+          c) доверительное управление этим лицом.
+
+
+   1.4. «Вы»
+
+        это физическое или юридическое лицо, использующее права, предоставленные настоящей Лицензией.
+
+
+   1.5. «Лицензируемый»
+
+        это Работа или Производные работы передаваемые под настоящей Лицензией физическим
+        или Юридическим лицом, имеющим все права для предоставления, в максимально возможной
+        степени, как в момент первичного предоставления, так и в последствии.
+
+
+   1.6. «Исходная форма»
+
+        это форма представления Работы, предпочтительная для внесения изменений, включая исходный
+        код, исходные формы документации, конфигурационные файлы и не ограничиваясь таковыми.
+
+
+   1.7. «Объектная форма»
+
+        это результат автоматического преобразования Исходной формы, включающий исходный код,
+        откомпилированный в объектный, сгенерированную документацию и формы, полученные в результате
+        преобразования в другие форматы, предназначенные для массового распространения,
+        но не ограничивающийся таковыми.
+
+
+   1.8. «Работа»
+
+        это объект авторского права в Исходной или Объектной форме, доступный на условиях настоящей
+        Лицензии, о чём свидетельствует уведомление об авторстве, которое входит в Работу или прилагается
+        к ней (см. примеры, показанные в Приложениях).
+
+
+   1.9. «Производные работы»
+
+        это любые работы в Исходной или Объектной форме, основанные на Работе или полученные из неё,
+        для которых редакционные изменения, аннотации, развитие или иные изменения, имеют, в целом,
+        независимое авторство. Для целей настоящей Лицензии, Производные работы не включают работы,
+        которые отделимы от Работы и её производных, например, связываются по имени или ссылке
+        с интерфейсом Работы.
+
+
+  1.10. «Вклад»
+
+        это любое авторское произведение, в том числе оригинальная версия Работы, все изменения и
+        дополнения Работы и Производных работ, умышленно представленные Лицензиару для включения
+        в Работу владельцем авторского права или лицом (в том числе, юридическим лицом), уполномоченным
+        представлять владельца авторских прав. Для целей данного определения, «представление» означает
+        любую форму электронного, словесного или письменного сообщения, направленного Лицензиару или
+        его представителям, включая, но не ограничиваясь электронными списками рассылки, системами
+        управления исходным кодом и дефектами, управляемыми Лицензиаром или от его имени с целью
+        обсуждения и улучшения Работы, за исключением сообщений, помеченных владельцем авторских прав,
+        как «не вклад».
+
+
+  1.11. «Участник»
+
+        means Licensor and any individual or Legal Entity on behalf of whom a Contribution has been
+        received by Licensor and subsequently incorporated within the Work.
+
+        это Лицензиар, а также любое физическое или юридическое лицо, от имени которого Лицензиаром
+        был получен Вклад, впоследствии включенный в Работу.
+
+
+  1.12. «Патентные права» Участника
+
+        это любые патентные права Участника, включая Метод, Процесс, Устройство или Изделие, но не
+        ограничиваясь ими, Лицензируемые Участником, которые будут нарушены, но только в целях
+        представления Вклада под настоящей Лицензией, производством, использованием, продажей,
+        предложенем продажи, импортом и иным способом передачи Вклада.
+
+
+
+2. Предоставление прав
+
+   В соответствии с условиями настоящей Лицензии, каждый Участник настоящим предоставляет
+   Вам вечную, простую (неисключительную), бесплатную, безвозмездную, безотзывную лицензию прав
+   на воспроизведение, изменение, публичный показ, публичное исполнение, сублицензирование
+   и распространение Работы и Производных работ в Исходной и Объектной формах по всему миру.
+
+
+3. Предоставление патентных прав
+
+   В соответствии с условиями настоящей Лицензии, каждый Участник настоящим предоставляет
+   Вам вечную, простую (неисключительную), бесплатную, безвозмездную, безотзывную (кроме
+   случаев, перечисленных в этом разделе) патентную лицензию производить, произвести,
+   использовать, предлагать продать, продавать, импортировать и иным образом передавать
+   Работу по всему миру. Эта Лицензия относится только к таким патентным правам,
+   Лицензированным каким-либо Участником, которые неизбежно нарушаются (но лишь для того,
+   чтобы предоставить настоящую Лицензию) из-за представления этим Участником Вклада(Вкладов)
+   в отдельности, либо его Вкладом(Вкладами) в купе с Работой, в которую сделан данный
+   Вклад(Вклады). Если Вы начинаете патентный спор в отношении любого лица (включая
+   встречный иск), утверждая, что Работа или Вклад, включенный в работу, являются прямым
+   или частичным нарушением патентных прав, то все патентные права, предоставленные Вам
+   настоящей Лицензией, заканчиваются в день соответствующего судебного иска.
+
+
+4. Распространение
+
+   Вы можете воспроизводить и распространять копии Работы или Производных работ на любом
+   носителе, с изменениями или без, в Исходной или Объектной форме, при условии, что Вы
+   выполняете следующие условия:
+
+     a. Вы должны предоставить всем другим получателям Работы и Производных работ,
+        копию этой лицензии, и
+
+     b. Вы должны снабдить все модифицированные файлы явными уведомлениями, что Вы
+        изменили файлы, и
+
+     c. Вы должны сохранить в Исходной форме любых Производных работ, которые вы
+        распространяете, авторские права, патенты, торговые марки, а также
+        соответствующие уведомления из Исходной формы Работы, за исключением тех,
+        что не имеют отношения к какой-либо части Производной работы; и
+
+     d. Если Работа включает в себя текстовый файл «PRINCIPLE», как часть пакета, то любые
+        Производные работы, распространяемые Вами, должны включать читаемую копию этого
+        файла. Вы можете добавить в файл PRINCIPLE свои собственные фундаментальные
+        идеи, утверждения или предположения, которые служат основой понимания внутренней
+        структуры и принципов Производной Работы или Вклада.
+
+   Вы можете добавить свои собственные заявления об авторских правах на изменения, сделанные
+   вами. Кроме того, Вы можете предоставить дополнительные или иные лицензионные условия и
+   условия использования, воспроизведения или распространения Ваших модификаций или Производных
+   работ, как и работы в целом. Если Вы не представили собственных условий использования,
+   воспроизведения или растространения Работы, то указанные условия будут соответствовать
+   настоящей Лицензии.
+
+
+5. Предоставление вкладов
+
+   Если Вы явно не указали иное, любые материалы, намеренно представленные Вами для включения
+   в Работу Лицензиаром должны соответствовать положениям и условиям данной Лицензии без каких-либо
+   дополнительных условий или ограничений. Вышесказанное никаким образом не заменяет и не изменяет
+   условия любого отдельного лицензионного соглашения, заключённого Вами и Лицензиаром в отношении
+   таких Вкладов.
+
+
+6. Товарные знаки
+
+   Эта лицензия не дает разрешения на использование торговых наименований, товарных знаков,
+   знаков обслуживания или названий продуктов Лицензиара, за исключением случаев разумного
+   и обычного использования при описании происхождения Работы и воспроизведении содержания
+   файла PRINCIPLE.
+
+
+7. Отказ от гарантий
+
+   Если это не предусмотрено применимыми законами или не согласовано в письменной форме,
+   Лицензиар предоставляет Работу (и каждый Участник предоставляет свои Вклады) «КАК ЕСТЬ»,
+   БЕЗ ГАРАНТИЙ И УСЛОВИЙ ЛЮБОГО РОДА, явных или подразумеваемых, включая, без ограничений,
+   любые условия или гарантии ПРАВ СОБСТВЕННОСТИ, ПАТЕНТНЫХ ПРАВ, КОММЕРЧЕСКОЙ ЦЕННОСТИ
+   и ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННОЙ ЦЕЛИ. Вы несете полную ответственность за определение
+   целесообразности использования или распространения Работы и несёте риски, связанные
+   с осуществлением прав в соответствии с настоящей Лицензией.
+
+
+8. Ограничение ответственности
+
+   Ни в каком случае и ни на каком правовом поле, будь то в результате гражданского
+   правонарушения (включая халатность), по соглашению, или в других случаях, если только
+   это не требуется действующим законодательством (например, в случае преднамеренных
+   действий и грубой небрежности) или согласовано в письменной форме, никакой Участник
+   не будет нести ответственность перед Вами за убытки, в том числе любые прямые, косвенные,
+   специальные, случайные или последующие убытки любого характера, возникающие в результате
+   этой Лицензии или в связи с использованием или невозможностью использования Работы
+   (включая возмещение ущерба за потерю репутации, прекращение работы, компьютерный сбой
+   или неисправность, любые другие коммерческие убытки или потери, но не ограничиваясь ими),
+   даже если такой Участник был уведомлен о возможности таких убытков.
+
+
+9. Принятие ответственности по гарантиям
+
+   При распространении работы Вы можете предложить и взимать плату за гарантии, поддержку,
+   поручительство, компенсации и другие обязательства по ответственности или правам
+   в соответствии с настоящей Лицензией. Тем не менее, при принятии таких обязательств,
+   Вы действуете только от своего имени и под Вашу исключительную ответственность,
+   а не от имени какого-либо другого Участника, и только тогда, когда Вы согласны
+   компенсировать убытки, защищать и поддерживать каждого Участника от какой-либо
+   ответственности или претензий, заявленных по причине Вашего принятия таких гарантий
+   или дополнительной ответственности.
+
+
+ПРИЛОЖЕНИЯ
+
+ПРИЛОЖЕНИЕ 1: Как применить Лицензию Radix.pro к вашей работе
+
+      Чтобы применить Лицензию Radix.pro к вашей Работе, необходимо приложить следующее
+      уведомление, заменив поля, заключенные в скобки "[]" вашей собственной идентификационной
+      информацией (Не включая сами скобки!). Текст должен быть заключен в комментарий,
+      соответствующий синтаксису формата файла. Мы также рекомендуем, чтобы имя файла или
+      имя класса, а также описание назначения Работы были включены в ту же "печатную страницу",
+      как уведомление об авторских правах для упрощения идентификации сторонних архивов.
+
+      Copyright [год] [имя владельца авторских прав]
+
+      Лицензировано согласно Лицензии Radix.pro, Версия 1.0 ("Лицензия");
+      Вы можете использовать этот файл только в соответствии с Лицензией.
+      Вы можете найти копию Лицензии по адресу
+
+          http://radix.pro/licenses/LICENSE-1.0-ru_RU.txt
+
+      Если это не предусмотрено применимыми законами  или не согласовано
+      в письменной форме,  программное обеспечение,  распространяемое на
+      условиях данной Лицензии, предоставляется «КАК ЕСТЬ», БЕЗ ГАРАНТИЙ
+      И УСЛОВИЙ ЛЮБОГО РОДА, явных или подразумеваемых.
+
+
+ПРИЛОЖЕНИЕ 2: Примеры комментариев
+
+/**********************************************************************
+
+  Copyright 2016 Андрей В.Костельцев
+
+  Лицензировано согласно Лицензии Radix.pro, Версия 1.0 ("Лицензия");
+  Вы можете использовать этот файл только в соответствии с Лицензией.
+  Вы можете найти копию Лицензии по адресу
+
+     http://radix.pro/licenses/LICENSE-1.0-ru_RU.txt
+
+  Если это не предусмотрено применимыми законами  или не согласовано
+  в письменной форме,  программное обеспечение,  распространяемое на
+  условиях данной Лицензии, предоставляется «КАК ЕСТЬ», БЕЗ ГАРАНТИЙ
+  И УСЛОВИЙ ЛЮБОГО РОДА, явных или подразумеваемых.
+
+ **********************************************************************/
+
+
+#!/bin/sh
+#######################################################################
+#
+# Copyright 2016 Андрей В.Костельцев
+#
+# Лицензировано согласно Лицензии Radix.pro, Версия 1.0 ("Лицензия").
+# Вы можете использовать этот файл только в соответствии с Лицензией.
+# Вы можете найти копию Лицензии по адресу:
+#
+#    http://radix.pro/licenses/LICENSE-1.0-ru_RU.txt
+#
+# Если это не предусмотрено применимыми законами  или не согласовано
+# в письменной форме,  программное обеспечение,  распространяемое на
+# условиях данной Лицензии, предоставляется «КАК ЕСТЬ», БЕЗ ГАРАНТИЙ
+# И УСЛОВИЙ ЛЮБОГО РОДА, явных или подразумеваемых.
+#
+#######################################################################
+
Index: build-system-1.2.3/.gitignore
===================================================================
--- build-system-1.2.3/.gitignore	(nonexistent)
+++ build-system-1.2.3/.gitignore	(revision 231)
@@ -0,0 +1,52 @@
+
+# local config & object files
+build-config.mk
+sbin/
+usr/
+var/
+progs/autom4te.cache/
+progs/.config
+progs/config.log
+progs/config.status
+progs/configure
+
+# generated scripts
+pkgtool/check-db-integrity
+pkgtool/check-package
+pkgtool/check-requires
+pkgtool/install-package
+pkgtool/make-package
+pkgtool/remove-package
+pkgtool/update-package
+
+# Target build dirs
+.build-machine/
+
+# Timestamps
+.makefile
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Object Files
+*.[ao]
+
+# backup copies
+*~
Index: build-system-1.2.3/.svnignore
===================================================================
--- build-system-1.2.3/.svnignore	(nonexistent)
+++ build-system-1.2.3/.svnignore	(revision 231)
@@ -0,0 +1,52 @@
+
+# local config & object files
+build-config.mk
+sbin/
+usr/
+var/
+progs/autom4te.cache/
+progs/.config
+progs/config.log
+progs/config.status
+progs/configure
+
+# generated scripts
+pkgtool/check-db-integrity
+pkgtool/check-package
+pkgtool/check-requires
+pkgtool/install-package
+pkgtool/make-package
+pkgtool/remove-package
+pkgtool/update-package
+
+# Target build dirs
+.build-machine/
+
+# Timestamps
+.makefile
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Object Files
+*.[ao]
+
+# backup copies
+*~
Index: build-system-1.2.3/LICENSE
===================================================================
--- build-system-1.2.3/LICENSE	(nonexistent)
+++ build-system-1.2.3/LICENSE	(revision 231)
@@ -0,0 +1,268 @@
+
+
+                                 Radix.pro License
+                              Version 1.0, March 2016
+                  http://radix.pro/licenses/LICENSE-1.0-en_US.txt
+
+
+1. Definitions
+
+   1.1. "License"
+
+        means the terms and conditions for use, reproduction, and distribution
+        as defined by this document.
+
+
+   1.2. "Licensor"
+
+        means the copyright owner or entity authorized by the copyright owner that is
+        granting the License.
+
+
+   1.3. "Legal Entity"
+
+        means the union of the acting entity and all other entities that control, are
+        controlled by, or are under common control with that entity. For the purposes
+        of this definition, "control" means:
+          a. the power, direct or indirect, to cause the direction or management of such
+             entity, whether by contract or otherwise, or
+          b. ownership of fifty percent (50%) or more of the outstanding shares, or
+          c. beneficial ownership of such entity.
+
+
+   1.4. "You" (or "Your")
+
+        means an individual or Legal Entity exercising permissions granted by this License.
+
+
+   1.5. “Licensable”
+
+        means having the right to grant, to the maximum extent possible, whether at the
+        time of the initial grant or subsequently, any and all of the rights conveyed
+        by this License.
+
+
+   1.6. "Source Form"
+
+        means the form of the Work preferred for making Modifications, including but not limited
+        to software source code, documentation source, and configuration files.
+
+
+   1.7. "Object Form"
+
+        means any form resulting from mechanical  transformation or translation of a Source form,
+        including but not limited to compiled object code, generated documentation, and conversions
+        to other media types.
+
+
+   1.8. "Work"
+
+        means the work of authorship, whether in Source or Object Form, made available under
+        the License, as indicated by a copyright notice that is included in or attached to the work
+        (an example is provided in the Appendix below).
+
+
+   1.9. "Derivative Works"
+
+        means any work, whether in Source or Object Form, that is based on (or derived from) the Work
+        and for which the editorial revisions, annotations, elaborations, or other modifications
+        represent, as a whole, an original work of authorship. For the purposes of this License,
+        Derivative Works shall not include works that remain separable from, or merely link
+        (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
+
+
+  1.10. "Contribution"
+
+        means any work of authorship, including the original version of the Work and any modifications
+        or additions to that Work or Derivative Works thereof, that is intentionally submitted to
+        Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity
+        authorized to submit on behalf of the copyright owner. For the purposes of this definition,
+        "submitted" means any form of electronic, verbal, or written communication sent to the Licensor
+        or its representatives, including but not limited to communication on electronic mailing lists,
+        source code control systems, and issue tracking systems that are managed by, or on behalf of,
+        the Licensor for the purpose of discussing and improving the Work, but excluding communication
+        that is conspicuously marked or otherwise designated in writing by the copyright owner
+        as "Not a Contribution."
+
+
+  1.11. "Contributor"
+
+        means Licensor and any individual or Legal Entity on behalf of whom a Contribution has been
+        received by Licensor and subsequently incorporated within the Work.
+
+
+  1.12. “Patent Claims” of a Contributor
+
+        means any patent claim(s), including without limitation, method, process, and apparatus claims,
+        in any patent Licensable by such Contributor that would be infringed, but for the grant of the
+        License, by the making, using, selling, offering for sale, having made, import, or transfer
+        of either its Contributions or its Contributor Version.
+
+
+
+2. Grant of Copyright License
+
+   Subject to the terms and conditions of this License, each Contributor hereby grants to You
+   a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license
+   to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense,
+   and distribute the Work and such Derivative Works in Source or Object Form.
+
+
+3. Grant of Patent License
+
+   Subject to the terms and conditions of this License, each Contributor hereby grants
+   to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made, use, offer to
+   sell, sell, import, and otherwise transfer the Work, where such license applies only
+   to those patent claims Licensable by such Contributor that are necessarily infringed
+   by their Contribution(s) alone or by combination of their Contribution(s) with the
+   Work to which such Contribution(s) was submitted. If You institute patent litigation
+   against any entity (including a cross-claim or counterclaim in a lawsuit) alleging
+   that the Work or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses granted to You under
+   this License for that Work shall terminate as of the date such litigation is filed.
+
+
+4. Redistribution
+
+   You may reproduce and distribute copies of the Work or Derivative Works thereof
+   in any medium, with or without modifications, and in Source or Object Form, provided
+   that You meet the following conditions:
+
+     a. You must give any other recipients of the Work or  Derivative Works
+        a copy of this License; and
+     b. You must cause any modified files to carry prominent notices stating that
+        You changed the files; and
+     c. You must retain, in the Source form of any Derivative Works that You distribute,
+        all copyright, patent, trademark, and attribution notices from the Source form
+        of the Work, excluding those notices that do not pertain to any part of the
+        Derivative Works; and
+     d. If the Work includes a "PRINCIPLE" text file as part of its distribution, then
+        any Derivative Works that You distribute must include a readable copy of the
+        fundamental ideas, truths or propositions contained within such PRINCIPLE file.
+        You may add Your own fundamental ideas, truths or propositions that serves as
+        the foundation for understanding the internal structure and principles of
+        Derivative works or Contributions.
+
+   You may add Your own copyright statement to Your modifications and may provide additional
+   or different license terms and conditions for use, reproduction, or distribution of Your
+   modifications, or for any such Derivative Works as a whole, provided Your use, reproduction,
+   and distribution of the Work otherwise complies with the conditions stated in this License.
+
+
+5. Submission of Contributions
+
+   Unless You explicitly state otherwise,  any Contribution intentionally submitted for
+   inclusion in the Work by You to the Licensor shall be under the terms and conditions
+   of this License, without any additional terms or conditions. Notwithstanding the above,
+   nothing herein shall supersede or modify the terms of any separate license agreement
+   you may have executed with Licensor regarding such Contributions.
+
+
+6. Trademarks
+
+   This License does not grant permission to use the trade names, trademarks, service marks,
+   or product names of the Licensor, except as required for reasonable and customary use in
+   describing the origin of the Work and reproducing the content of the PRINCIPLE file.
+
+
+7. Disclaimer of Warranty
+
+   Unless required by applicable law or agreed to in writing, Licensor provides the Work
+   (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES
+   OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any
+   warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of
+   using or redistributing the Work and assume any risks associated with Your exercise of
+   permissions under this License.
+
+
+8. Limitation of Liability
+
+   In no event and under no legal theory, whether in tort (including negligence), contract,
+   or otherwise, unless required by applicable law (such as deliberate and grossly negligent
+   acts) or agreed to in writing, shall any Contributor be liable to You for damages, including
+   any direct, indirect, special, incidental, or consequential damages of any character arising
+   as a result of this License or out of the use or inability to use the Work (including but not
+   limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or
+   any and all other commercial damages or losses), even if such Contributor has been advised
+   of the possibility of such damages.
+
+
+9. Accepting Warranty or Additional Liability
+
+   While redistributing the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,  or other liability
+   obligations and/or rights consistent with this License. However, in accepting such
+   obligations, You may act only on Your own behalf and on Your sole responsibility, not
+   on behalf of any other Contributor, and only if You agree to indemnify, defend, and
+   hold each Contributor harmless for any liability incurred by, or claims asserted
+   against, such Contributor by reason of your accepting any such warranty or additional
+   liability.
+
+
+APPENDICES
+
+APPENDIX 1: How to apply the Radix.pro License to your work
+
+      To apply the Radix.pro License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+      Copyright [yyyy] [name of copyright owner]
+
+      Licensed under the Radix.pro License, Version 1.0 (the "License");
+      you may not use this file except in compliance with the License.
+      You may obtain a copy of the License at
+
+          http://radix.pro/licenses/LICENSE-1.0-en_US.txt
+
+      Unless required by applicable law or agreed to in writing, software
+      distributed under the License is distributed on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied.
+
+
+APPENDIX 2: Examples of comments
+
+/**********************************************************************
+
+  Copyright 2016 Andrey V.Kosteltsev
+
+  Licensed under the Radix.pro License, Version 1.0 (the "License");
+  you may not use this file  except  in compliance with the License.
+  You may obtain a copy of the License at
+
+     http://radix.pro/licenses/LICENSE-1.0-en_US.txt
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+  implied.
+
+ **********************************************************************/
+
+
+#!/bin/sh
+#######################################################################
+#
+# Copyright 2016 Andrey V.Kosteltsev
+#
+# Licensed under the Radix.pro License, Version 1.0 (the "License");
+# you may not use this file  except  in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://radix.pro/licenses/LICENSE-1.0-en_US.txt
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+#  implied.
+#
+#######################################################################
+
Index: build-system-1.2.3/README
===================================================================
--- build-system-1.2.3/README	(nonexistent)
+++ build-system-1.2.3/README	(revision 231)
@@ -0,0 +1,3 @@
+
+see README.md instead
+
Index: build-system-1.2.3/transmitting_hash
===================================================================
--- build-system-1.2.3/transmitting_hash	(nonexistent)
+++ build-system-1.2.3/transmitting_hash	(revision 231)
@@ -0,0 +1,172 @@
+#!/usr/bin/perl
+
+use FindBin;
+use lib $FindBin::Bin;
+
+use strict;
+use warnings FATAL => 'all';
+
+use File::Basename;
+use File::Temp;
+use File::Path qw(make_path remove_tree);
+use Storable qw(lock_store lock_nstore lock_retrieve);
+use _kxLab;
+
+
+my $program = basename( $0 );
+
+my ($hardware, $flavour, $poolname, $operation, $name, $value);
+my $value_only = 'no';
+
+sub usage
+{
+  print <<EOF;
+
+Usage: $program [options]
+Options:
+   {--get | --set}                  - type of operation;
+   --hardware=HARDWARE              - where HARDWARE ia a current HARDWARE name;
+   --flavour=FLAVOUR                - where FLAVOUR ia a current FLAVOUR name;
+   --pool-name=NAME                 - where NAME is the variables pool name;
+   --name=NAME                      - where NAME is a variable name;
+   --value=string                   - where 'string' is a value of variable;
+   --value-only                     - if this option is used then $program
+                                      prints out only value of required vatiable,
+                                      if this option is not used then $program
+                                      prints out the pair 'NAME=VALUE' without
+                                      spaces around of equal ('=') symbol.
+
+EOF
+  exit;
+}
+
+# args:
+#  - environment pool name ( perl,for example );
+#  - hardware name ( ci20, for example );
+#  - flavour name ( m512, for example );
+#  - variable;
+#  - value;
+sub save_env
+{
+  my $fname = shift;
+  my $name  = shift;
+  my $value = shift;
+
+  my $tabref;
+
+  if( -s $fname and defined( Storable::file_magic( $fname ) ) )
+  {
+    $tabref = lock_retrieve( $fname );
+    if( ! defined $tabref )
+    {
+      $tabref = 0;
+    }
+  }
+  $tabref->{ $name } = $value;
+  lock_store( \%$tabref, $fname );
+}
+
+sub get_env
+{
+  my $fname = shift;
+  my $name  = shift;
+
+  my $value = "";
+  my $tabref;
+
+  if( -s $fname and defined( Storable::file_magic( $fname ) ) )
+  {
+    $tabref = lock_retrieve( $fname );
+  }
+  if( defined $tabref )
+  {
+    my $val = $tabref->{ $name };
+    if( defined $val ) { $value = $val; }
+  }
+  return $value;
+}
+
+
+foreach ( @ARGV )
+{
+  if( /--hardware=(\S*)/ )
+  {
+    $hardware = $1;
+  }
+  elsif( /--flavour=(\S*)/ )
+  {
+    $flavour = $1;
+  }
+  elsif( /--pool-name=(\S*)/ )
+  {
+    $poolname = $1;
+  }
+  elsif( /--name=(\S*)/ )
+  {
+    $name = $1;
+  }
+  elsif( /--value=(\S*)/ )
+  {
+    $value = $1;
+  }
+  elsif( /--set/ )
+  {
+    $operation = 'set';
+  }
+  elsif( /--get/ )
+  {
+    $operation = 'get';
+  }
+  elsif( /--value-only/ )
+  {
+    $value_only = 'yes';
+  }
+  elsif( /--help/ )
+  {
+    usage;
+  }
+  else
+  {
+    usage;
+  }
+}
+
+if( ! defined $hardware  or $hardware  eq "" ) { usage; }
+if( ! defined $poolname  or $poolname  eq "" ) { usage; }
+if( ! defined $operation or $operation eq "" ) { usage; }
+if( ! defined $name      or $name      eq "" ) { usage; }
+if( $operation eq 'set' )
+{
+  if( ! defined $value   or $value     eq "" ) { usage; }
+}
+
+my $hash_fname;
+if( defined $flavour and $flavour ne "" )
+{
+  $hash_fname = _kxLab::build_system_tmpdir() . "/" . "." .
+                 $hardware . "." . $flavour . "." . $poolname . ".transmitting-hash";
+}
+else
+{
+  $hash_fname = _kxLab::build_system_tmpdir() . "/" . "." .
+                 $hardware . "." . $poolname . ".transmitting-hash";
+}
+
+if( $operation eq 'set' )
+{
+  save_env( $hash_fname, $name, $value );
+}
+else
+{
+  my $val = get_env( $hash_fname, $name );
+  if( defined $val and $val ne "" )
+  {
+    $value = $val;
+  }
+}
+
+#
+# ECHO according to '--value-only' option:
+#
+if( $value_only eq 'yes' ) { print $value ; }
+else                       { print $name . "=" . $value ; }

Property changes on: build-system-1.2.3/transmitting_hash
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: build-system-1.2.3/_kxLab.pm
===================================================================
--- build-system-1.2.3/_kxLab.pm	(nonexistent)
+++ build-system-1.2.3/_kxLab.pm	(revision 231)
@@ -0,0 +1,72 @@
+
+use File::Basename;
+
+use strict;
+use warnings FATAL => 'all';
+
+my $path = dirname( __FILE__ );
+
+package _kxLab;
+
+
+sub distro_name
+{
+  my $name = "kxLab";
+
+  open( FILE, "< $path/constants.mk" );
+
+  while( <FILE> )
+  {
+    if( /^DISTRO_NAME(.+= +)(.+)/ )
+    {
+      $name = $2;
+    }
+  }
+  close( FILE );
+
+  return $name;
+}
+
+sub build_system_tmpdir
+{
+  return $path . "/var/tmp";
+}
+
+sub build_system_path
+{
+  return $path;
+}
+
+sub error
+{
+  my $message = shift;
+  my $func = shift;
+
+  print STDERR "Error: $message\n";
+  if( defined( $func ) )
+  {
+    &$func();
+  }
+  exit 1;
+}
+
+sub command_error
+{
+  my $command = shift;
+  my $context = shift;
+
+  error( "$command failed at @{$context}[1] line @{$context}[2]" );
+}
+
+sub system
+{
+  my $command = shift;
+
+  if( system( $command ) )
+  {
+    my @context = caller;
+    command_error($command, \@context);
+  }
+}
+
+1;
Index: build-system-1.2.3/html/scripts/README
===================================================================
--- build-system-1.2.3/html/scripts/README	(nonexistent)
+++ build-system-1.2.3/html/scripts/README	(revision 231)
@@ -0,0 +1,7 @@
+
+Download:
+========
+
+wget http://code.jquery.com/jquery-1.10.2.js
+wget http://code.jquery.com/ui/1.11.2/jquery-ui.js
+wget http://d3js.org/d3.v3.min.js
Index: build-system-1.2.3/html/scripts/d3.v3.min.js
===================================================================
--- build-system-1.2.3/html/scripts/d3.v3.min.js	(nonexistent)
+++ build-system-1.2.3/html/scripts/d3.v3.min.js	(revision 231)
@@ -0,0 +1,5 @@
+!function(){function n(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function t(n){return null===n?0/0:+n}function e(n){return!isNaN(n)}function r(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function u(n){return n.length}function i(n){for(var t=1;n*t%1;)t*=10;return t}function o(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function a(){this._=Object.create(null)}function c(n){return(n+="")===la||n[0]===sa?sa+n:n}function l(n){return(n+="")[0]===sa?n.slice(1):n}function s(n){return c(n)in this._}function f(n){return(n=c(n))in this._&&delete this._[n]}function h(){var n=[];for(var t in this._)n.push(l(t));return n}function g(){var n=0;for(var t in this._)++n;return n}function p(){for(var n in this._)return!1;return!0}function v(){this._=Object.create(null)}function d(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function m(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=fa.length;r>e;++e){var u=fa[e]+t;if(u in n)return u}}function y(){}function x(){}function M(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new a;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function _(){Bo.event.preventDefault()}function b(){for(var n,t=Bo.event;n=t.sourceEvent;)t=n;return t}function w(n){for(var t=new x,e=0,r=arguments.length;++e<r;)t[arguments[e]]=M(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Bo.event;u.target=n,Bo.event=u,t[u.type].apply(e,r)}finally{Bo.event=i}}},t}function S(n){return ga(n,ya),n}function k(n){return"function"==typeof n?n:function(){return pa(n,this)}}function E(n){return"function"==typeof n?n:function(){return va(n,this)}}function A(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Bo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function C(n){return n.trim().replace(/\s+/g," ")}function N(n){return new RegExp("(?:^|\\s+)"+Bo.requote(n)+"(?:\\s+|$)","g")}function z(n){return(n+"").trim().split(/^|\s+/)}function L(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=z(n).map(T);var u=n.length;return"function"==typeof t?r:e}function T(n){var t=N(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",C(u+" "+n))):e.setAttribute("class",C(u.replace(t," ")))}}function q(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function R(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function D(n){return"function"==typeof n?n:(n=Bo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function P(n){return{__data__:n}}function U(n){return function(){return ma(this,n)}}function j(t){return arguments.length||(t=n),function(n,e){return n&&e?t(n.__data__,e.__data__):!n-!e}}function F(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function H(n){return ga(n,Ma),n}function O(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function Y(){var n=this.__transition__;n&&++n.active}function I(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Jo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Bo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=Z;a>0&&(n=n.slice(0,a));var l=ba.get(n);return l&&(n=l,c=V),a?t?u:r:t?y:i}function Z(n,t){return function(e){var r=Bo.event;Bo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Bo.event=r}}}function V(n,t){var e=Z(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function X(){var n=".dragsuppress-"+ ++Sa,t="click"+n,e=Bo.select(Qo).on("touchmove"+n,_).on("dragstart"+n,_).on("selectstart"+n,_);if(wa){var r=Ko.style,u=r[wa];r[wa]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),wa&&(r[wa]=u),i&&(e.on(t,function(){_(),o()},!0),setTimeout(o,0))}}function $(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>ka&&(Qo.scrollX||Qo.scrollY)){e=Bo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();ka=!(u.f||u.e),e.remove()}return ka?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function B(){return Bo.event.changedTouches[0].identifier}function W(){return Bo.event.target}function J(){return Qo}function G(n){return n>0?1:0>n?-1:0}function K(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function Q(n){return n>1?0:-1>n?Ea:Math.acos(n)}function nt(n){return n>1?Ca:-1>n?-Ca:Math.asin(n)}function tt(n){return((n=Math.exp(n))-1/n)/2}function et(n){return((n=Math.exp(n))+1/n)/2}function rt(n){return((n=Math.exp(2*n))-1)/(n+1)}function ut(n){return(n=Math.sin(n/2))*n}function it(){}function ot(n,t,e){return this instanceof ot?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ot?new ot(n.h,n.s,n.l):Mt(""+n,_t,ot):new ot(n,t,e)}function at(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new dt(u(n+120),u(n),u(n-120))}function ct(n,t,e){return this instanceof ct?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof ct?new ct(n.h,n.c,n.l):n instanceof st?ht(n.l,n.a,n.b):ht((n=bt((n=Bo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new ct(n,t,e)}function lt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new st(e,Math.cos(n*=La)*t,Math.sin(n)*t)}function st(n,t,e){return this instanceof st?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof st?new st(n.l,n.a,n.b):n instanceof ct?lt(n.h,n.c,n.l):bt((n=dt(n)).r,n.g,n.b):new st(n,t,e)}function ft(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=gt(u)*Ya,r=gt(r)*Ia,i=gt(i)*Za,new dt(vt(3.2404542*u-1.5371385*r-.4985314*i),vt(-.969266*u+1.8760108*r+.041556*i),vt(.0556434*u-.2040259*r+1.0572252*i))}function ht(n,t,e){return n>0?new ct(Math.atan2(e,t)*Ta,Math.sqrt(t*t+e*e),n):new ct(0/0,0/0,n)}function gt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function pt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function vt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function dt(n,t,e){return this instanceof dt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof dt?new dt(n.r,n.g,n.b):Mt(""+n,dt,at):new dt(n,t,e)}function mt(n){return new dt(n>>16,255&n>>8,255&n)}function yt(n){return mt(n)+""}function xt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function Mt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(St(u[0]),St(u[1]),St(u[2]))}return(i=$a.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function _t(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new ot(r,u,c)}function bt(n,t,e){n=wt(n),t=wt(t),e=wt(e);var r=pt((.4124564*n+.3575761*t+.1804375*e)/Ya),u=pt((.2126729*n+.7151522*t+.072175*e)/Ia),i=pt((.0193339*n+.119192*t+.9503041*e)/Za);return st(116*u-16,500*(r-u),200*(u-i))}function wt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function St(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function kt(n){return"function"==typeof n?n:function(){return n}}function Et(n){return n}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Ct(t,e,n,r)}}function Ct(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Bo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!Qo.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Bo.event;Bo.event=n;try{o.progress.call(i,c)}finally{Bo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Jo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Bo.rebind(i,o,"on"),null==r?i:i.get(Nt(r))}function Nt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function Lt(){var n=Tt(),t=qt()-n;t>24?(isFinite(t)&&(clearTimeout(Ga),Ga=setTimeout(Lt,t)),Ja=0):(Ja=1,Qa(Lt))}function Tt(){var n=Date.now();for(Ka=Ba;Ka;)n>=Ka.t&&(Ka.f=Ka.c(n-Ka.t)),Ka=Ka.n;return n}function qt(){for(var n,t=Ba,e=1/0;t;)t.f?t=n?n.n=t.n:Ba=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Wa=n,e}function Rt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Dt(n,t){var e=Math.pow(10,3*ca(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:Et;return function(n){var e=tc.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=ec.get(g)||Ut;var x=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=Bo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var M,_,b=n.lastIndexOf(".");if(0>b){var w=y?n.lastIndexOf("e"):-1;0>w?(M=n,_=""):(M=n.substring(0,w),_=n.substring(w))}else M=n.substring(0,b),_=t+n.substring(b+1);!l&&f&&(M=i(M,1/0));var S=v.length+M.length+_.length+(x?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return x&&(M=i(k+M,k.length?s-_.length:1/0)),u+=v,n=M+_,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(x?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new uc(e-1)),1),e}function i(n,e){return t(n=new uc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{uc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{uc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{uc=jt;var r=new jt;return r._=t,n(r,e)._}finally{uc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(c,a)),null!=(u=oc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.slice(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&uc!==jt,o=new(i?jt:uc);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(0|r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,l=e.length;c>a;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in oc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.slice(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function l(n,t,r){return e(n,C.X.toString(),t,r)}function s(n,t,e){var r=x.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{uc=jt;var t=new uc;return t._=n,r(t)}finally{uc=Date}}var r=t(n);return e.parse=function(n){try{uc=jt;var t=r.parse(n);return t&&t._}finally{uc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var x=Bo.map(),M=It(v),_=Zt(v),b=It(d),w=Zt(d),S=It(m),k=Zt(m),E=It(y),A=Zt(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Yt(n.getDate(),t,2)},e:function(n,t){return Yt(n.getDate(),t,2)},H:function(n,t){return Yt(n.getHours(),t,2)},I:function(n,t){return Yt(n.getHours()%12||12,t,2)},j:function(n,t){return Yt(1+rc.dayOfYear(n),t,3)},L:function(n,t){return Yt(n.getMilliseconds(),t,3)},m:function(n,t){return Yt(n.getMonth()+1,t,2)},M:function(n,t){return Yt(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Yt(n.getSeconds(),t,2)},U:function(n,t){return Yt(rc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Yt(rc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Yt(n.getFullYear()%100,t,2)},Y:function(n,t){return Yt(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function Yt(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function It(n){return new RegExp("^(?:"+n.map(Bo.requote).join("|")+")","i")}function Zt(n){for(var t=new a,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Vt(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Xt(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function $t(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Bt(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Wt(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.y=Gt(+r[0]),e+r[0].length):-1}function Jt(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Gt(n){return n+(n>68?1900:2e3)}function Kt(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){ac.lastIndex=0;var r=ac.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=0|ca(t)/60,u=ca(t)%60;return e+Yt(r,"0",2)+Yt(u,"0",2)}function oe(n,t,e){cc.lastIndex=0;var r=cc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ce(){}function le(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function se(n,t){n&&hc.hasOwnProperty(n.type)&&hc[n.type](n,t)}function fe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function he(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)fe(n[e],t,1);t.polygonEnd()}function ge(){function n(n,t){n*=La,t=t*La/2+Ea/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);pc.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;vc.point=function(o,a){vc.point=n,r=(t=o)*La,u=Math.cos(a=(e=a)*La/2+Ea/4),i=Math.sin(a)},vc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function xe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function Me(n){return[Math.atan2(n[1],n[0]),nt(n[2])]}function _e(n,t){return ca(n[0]-t[0])<Na&&ca(n[1]-t[1])<Na}function be(n,t){n*=La;var e=Math.cos(t*=La);we(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function we(n,t,e){++dc,yc+=(n-yc)/dc,xc+=(t-xc)/dc,Mc+=(e-Mc)/dc}function Se(){function n(n,u){n*=La;var i=Math.cos(u*=La),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),l=Math.atan2(Math.sqrt((l=e*c-r*a)*l+(l=r*o-t*c)*l+(l=t*a-e*o)*l),t*o+e*a+r*c);mc+=l,_c+=l*(t+(t=o)),bc+=l*(e+(e=a)),wc+=l*(r+(r=c)),we(t,e,r)}var t,e,r;Ac.point=function(u,i){u*=La;var o=Math.cos(i*=La);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),Ac.point=n,we(t,e,r)}}function ke(){Ac.point=be}function Ee(){function n(n,t){n*=La;var e=Math.cos(t*=La),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),l=u*c-i*a,s=i*o-r*c,f=r*a-u*o,h=Math.sqrt(l*l+s*s+f*f),g=r*o+u*a+i*c,p=h&&-Q(g)/h,v=Math.atan2(h,g);Sc+=p*l,kc+=p*s,Ec+=p*f,mc+=v,_c+=v*(r+(r=o)),bc+=v*(u+(u=a)),wc+=v*(i+(i=c)),we(r,u,i)}var t,e,r,u,i;Ac.point=function(o,a){t=o,e=a,Ac.point=n,o*=La;var c=Math.cos(a*=La);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),we(r,u,i)},Ac.lineEnd=function(){n(t,e),Ac.lineEnd=ke,Ac.point=be}}function Ae(){return!0}function Ce(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(_e(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new ze(e,n,null,!0),l=new ze(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new ze(r,n,null,!1),l=new ze(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),Ne(i),Ne(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Ne(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function ze(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Le(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function l(){y.point=o,d.lineEnd()}function s(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){s(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r)if(1&t){n=e[0];var u,r=n.length-1,o=-1;if(r>0){for(_||(i.polygonStart(),_=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=Bo.merge(g);var n=je(m,p);g.length?(_||(i.polygonStart(),_=!0),Ce(g,Re,n,e,i)):n&&(_||(i.polygonStart(),_=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),_&&(i.polygonEnd(),_=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=qe(),M=t(x),_=!1;return y}}function Te(n){return n.length>1}function qe(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:y,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Re(n,t){return((n=n.x)[0]<0?n[1]-Ca-Na:Ca-n[1])-((t=t.x)[0]<0?t[1]-Ca-Na:Ca-t[1])}function De(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Ea:-Ea,c=ca(i-e);ca(c-Ea)<Na?(n.point(e,r=(r+o)/2>0?Ca:-Ca),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Ea&&(ca(e-u)<Na&&(e-=u*Na),ca(i-a)<Na&&(i-=a*Na),r=Pe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function Pe(n,t,e,r){var u,i,o=Math.sin(n-e);return ca(o)>Na?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function Ue(n,t,e,r){var u;if(null==n)u=e*Ca,r.point(-Ea,u),r.point(0,u),r.point(Ea,u),r.point(Ea,0),r.point(Ea,-u),r.point(0,-u),r.point(-Ea,-u),r.point(-Ea,0),r.point(-Ea,u);else if(ca(n[0]-t[0])>Na){var i=n[0]<t[0]?Ea:-Ea;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function je(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;pc.reset();for(var a=0,c=t.length;c>a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+Ea/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+Ea/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>Ea,k=p*x;if(pc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*Aa:_,S^h>=e^m>=e){var E=de(pe(f),pe(n));xe(E);var A=de(u,E);xe(A);var C=(S^_>=0?-1:1)*nt(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Na>i||Na>i&&0>pc)^1&o}function Fe(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Ea:-Ea),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(_e(e,g)||_e(p,g))&&(p[0]+=Na,p[1]+=Na,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&_e(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),x=m*m-y*(ve(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ye(d,(-m-M)/y);if(me(_,p),_=Me(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=ca(A-Ea)<Na,N=C||Na>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(ca(_[0]-w)<Na?k:E):k<=_[1]&&_[1]<=E:A>Ea^(w<=_[0]&&_[0]<=S)){var z=ye(d,(-m+M)/y);return me(z,p),[_,Me(z)]}}}function u(t,e){var r=o?n:Ea-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ca(i)>Na,c=gr(n,6*La);return Le(t,e,c,o?[0,-n]:[-Ea,n-Ea])}function He(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Oe(n,t,e,r){function u(r,u){return ca(r[0]-n)<Na?u>0?0:3:ca(r[0]-e)<Na?u>0?2:1:ca(r[1]-t)<Na?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&K(l,i,n)>0&&++t:i[1]<=r&&K(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Nc,Math.min(Nc,n)),t=Math.max(-Nc,Math.min(Nc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=qe(),C=He(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Bo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return N}}function Ye(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function Ie(n){var t=0,e=Ea/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Ea/180,e=n[1]*Ea/180):[180*(t/Ea),180*(e/Ea)]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,nt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Lc+=u*n-r*t,r=n,u=t}var t,e,r,u;Pc.point=function(i,o){Pc.point=n,t=r=i,e=u=o},Pc.lineEnd=function(){n(t,e)}}function Xe(n,t){Tc>n&&(Tc=n),n>Rc&&(Rc=n),qc>t&&(qc=t),t>Dc&&(Dc=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){yc+=n,xc+=t,++Mc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);_c+=o*(t+n)/2,bc+=o*(e+r)/2,wc+=o,We(t=n,e=r)}var t,e;jc.point=function(r,u){jc.point=n,We(t=r,e=u)}}function Ge(){jc.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);_c+=o*(r+n)/2,bc+=o*(u+t)/2,wc+=o,o=u*n-r*t,Sc+=o*(r+n),kc+=o*(u+t),Ec+=3*o,We(r=n,u=t)}var t,e,r,u;jc.point=function(i,o){jc.point=n,We(t=r=i,e=u=o)},jc.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,Aa)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:y};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function s(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=l+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=ca(ca(w)-1)<Na||ca(r-h)<Na?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],z=C-t,L=N-e,T=x*z-y*L;
+(T*T/M>i||ca((y*z+x*L)/M-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*La),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Ta,e*Ta])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*La,n[1]*La),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Ta,n[1]*Ta]}function r(){a=Ye(o=lr(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Cc,_=Et,b=null,w=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(M(o,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Cc):Fe((b=+n)*La),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Oe(n[0][0],n[0][1],n[1][0],n[1][1]):Et,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*La,d=n[1]%360*La,r()):[v*Ta,d*Ta]},t.rotate=function(n){return arguments.length?(m=n[0]%360*La,y=n[1]%360*La,x=n.length>2?n[2]%360*La:0,r()):[m*Ta,y*Ta,x*Ta]},Bo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*La,e*La)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>Ea?n-Aa:-Ea>n?n+Aa:n,t]}function lr(n,t,e){return n?t||e?Ye(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>Ea?t-Aa:-Ea>t?t+Aa:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),nt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),nt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*Aa)):(u=n+o*Aa,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=Me([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,xe(e);var r=Q(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Na)%(2*Math.PI)}function vr(n,t,e){var r=Bo.range(n,t-Na,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=Bo.range(n,t-Na,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function xr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(ut(r-t)+u*o*ut(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Ta,Math.atan2(o,Math.sqrt(r*r+u*u))*Ta]}:function(){return[n*Ta,t*Ta]};return p.distance=h,p}function Mr(){function n(n,u){var i=Math.sin(u*=La),o=Math.cos(u),a=ca((n*=La)-t),c=Math.cos(a);Fc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Hc.point=function(u,i){t=u*La,e=Math.sin(i*=La),r=Math.cos(i),Hc.point=n},Hc.lineEnd=function(){Hc.point=Hc.lineEnd=y}}function _r(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function br(n,t){function e(n,t){o>0?-Ca+Na>t&&(t=-Ca+Na):t>Ca-Na&&(t=Ca-Na);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Ea/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=G(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ca]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ca(u)<Na?ar:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-G(u)*Math.sqrt(n*n+e*e)]},e)}function Sr(n,t){return[n,Math.log(Math.tan(Ea/4+t/2))]}function kr(n){var t,e=ur(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=Ea*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Er(n,t){return[Math.log(Math.tan(Ea/4+t/2)),-n]}function Ar(n){return n[0]}function Cr(n){return n[1]}function Nr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&K(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function Lr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Tr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function qr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=Kc.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),Wc.remove(n),Kc.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&ca(e-c.circle.x)<Na&&ca(r-c.circle.cy)<Na;)i=c.P,a.unshift(c),Pr(c),c=i;a.unshift(c),Xr(c);for(var l=o;l.circle&&ca(e-l.circle.x)<Na&&ca(r-l.circle.cy)<Na;)o=l.N,a.push(l),Pr(l),l=o;a.push(l),Xr(l);var s,f=a.length;for(s=1;f>s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Wc._;a;)if(r=Fr(a,o)-i,r>Na)a=a.L;else{if(u=i-Hr(a,o),!(u>Na)){r>-Na?(t=a.P,e=a):u>-Na?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(Wc.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),Wc.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),Vr(e),void 0;if(!e)return c.edge=Jr(t.site,c.site),void 0;Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+s,y:(h*x-v*y)/m+f};Kr(e.edge,l,p,M),c.edge=Jr(l,n,null,M),e.edge=Jr(n,p,null,M),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Yr(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Bc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(ca(r-t)>Na||ca(u-e)>Na)&&(a.splice(o,0,new Qr(Gr(i.site,s,ca(r-f)<Na&&p-u>Na?{x:f,y:ca(t-f)<Na?e:p}:ca(u-p)<Na&&h-r>Na?{x:ca(e-p)<Na?t:h,y:p}:ca(r-h)<Na&&u-g>Na?{x:h,y:ca(t-h)<Na?e:g}:ca(u-g)<Na&&r-f>Na?{x:ca(e-g)<Na?t:f,y:g}:null),i.site,null)),++c)}function Ir(n,t){return t.angle-n.angle}function Zr(){tu(this),this.x=this.y=this.arc=this.site=this.cy=null}function Vr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,l=r.y-a,s=i.x-o,f=i.y-a,h=2*(c*f-l*s);if(!(h>=-za)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=Qc.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Gc._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}Gc.insert(y,m),y||(Jc=m)}}}}function Xr(n){var t=n.circle;t&&(t.P||(Jc=t.N),Gc.remove(t),Qc.push(t),tu(t),n.circle=null)}function $r(n){for(var t,e=$c,r=He(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Br(t,n)||!r(t)||ca(t.a.x-t.b.x)<Na&&ca(t.a.y-t.b.y)<Na)&&(t.a=t.b=null,e.splice(u,1))}function Br(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],l=t[1][1],s=n.l,f=n.r,h=s.x,g=s.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.y<c)return}else i={x:d,y:l};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.y<c)return}else i={x:(l-u)/r,y:l};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Wr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Jr(n,t,e,r){var u=new Wr(n,t);return $c.push(u),e&&Kr(u,n,t,e),r&&Kr(u,t,n,r),Bc[n.i].edges.push(new Qr(u,n,t)),Bc[t.i].edges.push(new Qr(u,t,n)),u}function Gr(n,t,e){var r=new Wr(n,null);return r.a=t,r.b=e,$c.push(r),r}function Kr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Qr(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function nu(){this._=null}function tu(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function eu(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ru(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function uu(n){for(;n.L;)n=n.L;return n}function iu(n,t){var e,r,u,i=n.sort(ou).pop();for($c=[],Bc=new Array(n.length),Wc=new nu,Gc=new nu;;)if(u=Jc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Bc[i.i]=new Or(i),jr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;Ur(u.arc)}t&&($r(t),Yr(t));var o={cells:Bc,edges:$c};return Wc=Gc=$c=Bc=null,o}function ou(n,t){return t.y-n.y||t.x-n.x}function au(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function cu(n){return n.x}function lu(n){return n.y}function su(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function fu(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&fu(n,c[0],e,r,o,a),c[1]&&fu(n,c[1],o,r,u,a),c[2]&&fu(n,c[2],e,a,o,i),c[3]&&fu(n,c[3],o,a,u,i)}}function hu(n,t){n=Bo.rgb(n),t=Bo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+xt(Math.round(e+i*n))+xt(Math.round(r+o*n))+xt(Math.round(u+a*n))}}function gu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=du(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function pu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function vu(n,t){var e,r,u,i=tl.lastIndex=el.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=tl.exec(n))&&(r=el.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:pu(e,r)})),i=el.lastIndex;return i<t.length&&(u=t.slice(i),a[o]?a[o]+=u:a[++o]=u),a.length<2?c[0]?(t=c[0].x,function(n){return t(n)+""}):function(){return t}:(t=c.length,function(n){for(var e,r=0;t>r;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function du(n,t){for(var e,r=Bo.interpolators.length;--r>=0&&!(e=Bo.interpolators[r](n,t)););return e}function mu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(du(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function yu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function Mu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function bu(n){return n*n*n}function wu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Su(n){return function(t){return Math.pow(t,n)}}function ku(n){return 1-Math.cos(n*Ca)}function Eu(n){return Math.pow(2,10*(n-1))}function Au(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Aa*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Aa/t)}}function Nu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function zu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=Bo.hcl(n),t=Bo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return lt(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=Bo.hsl(n),t=Bo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return at(e+i*n,r+o*n,u+a*n)+""}}function qu(n,t){n=Bo.lab(n),t=Bo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ft(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Du(n){var t=[n.a,n.b],e=[n.c,n.d],r=Uu(t),u=Pu(t,e),i=Uu(ju(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Ta,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*Ta:0}function Pu(n,t){return n[0]*t[0]+n[1]*t[1]}function Uu(n){var t=Math.sqrt(Pu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function ju(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Fu(n,t){var e,r=[],u=[],i=Bo.transform(n),o=Bo.transform(t),a=i.translate,c=o.translate,l=i.rotate,s=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:pu(a[0],c[0])},{i:3,x:pu(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),l!=s?(l-s>180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:pu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:pu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:pu(g[0],p[0])},{i:e-2,x:pu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Hu(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Ou(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Yu(n){for(var t=n.source,e=n.target,r=Zu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function Iu(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Zu(n,t){if(n===t)return n;for(var e=Iu(n),r=Iu(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Vu(n){n.fixed|=2}function Xu(n){n.fixed&=-7}function $u(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Bu(n){n.fixed&=-5}function Wu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Wu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var l=t*e[n.point.index];n.charge+=n.pointCharge=l,r+=l*n.point.x,u+=l*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Ju(n,t){return Bo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=ei,n}function Gu(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(u=n.children)&&(r=u.length))for(var r,u;--r>=0;)e.push(u[r])}function Ku(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++o<u;)e.push(i[o]);for(;null!=(n=r.pop());)t(n)}function Qu(n){return n.children}function ni(n){return n.value}function ti(n,t){return t.value-n.value}function ei(n){return Bo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function ri(n){return n.x}function ui(n){return n.y}function ii(n,t,e){n.y0=t,n.y=e}function oi(n){return Bo.range(n.length)}function ai(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ci(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function li(n){return n.reduce(si,0)}function si(n,t){return n+t[1]}function fi(n,t){return hi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function hi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function gi(n){return[Bo.min(n),Bo.max(n)]}function pi(n,t){return n.value-t.value}function vi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function di(n,t){n._pack_next=t,t._pack_prev=n}function mi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function yi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],bi(r,u,i),t(i),vi(r,i),r._pack_prev=i,vi(i,u),u=r._pack_next,o=3;l>o;o++){bi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(mi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!mi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?di(r,u=a):di(r=c,u),o--):(vi(r,i),u=i,t(i))}var m=(s+f)/2,y=(h+g)/2,x=0;for(o=0;l>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Mi)}}function xi(n){n._pack_next=n._pack_prev=n}function Mi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)_i(u[i],t,e,r)}function bi(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),l=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+l*i,e.y=n.y+c*i-l*u}else e.x=n.x+r,e.y=n.y}function wi(n,t){return n.parent==t.parent?1:2}function Si(n){var t=n.children;return t.length?t[0]:n.t}function ki(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ei(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Ai(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function Ni(n){return 1+Bo.max(n,function(n){return n.y})}function zi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function qi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ri(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Di(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Pi(n){return n.rangeExtent?n.rangeExtent():Di(n.range())}function Ui(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function ji(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Fi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:gl}function Hi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Bo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Oi(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?Hi:Ui,c=r?Ou:Hu;return o=u(n,t,c,e),a=u(t,n,c,du),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Ru)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Vi(n,t)},i.tickFormat=function(t,e){return Xi(n,t,e)},i.nice=function(t){return Ii(n,t),u()},i.copy=function(){return Oi(n,t,e,r)},u()}function Yi(n,t){return Bo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Ii(n,t){return ji(n,Fi(Zi(n,t)[2]))}function Zi(n,t){null==t&&(t=10);var e=Di(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Vi(n,t){return Bo.range.apply(Bo,Zi(n,t))}function Xi(n,t,e){var r=Zi(n,t);if(e){var u=tc.exec(e);if(u.shift(),"s"===u[8]){var i=Bo.formatPrefix(Math.max(ca(r[0]),ca(r[1])));return u[7]||(u[7]="."+$i(i.scale(r[2]))),u[8]="f",e=Bo.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Bi(u[8],r)),e=u.join("")}else e=",."+$i(r[2])+"f";return Bo.format(e)}function $i(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Bi(n,t){var e=$i(t[2]);return n in pl?Math.abs(e-$i(Math.max(ca(t[0]),ca(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Wi(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=ji(r.map(u),e?Math:dl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Di(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++<s;)for(var h=f-1;h>0;h--)o.push(i(l)*h);for(l=0;o[l]<a;l++);for(s=o.length;o[s-1]>c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return vl;arguments.length<2?t=vl:"function"!=typeof t&&(t=Bo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Wi(n.copy(),t,e,r)},Yi(o,n)}function Ji(n,t,e){function r(t){return n(u(t))}var u=Gi(t),i=Gi(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Vi(e,n)},r.tickFormat=function(n,t){return Xi(e,n,t)},r.nice=function(n){return r.domain(Ii(e,n))},r.exponent=function(o){return arguments.length?(u=Gi(t=o),i=Gi(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Ji(n.copy(),t,e)},Yi(r,n)}function Gi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Ki(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return Bo.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new a;for(var i,o=-1,c=r.length;++o<c;)u.has(i=r[o])||u.set(i,n.push(i));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(i=n,o=0,t={t:"range",a:arguments},e):i},e.rangePoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=(l-c)/(Math.max(1,n.length-1)+a);return i=r(n.length<2?(c+l)/2:c+s*a/2,s),o=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=(f-s)/(n.length-a+2*c);return i=r(s+h*c,h),l&&i.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=Math.floor((f-s)/(n.length-a+2*c)),g=f-s-(n.length-a)*h;return i=r(s+Math.round(g/2),h),l&&i.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Di(t.a[0])},e.copy=function(){return Ki(n,t)},e.domain(n)}function Qi(r,u){function i(){var n=0,t=u.length;for(a=[];++n<t;)a[n-1]=Bo.quantile(r,n/t);return o}function o(n){return isNaN(n=+n)?void 0:u[Bo.bisect(a,n)]}var a;return o.domain=function(u){return arguments.length?(r=u.map(t).filter(e).sort(n),i()):r},o.range=function(n){return arguments.length?(u=n,i()):u},o.quantiles=function(){return a},o.invertExtent=function(n){return n=u.indexOf(n),0>n?[0/0,0/0]:[n>0?a[n-1]:r[0],n<a.length?a[n]:r[r.length-1]]},o.copy=function(){return Qi(r,u)},i()}function no(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return no(n,t,e)},u()}function to(n,t){function e(e){return e>=e?t[Bo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return to(n,t)},e}function eo(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Vi(n,t)},t.tickFormat=function(t,e){return Xi(n,t,e)},t.copy=function(){return eo(n)},t}function ro(n){return n.innerRadius}function uo(n){return n.outerRadius}function io(n){return n.startAngle}function oo(n){return n.endAngle}function ao(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=kt(e),p=kt(r);++f<h;)u.call(this,c=t[f],f)?s.push([+g.call(this,c,f),+p.call(this,c,f)]):s.length&&(o(),s=[]);return s.length&&o(),l.length?l.join(""):null}var e=Ar,r=Cr,u=Ae,i=co,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=wl.get(n)||co).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function co(n){return n.join("L")}function lo(n){return co(n)+"Z"}function so(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function fo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function ho(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function go(n,t){return n.length<4?co(n):n[1]+mo(n.slice(1,n.length-1),yo(n,t))}function po(n,t){return n.length<3?co(n):n[0]+mo((n.push(n[0]),n),yo([n[n.length-2]].concat(n,[n[1]]),t))}function vo(n,t){return n.length<3?co(n):n[0]+mo(n,yo(n,t))}function mo(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return co(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l<t.length;l++,c++)i=n[c],a=t[l],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var s=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+s[0]+","+s[1]}return r}function yo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function xo(n){if(n.length<3)return co(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",wo(El,o),",",wo(El,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),So(c,o,a);return n.pop(),c.push("L",r),c.join("")}function Mo(n){if(n.length<4)return co(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(wo(El,i)+","+wo(El,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),So(e,i,o);return e.join("")}function _o(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[wo(El,o),",",wo(El,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),So(t,o,a);return t.join("")}function bo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,l=-1;++l<=e;)r=n[l],u=l/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return xo(n)}function wo(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function So(n,t,e){n.push("C",wo(Sl,t),",",wo(Sl,e),",",wo(kl,t),",",wo(kl,e),",",wo(El,t),",",wo(El,e))}function ko(n,t){return(t[1]-n[1])/(t[0]-n[0])}function Eo(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=ko(u,i);++t<e;)r[t]=(o+(o=ko(u=i,i=n[t+1])))/2;return r[t]=o,r}function Ao(n){for(var t,e,r,u,i=[],o=Eo(n),a=-1,c=n.length-1;++a<c;)t=ko(n[a],n[a+1]),ca(t)<Na?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function Co(n){return n.length<3?co(n):n[0]+mo(n,Ao(n))}function No(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+_l,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function zo(n){function t(t){function c(){v.push("M",a(n(m),f),s,l(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=kt(e),_=kt(u),b=e===r?function(){return g}:kt(r),w=u===i?function(){return p}:kt(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=Ar,r=Ar,u=0,i=Cr,o=Ae,a=co,c=a.key,l=a,s="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=wl.get(n)||co).key,l=a.reverse||a,s=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function Lo(n){return n.radius}function To(n){return[n.x,n.y]}function qo(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+_l;return[e*Math.cos(r),e*Math.sin(r)]}}function Ro(){return 64}function Do(){return"circle"}function Po(n){var t=Math.sqrt(n/Ea);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Uo(n,t){return ga(n,Tl),n.id=t,n}function jo(n,t,e,r){var u=n.id;return F(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Fo(n){return null==n&&(n=""),function(){this.textContent=n}}function Ho(n,t,e,r){var u=n.__transition__||(n.__transition__={active:0,count:0}),i=u[e];if(!i){var o=r.time;i=u[e]={tween:new a,time:o,ease:r.ease,delay:r.delay,duration:r.duration},++u.count,Bo.timer(function(r){function a(r){return u.active>e?l():(u.active=e,i.event&&i.event.start.call(n,s,t),i.tween.forEach(function(e,r){(r=r.call(n,s,t))&&v.push(r)
+}),Bo.timer(function(){return p.c=c(r||1)?Ae:c,1},0,o),void 0)}function c(r){if(u.active!==e)return l();for(var o=r/g,a=f(o),c=v.length;c>0;)v[--c].call(n,a);return o>=1?(i.event&&i.event.end.call(n,s,t),l()):void 0}function l(){return--u.count?delete u[e]:delete n.__transition__,1}var s=n.__data__,f=i.ease,h=i.delay,g=i.duration,p=Ka,v=[];return p.t=h+o,r>=h?a(r-h):(p.c=a,void 0)},0,o)}}function Oo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Yo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Io(n){return n.toISOString()}function Zo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Bo.bisect(Ol,u);return i==Ol.length?[t.year,Zi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Ol[i-1]<Ol[i]/u?i-1:i]:[Zl,Zi(n,e)[2]]}return r.invert=function(t){return Vo(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Vo)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Vo(+e+1),t).length}var i=r.domain(),o=Di(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(ji(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Vo(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Vo(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Di(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Vo(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Zo(n.copy(),t,e)},Yi(r,n)}function Vo(n){return new Date(n)}function Xo(n){return JSON.parse(n.responseText)}function $o(n){var t=Go.createRange();return t.selectNode(Go.body),t.createContextualFragment(n.responseText)}var Bo={version:"3.4.13"};Date.now||(Date.now=function(){return+new Date});var Wo=[].slice,Jo=function(n){return Wo.call(n)},Go=document,Ko=Go.documentElement,Qo=window;try{Jo(Ko.childNodes)[0].nodeType}catch(na){Jo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{Go.createElement("div").style.setProperty("opacity",0,"")}catch(ta){var ea=Qo.Element.prototype,ra=ea.setAttribute,ua=ea.setAttributeNS,ia=Qo.CSSStyleDeclaration.prototype,oa=ia.setProperty;ea.setAttribute=function(n,t){ra.call(this,n,t+"")},ea.setAttributeNS=function(n,t,e){ua.call(this,n,t,e+"")},ia.setProperty=function(n,t,e){oa.call(this,n,t+"",e)}}Bo.ascending=n,Bo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Bo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Bo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Bo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Bo.sum=function(n,t){var r,u=0,i=n.length,o=-1;if(1===arguments.length)for(;++o<i;)e(r=+n[o])&&(u+=r);else for(;++o<i;)e(r=+t.call(n,n[o],o))&&(u+=r);return u},Bo.mean=function(n,r){var u,i=0,o=n.length,a=-1,c=o;if(1===arguments.length)for(;++a<o;)e(u=t(n[a]))?i+=u:--c;else for(;++a<o;)e(u=t(r.call(n,n[a],a)))?i+=u:--c;return c?i/c:void 0},Bo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Bo.median=function(r,u){var i,o=[],a=r.length,c=-1;if(1===arguments.length)for(;++c<a;)e(i=t(r[c]))&&o.push(i);else for(;++c<a;)e(i=t(u.call(r,r[c],c)))&&o.push(i);return o.length?Bo.quantile(o.sort(n),.5):void 0};var aa=r(n);Bo.bisectLeft=aa.left,Bo.bisect=Bo.bisectRight=aa.right,Bo.bisector=function(t){return r(1===t.length?function(e,r){return n(t(e),r)}:t)},Bo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Bo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Bo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Bo.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=Bo.min(arguments,u),e=new Array(t);++n<t;)for(var r,i=-1,o=e[n]=new Array(r);++i<r;)o[i]=arguments[i][n];return e},Bo.transpose=function(n){return Bo.zip.apply(Bo,n)},Bo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Bo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Bo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Bo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ca=Math.abs;Bo.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/e)throw new Error("infinite range");var r,u=[],o=i(ca(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)u.push(r/o);else for(;(r=n+e*++a)<t;)u.push(r/o);return u},Bo.map=function(n){var t=new a;if(n instanceof a)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t};var la="__proto__",sa="\x00";o(a,{has:s,get:function(n){return this._[c(n)]},set:function(n,t){return this._[c(n)]=t},remove:f,keys:h,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:l(t),value:this._[t]});return n},size:g,empty:p,forEach:function(n){for(var t in this._)n.call(this,l(t),this._[t])}}),Bo.nest=function(){function n(t,o,c){if(c>=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var l,s,f,h,g=-1,p=o.length,v=i[c++],d=new a;++g<p;)(h=d.get(l=v(s=o[g])))?h.push(s):d.set(l,[s]);return t?(s=t(),f=function(e,r){s.set(e,n(t,r,c))}):(s={},f=function(e,r){s[e]=n(t,r,c)}),d.forEach(f),s}function t(n,e){if(e>=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(Bo.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},Bo.set=function(n){var t=new v;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},o(v,{has:s,add:function(n){return this._[c(n+="")]=!0,n},remove:f,values:h,size:g,empty:p,forEach:function(n){for(var t in this._)n.call(this,l(t))}}),Bo.behavior={},Bo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=d(n,t,t[e]);return n};var fa=["webkit","ms","moz","Moz","o","O"];Bo.dispatch=function(){for(var n=new x,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=M(n);return n},x.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Bo.event=null,Bo.requote=function(n){return n.replace(ha,"\\$&")};var ha=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ga={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},pa=function(n,t){return t.querySelector(n)},va=function(n,t){return t.querySelectorAll(n)},da=Ko.matches||Ko[m(Ko,"matchesSelector")],ma=function(n,t){return da.call(n,t)};"function"==typeof Sizzle&&(pa=function(n,t){return Sizzle(n,t)[0]||null},va=Sizzle,ma=Sizzle.matchesSelector),Bo.selection=function(){return _a};var ya=Bo.selection.prototype=[];ya.select=function(n){var t,e,r,u,i=[];n=k(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,l=r.length;++c<l;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return S(i)},ya.selectAll=function(n){var t,e,r=[];n=E(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Jo(n.call(e,e.__data__,a,u))),t.parentNode=e);return S(r)};var xa={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Bo.ns={prefix:xa,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.slice(0,t),n=n.slice(t+1)),xa.hasOwnProperty(e)?{space:xa[e],local:n}:n}},ya.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Bo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(A(t,n[t]));return this}return this.each(A(n,t))},ya.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=z(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!N(n[u]).test(t))return!1;return!0}for(t in n)this.each(L(t,n[t]));return this}return this.each(L(n,t))},ya.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(q(e,n[e],t));return this}if(2>r)return Qo.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(q(n,t,e))},ya.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},ya.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},ya.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},ya.append=function(n){return n=D(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},ya.insert=function(n,t){return n=D(n),t=k(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},ya.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},ya.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new a,y=new Array(o);for(r=-1;++r<o;)m.has(d=t.call(u=n[r],u.__data__,r))?v[r]=u:m.set(d,u),y[r]=d;for(r=-1;++r<f;)(u=m.get(d=t.call(e,i=e[r],r)))?u!==!0&&(g[r]=u,u.__data__=i):p[r]=P(i),m.set(d,!0);for(r=-1;++r<o;)m.get(y[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],i=e[r],u?(u.__data__=i,g[r]=u):p[r]=P(i);for(;f>r;++r)p[r]=P(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),l.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++i<o;)(u=r[i])&&(n[i]=u.__data__);return n}var c=H([]),l=S([]),s=S([]);if("function"==typeof n)for(;++i<o;)e(r=this[i],n.call(r,r.parentNode.__data__,i));else for(;++i<o;)e(r=this[i],n);return l.enter=function(){return c},l.exit=function(){return s},l},ya.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},ya.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=U(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return S(u)},ya.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},ya.sort=function(n){n=j.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},ya.each=function(n){return F(this,function(t,e,r){n.call(t,t.__data__,e,r)})},ya.call=function(n){var t=Jo(arguments);return n.apply(t[0]=this,t),this},ya.empty=function(){return!this.node()},ya.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},ya.size=function(){var n=0;return F(this,function(){++n}),n};var Ma=[];Bo.selection.enter=H,Bo.selection.enter.prototype=Ma,Ma.append=ya.append,Ma.empty=ya.empty,Ma.node=ya.node,Ma.call=ya.call,Ma.size=ya.size,Ma.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var l=-1,s=u.length;++l<s;)(i=u[l])?(t.push(r[l]=e=n.call(u.parentNode,i.__data__,l,a)),e.__data__=i.__data__):t.push(null)}return S(o)},Ma.insert=function(n,t){return arguments.length<2&&(t=O(this)),ya.insert.call(this,n,t)},ya.transition=function(){for(var n,t,e=Cl||++ql,r=[],u=Nl||{time:Date.now(),ease:wu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,l=a.length;++c<l;)(t=a[c])&&Ho(t,c,e,u),n.push(t)}return Uo(r,e)},ya.interrupt=function(){return this.each(Y)},Bo.select=function(n){var t=["string"==typeof n?pa(n,Go):n];return t.parentNode=Ko,S([t])},Bo.selectAll=function(n){var t=Jo("string"==typeof n?va(n,Go):n);return t.parentNode=Ko,S([t])};var _a=Bo.select(Ko);ya.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(I(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(I(n,t,e))};var ba=Bo.map({mouseenter:"mouseover",mouseleave:"mouseout"});ba.forEach(function(n){"on"+n in Go&&ba.remove(n)});var wa="onselectstart"in Go?null:m(Ko.style,"userSelect"),Sa=0;Bo.mouse=function(n){return $(n,b())};var ka=/WebKit/.test(Qo.navigator.userAgent)?-1:0;Bo.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=b().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return $(n,r)},Bo.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",i)}function t(n,t,u,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-x[0],e=r[1]-x[1],p|=n|e,x=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&Bo.event.target===f),g({type:"dragend"}))}var l,s=this,f=Bo.event.target,h=s.parentNode,g=e.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=Bo.select(u()).on(i+d,a).on(o+d,c),y=X(),x=t(h,v);r?(l=r.apply(s,arguments),l=[l.x-x[0],l.y-x[1]]):l=[0,0],g({type:"dragstart"})}}var e=w(n,"drag","dragstart","dragend"),r=null,u=t(y,Bo.mouse,J,"mousemove","mouseup"),i=t(B,Bo.touch,W,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},Bo.rebind(n,e,"on")},Bo.touches=function(n,t){return arguments.length<2&&(t=b().touches),t?Jo(t).map(function(t){var e=$(n,t);return e.identifier=t.identifier,e}):[]};var Ea=Math.PI,Aa=2*Ea,Ca=Ea/2,Na=1e-6,za=Na*Na,La=Ea/180,Ta=180/Ea,qa=Math.SQRT2,Ra=2,Da=4;Bo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=et(v),o=i/(Ra*h)*(e*rt(qa*t+v)-tt(v));return[r+o*l,u+o*s,i*e/et(qa*t+v)]}return[r+n*l,u+n*s,i*Math.exp(qa*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Da*f)/(2*i*Ra*h),p=(c*c-i*i-Da*f)/(2*c*Ra*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/qa;return e.duration=1e3*y,e},Bo.behavior.zoom=function(){function n(n){n.on(A,l).on(ja+".zoom",f).on("dblclick.zoom",h).on(z,s)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){x&&x.domain(y.range().map(function(n){return(n-S.x)/S.k}).map(y.invert)),b&&b.domain(M.range().map(function(n){return(n-S.y)/S.k}).map(M.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function l(){function n(){s=1,u(Bo.mouse(r),h),a(l)}function e(){f.on(C,null).on(N,null),g(s&&Bo.event.target===i),c(l)}var r=this,i=Bo.event.target,l=L.of(r,arguments),s=0,f=Bo.select(Qo).on(C,n).on(N,e),h=t(Bo.mouse(r)),g=X();Y.call(r),o(l)}function s(){function n(){var n=Bo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){var t=Bo.event.target;Bo.select(t).on(x,i).on(M,f),b.push(t);for(var e=Bo.event.changedTouches,o=0,c=e.length;c>o;++o)v[e[o].identifier]=null;var l=n(),s=Date.now();if(1===l.length){if(500>s-m){var h=l[0],g=v[h.identifier];r(2*S.k),u(h,g),_(),a(p)}m=s}else if(l.length>1){var h=l[0],y=l[1],w=h[0]-y[0],k=h[1]-y[1];d=w*w+k*k}}function i(){for(var n,t,e,i,o=Bo.touches(g),c=0,l=o.length;l>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=d&&Math.sqrt(s/d);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}m=null,u(n,t),a(p)}function f(){if(Bo.event.touches.length){for(var t=Bo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}Bo.selectAll(b).on(y,null),w.on(A,l).on(z,s),k(),c(p)}var h,g=this,p=L.of(g,arguments),v={},d=0,y=".zoom-"+Bo.event.changedTouches[0].identifier,x="touchmove"+y,M="touchend"+y,b=[],w=Bo.select(g),k=X();Y.call(g),e(),o(p),w.on(A,null).on(z,e)}function f(){var n=L.of(this,arguments);d?clearTimeout(d):(g=t(p=v||Bo.mouse(this)),Y.call(this),o(n)),d=setTimeout(function(){d=null,c(n)},50),_(),r(Math.pow(2,.002*Pa())*S.k),u(p,g),a(n)}function h(){var n=L.of(this,arguments),e=Bo.mouse(this),i=t(e),l=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Bo.event.shiftKey?Math.ceil(l)-1:Math.floor(l)+1)),u(e,i),a(n),c(n)}var g,p,v,d,m,y,x,M,b,S={x:0,y:0,k:1},k=[960,500],E=Ua,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",z="touchstart.zoom",L=w(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=L.of(this,arguments),t=S;Cl?Bo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Bo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Ua:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(x=t,y=t.copy(),S={x:0,y:0,k:1},n):x},n.y=function(t){return arguments.length?(b=t,M=t.copy(),S={x:0,y:0,k:1},n):b},Bo.rebind(n,L,"on")};var Pa,Ua=[0,1/0],ja="onwheel"in Go?(Pa=function(){return-Bo.event.deltaY*(Bo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Go?(Pa=function(){return Bo.event.wheelDelta},"mousewheel"):(Pa=function(){return-Bo.event.detail},"MozMousePixelScroll");Bo.color=it,it.prototype.toString=function(){return this.rgb()+""},Bo.hsl=ot;var Fa=ot.prototype=new it;Fa.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ot(this.h,this.s,this.l/n)},Fa.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ot(this.h,this.s,n*this.l)},Fa.rgb=function(){return at(this.h,this.s,this.l)},Bo.hcl=ct;var Ha=ct.prototype=new it;Ha.brighter=function(n){return new ct(this.h,this.c,Math.min(100,this.l+Oa*(arguments.length?n:1)))},Ha.darker=function(n){return new ct(this.h,this.c,Math.max(0,this.l-Oa*(arguments.length?n:1)))},Ha.rgb=function(){return lt(this.h,this.c,this.l).rgb()},Bo.lab=st;var Oa=18,Ya=.95047,Ia=1,Za=1.08883,Va=st.prototype=new it;Va.brighter=function(n){return new st(Math.min(100,this.l+Oa*(arguments.length?n:1)),this.a,this.b)},Va.darker=function(n){return new st(Math.max(0,this.l-Oa*(arguments.length?n:1)),this.a,this.b)},Va.rgb=function(){return ft(this.l,this.a,this.b)},Bo.rgb=dt;var Xa=dt.prototype=new it;Xa.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new dt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new dt(u,u,u)},Xa.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new dt(n*this.r,n*this.g,n*this.b)},Xa.hsl=function(){return _t(this.r,this.g,this.b)},Xa.toString=function(){return"#"+xt(this.r)+xt(this.g)+xt(this.b)};var $a=Bo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});$a.forEach(function(n,t){$a.set(n,mt(t))}),Bo.functor=kt,Bo.xhr=At(Et),Bo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Ct(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++<l;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}s=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++s):10===r&&(u=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;l>s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new v,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Bo.csv=Bo.dsv(",","text/csv"),Bo.tsv=Bo.dsv("	","text/tab-separated-values");var Ba,Wa,Ja,Ga,Ka,Qa=Qo[m(Qo,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Bo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Wa?Wa.n=i:Ba=i,Wa=i,Ja||(Ga=clearTimeout(Ga),Ja=1,Qa(Lt))},Bo.timer.flush=function(){Tt(),qt()},Bo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var nc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);Bo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Bo.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),nc[8+e/3]};var tc=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,ec=Bo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Bo.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),rc=Bo.time={},uc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){ic.setUTCDate.apply(this._,arguments)},setDay:function(){ic.setUTCDay.apply(this._,arguments)},setFullYear:function(){ic.setUTCFullYear.apply(this._,arguments)},setHours:function(){ic.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){ic.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){ic.setUTCMinutes.apply(this._,arguments)},setMonth:function(){ic.setUTCMonth.apply(this._,arguments)},setSeconds:function(){ic.setUTCSeconds.apply(this._,arguments)},setTime:function(){ic.setTime.apply(this._,arguments)}};var ic=Date.prototype;rc.year=Ft(function(n){return n=rc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),rc.years=rc.year.range,rc.years.utc=rc.year.utc.range,rc.day=Ft(function(n){var t=new uc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),rc.days=rc.day.range,rc.days.utc=rc.day.utc.range,rc.dayOfYear=function(n){var t=rc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=rc[n]=Ft(function(n){return(n=rc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=rc.year(n).getDay();return Math.floor((rc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});rc[n+"s"]=e.range,rc[n+"s"].utc=e.utc.range,rc[n+"OfYear"]=function(n){var e=rc.year(n).getDay();return Math.floor((rc.dayOfYear(n)+(e+t)%7)/7)}}),rc.week=rc.sunday,rc.weeks=rc.sunday.range,rc.weeks.utc=rc.sunday.utc.range,rc.weekOfYear=rc.sundayOfYear;var oc={"-":"",_:" ",0:"0"},ac=/^\s*\d+/,cc=/^%/;Bo.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var lc=Bo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Bo.format=lc.numberFormat,Bo.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,sc),le(sc.s,this.s,this),this.s?this.t+=sc.t:this.s=sc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var sc=new ce;Bo.geo.stream=function(n,t){n&&fc.hasOwnProperty(n.type)?fc[n.type](n,t):se(n,t)};var fc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)se(e[r].geometry,t)}},hc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){fe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)fe(e[r],t,0)},Polygon:function(n,t){he(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)he(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)se(e[r],t)}};Bo.geo.area=function(n){return gc=0,Bo.geo.stream(n,vc),gc};var gc,pc=new ce,vc={sphere:function(){gc+=4*Ea},point:y,lineStart:y,lineEnd:y,polygonStart:function(){pc.reset(),vc.lineStart=ge},polygonEnd:function(){var n=2*pc;gc+=0>n?4*Ea+n:n,vc.lineStart=vc.lineEnd=vc.point=y}};Bo.geo.bounds=function(){function n(n,t){x.push(M=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*La,e*La]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);xe(o),o=Me(o);var c=t-p,l=c>0?1:-1,v=o[0]*Ta*l,d=ca(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Ta;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Ta;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=s,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ca(r)>180?r+(r>0?360:-360):r}else v=n,d=e;vc.point(n,e),t(n,e)}function i(){vc.lineStart()}function o(){u(v,d),vc.lineEnd(),ca(y)>Na&&(s=-(h=180)),M[0]=s,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var s,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,vc.polygonStart()},polygonEnd:function(){vc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>pc?(s=-(h=180),f=-(g=90)):y>Na?g=90:-Na>y&&(f=-90),M[0]=s,M[1]=h}};return function(n){g=h=-(s=f=1/0),x=[],Bo.geo.stream(n,_);
+var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return x=M=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),Bo.geo.centroid=function(n){dc=mc=yc=xc=Mc=_c=bc=wc=Sc=kc=Ec=0,Bo.geo.stream(n,Ac);var t=Sc,e=kc,r=Ec,u=t*t+e*e+r*r;return za>u&&(t=_c,e=bc,r=wc,Na>mc&&(t=yc,e=xc,r=Mc),u=t*t+e*e+r*r,za>u)?[0/0,0/0]:[Math.atan2(e,t)*Ta,nt(r/Math.sqrt(u))*Ta]};var dc,mc,yc,xc,Mc,_c,bc,wc,Sc,kc,Ec,Ac={sphere:y,point:be,lineStart:Se,lineEnd:ke,polygonStart:function(){Ac.lineStart=Ee},polygonEnd:function(){Ac.lineStart=Se}},Cc=Le(Ae,De,Ue,[-Ea,-Ea/2]),Nc=1e9;Bo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Oe(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Bo.geo.conicEqualArea=function(){return Ie(Ze)}).raw=Ze,Bo.geo.albers=function(){return Bo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Bo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Bo.geo.albers(),o=Bo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Bo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Na,f+.12*l+Na],[s-.214*l-Na,f+.234*l-Na]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Na,f+.166*l+Na],[s-.115*l-Na,f+.234*l-Na]]).stream(c).point,n},n.scale(1070)};var zc,Lc,Tc,qc,Rc,Dc,Pc={point:y,lineStart:y,lineEnd:y,polygonStart:function(){Lc=0,Pc.lineStart=Ve},polygonEnd:function(){Pc.lineStart=Pc.lineEnd=Pc.point=y,zc+=ca(Lc/2)}},Uc={point:Xe,lineStart:y,lineEnd:y,polygonStart:y,polygonEnd:y},jc={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){jc.lineStart=Ke},polygonEnd:function(){jc.point=We,jc.lineStart=Je,jc.lineEnd=Ge}};Bo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Bo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return zc=0,Bo.geo.stream(n,u(Pc)),zc},n.centroid=function(n){return yc=xc=Mc=_c=bc=wc=Sc=kc=Ec=0,Bo.geo.stream(n,u(jc)),Ec?[Sc/Ec,kc/Ec]:wc?[_c/wc,bc/wc]:Mc?[yc/Mc,xc/Mc]:[0/0,0/0]},n.bounds=function(n){return Rc=Dc=-(Tc=qc=1/0),Bo.geo.stream(n,u(Uc)),[[Tc,qc],[Rc,Dc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):Et,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Bo.geo.albersUsa()).context(null)},Bo.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Bo.geo.projection=ur,Bo.geo.projectionMutator=ir,(Bo.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,Bo.geo.rotation=function(n){function t(t){return t=n(t[0]*La,t[1]*La),t[0]*=Ta,t[1]*=Ta,t}return n=lr(n[0]%360*La,n[1]*La,n.length>2?n[2]*La:0),t.invert=function(t){return t=n.invert(t[0]*La,t[1]*La),t[0]*=Ta,t[1]*=Ta,t},t},cr.invert=ar,Bo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*La,-n[1]*La,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ta,n[1]*=Ta}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*La,u*La),n):t},n.precision=function(r){return arguments.length?(e=gr(t*La,(u=+r)*La),n):u},n.angle(90)},Bo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*La,u=n[1]*La,i=t[1]*La,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},Bo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Bo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Bo.range(Math.ceil(l/m)*m,c,m).map(g)).concat(Bo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ca(n%d)>Na}).map(s)).concat(Bo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ca(n%m)>Na}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Na],[180,90-Na]]).minorExtent([[-180,-80-Na],[180,80+Na]])},Bo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return Bo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Bo.geo.interpolate=function(n,t){return xr(n[0]*La,n[1]*La,t[0]*La,t[1]*La)},Bo.geo.length=function(n){return Fc=0,Bo.geo.stream(n,Hc),Fc};var Fc,Hc={sphere:y,point:y,lineStart:Mr,lineEnd:y,polygonStart:y,polygonEnd:y},Oc=_r(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Bo.geo.azimuthalEqualArea=function(){return ur(Oc)}).raw=Oc;var Yc=_r(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},Et);(Bo.geo.azimuthalEquidistant=function(){return ur(Yc)}).raw=Yc,(Bo.geo.conicConformal=function(){return Ie(br)}).raw=br,(Bo.geo.conicEquidistant=function(){return Ie(wr)}).raw=wr;var Ic=_r(function(n){return 1/n},Math.atan);(Bo.geo.gnomonic=function(){return ur(Ic)}).raw=Ic,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ca]},(Bo.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Zc=_r(function(){return 1},Math.asin);(Bo.geo.orthographic=function(){return ur(Zc)}).raw=Zc;var Vc=_r(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Bo.geo.stereographic=function(){return ur(Vc)}).raw=Vc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ca]},(Bo.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,Bo.geom={},Bo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=kt(e),i=kt(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Nr(a),s=Nr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t<s.length-h;++t)g.push(n[a[s[t]][2]]);return g}var e=Ar,r=Cr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Bo.geom.polygon=function(n){return ga(n,Xc),n};var Xc=Bo.geom.polygon.prototype=[];Xc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Xc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Xc.clip=function(n){for(var t,e,r,u,i,o,a=qr(n),c=-1,l=this.length-qr(this),s=this[l-1];++c<l;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Lr(o,s,u)?(Lr(i,s,u)||n.push(Tr(i,o,s,u)),n.push(o)):Lr(i,s,u)&&n.push(Tr(i,o,s,u)),i=o;a&&n.push(n[0]),s=u}return n};var $c,Bc,Wc,Jc,Gc,Kc=[],Qc=[];Or.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Ir),t.length},Qr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},nu.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=uu(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(eu(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ru(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(ru(this,e),n=e,e=n.U),e.C=!1,r.C=!0,eu(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?uu(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,eu(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ru(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,eu(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,ru(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,eu(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,ru(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Bo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return iu(e(n),a).cells.forEach(function(e,a){var c=e.edges,l=e.site,s=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):l.x>=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Na)*Na,y:Math.round(o(n,t)/Na)*Na,i:t}})}var r=Ar,u=Cr,i=r,o=u,a=nl;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Ir),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c<l;)u=s,i=f,s=a[c].edge,f=s.l===o?s.r:s.l,r<i.i&&r<f.i&&au(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=kt(r=n),t):r},t.y=function(n){return arguments.length?(o=kt(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?nl:n,t):a===nl?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===nl?null:a&&a[1]},t)};var nl=[[-1e6,-1e6],[1e6,1e6]];Bo.geom.delaunay=function(n){return Bo.geom.voronoi().triangles(n)},Bo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,s=n.y;if(null!=c)if(ca(c-e)+ca(s-r)<.01)l(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,l(n,f,c,s,u,i,o,a),l(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else l(n,t,e,r,u,i,o,a)}function l(n,t,e,r,u,o,a,c){var l=.5*(u+a),s=.5*(o+c),f=e>=l,h=r>=s,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,x=kt(a),M=kt(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.x<v&&(v=s.x),s.y<d&&(d=s.y),s.x>m&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var _=+x(s=n[g],g),b=+M(s,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=s=null,k}var o,a=Ar,c=Cr;return(o=arguments.length)?(a=cu,c=lu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Bo.interpolateRgb=hu,Bo.interpolateObject=gu,Bo.interpolateNumber=pu,Bo.interpolateString=vu;var tl=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,el=new RegExp(tl.source,"g");Bo.interpolate=du,Bo.interpolators=[function(n,t){var e=typeof t;return("string"===e?$a.has(t)||/^(#|rgb\(|hsl\()/.test(t)?hu:vu:t instanceof it?hu:Array.isArray(t)?mu:"object"===e&&isNaN(t)?gu:pu)(n,t)}],Bo.interpolateArray=mu;var rl=function(){return Et},ul=Bo.map({linear:rl,poly:Su,quad:function(){return _u},cubic:function(){return bu},sin:function(){return ku},exp:function(){return Eu},circle:function(){return Au},elastic:Cu,back:Nu,bounce:function(){return zu}}),il=Bo.map({"in":Et,out:xu,"in-out":Mu,"out-in":function(n){return Mu(xu(n))}});Bo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=ul.get(e)||rl,r=il.get(r)||Et,yu(r(e.apply(null,Wo.call(arguments,1))))},Bo.interpolateHcl=Lu,Bo.interpolateHsl=Tu,Bo.interpolateLab=qu,Bo.interpolateRound=Ru,Bo.transform=function(n){var t=Go.createElementNS(Bo.ns.prefix.svg,"g");return(Bo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Du(e?e.matrix:ol)})(n)},Du.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var ol={a:1,b:0,c:0,d:1,e:0,f:0};Bo.interpolateTransform=Fu,Bo.layout={},Bo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Yu(n[e]));return t}},Bo.layout.chord=function(){function n(){var n,l,f,h,g,p={},v=[],d=Bo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(l=0,g=-1;++g<i;)l+=u[h][g];v.push(l),m.push(Bo.range(i)),n+=l}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(Aa-s*i)/n,l=0,h=-1;++h<i;){for(f=l,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=l,b=l+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:l,value:(l-f)/n},l+=s}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,l={},s=0;return l.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,l):u},l.padding=function(n){return arguments.length?(s=n,e=r=null,l):s},l.sortGroups=function(n){return arguments.length?(o=n,e=r=null,l):o},l.sortSubgroups=function(n){return arguments.length?(a=n,e=null,l):a},l.sortChords=function(n){return arguments.length?(c=n,e&&t(),l):c},l.chords=function(){return e||n(),e},l.groups=function(){return r||n(),r},l},Bo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=Bo.event.x,n.py=Bo.event.y,a.resume()}var e,r,u,i,o,a={},c=Bo.dispatch("start","tick","end"),l=[1,1],s=.9,f=al,h=cl,g=-30,p=ll,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=l[0]/2,M=l[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Wu(t=Bo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*s,a.y-=(a.py-(a.py=a.y))*s);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(l=n,a):l},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(s=+n,a):s},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Bo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;l>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++a<l;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,s=y.length,p=l[0],v=l[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Bo.behavior.drag().origin(Et).on("dragstart.force",Vu).on("drag.force",t).on("dragend.force",Xu)),arguments.length?(this.on("mouseover.force",$u).on("mouseout.force",Bu).call(e),void 0):e},Bo.rebind(a,c,"on")};var al=20,cl=1,ll=1/0;Bo.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Ku(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ti,e=Qu,r=ni;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Gu(t,function(n){n.children&&(n.value=0)}),Ku(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},Bo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++l<o;)n(a=i[l],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Bo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Ju(e,r)},Bo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Bo.sum(o),l=Bo.range(i.length);null!=e&&l.sort(e===sl?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var s=[];return l.forEach(function(n){var t;s[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),s}var t=Number,e=sl,r=0,u=Aa;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var sl={};Bo.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=Bo.permute(l,f),s=Bo.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=Et,e=oi,r=ai,u=ii,i=ri,o=ui;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:fl.get(t)||oi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:hl.get(t)||ai,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var fl=Bo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ci),i=n.map(li),o=Bo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return Bo.range(n.length).reverse()},"default":oi}),hl=Bo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ai});Bo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=l[i],a>=s[0]&&a<=s[1]&&(o=c[Bo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=gi,u=fi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=kt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return hi(n,t)}:kt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Bo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Ku(a,function(n){n.r=+s(n.value)}),Ku(a,yi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Ku(a,function(n){n.r+=f}),Ku(a,yi),Ku(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=Bo.layout.hierarchy().sort(pi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Ju(n,e)},Bo.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Ku(h,e),h.parent.m=-h.z,Gu(h,r),l)Gu(f,i);else{var g=f,p=f,v=f;Gu(f,function(n){n.x<g.x&&(g=n),n.x>p.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Gu(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ai(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=ki(o),u=Si(u),o&&u;)c=Si(c),i=ki(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ei(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!ki(i)&&(i.t=o,i.m+=f-s),u&&!Si(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=Bo.layout.hierarchy().sort(null).value(null),a=wi,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Ju(n,o)},Bo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Ku(c,function(n){var t=n.children;t&&t.length?(n.x=zi(t),n.y=Ni(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Ku(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Bo.layout.hierarchy().sort(null).value(null),e=wi,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Ju(n,t)},Bo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++i<o;)u=n[i],u.x=a,u.y=l,u.dy=s,a+=u.dx=Math.min(e.x+e.dx-a,s?c(u.area/s):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=s,e.dy-=s}else{for((r||s>e.dx)&&(s=e.dx);++i<o;)u=n[i],u.x=a,u.y=l,u.dx=s,l+=u.dy=Math.min(e.y+e.dy-l,s?c(u.area/s):0);u.z=!1,u.dy+=e.y+e.dy-l,e.x+=s,e.dx-=s}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=l[0],i.dy=l[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Bo.layout.hierarchy(),c=Math.round,l=[1,1],s=null,f=qi,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(l=n,i):l},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?qi(t):Ri(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Ri(t,n)}if(!arguments.length)return s;var r;return f=null==(s=n)?qi:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Ju(i,a)},Bo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Bo.random.normal.apply(Bo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Bo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Bo.scale={};var gl={floor:Et,ceil:Et};Bo.scale.linear=function(){return Oi([0,1],[0,1],du,!1)};var pl={s:1,g:1,p:1,r:1,e:1};Bo.scale.log=function(){return Wi(Bo.scale.linear().domain([0,1]),10,!0,[1,10])};var vl=Bo.format(".0e"),dl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Bo.scale.pow=function(){return Ji(Bo.scale.linear(),1,[0,1])},Bo.scale.sqrt=function(){return Bo.scale.pow().exponent(.5)},Bo.scale.ordinal=function(){return Ki([],{t:"range",a:[[]]})},Bo.scale.category10=function(){return Bo.scale.ordinal().range(ml)},Bo.scale.category20=function(){return Bo.scale.ordinal().range(yl)},Bo.scale.category20b=function(){return Bo.scale.ordinal().range(xl)},Bo.scale.category20c=function(){return Bo.scale.ordinal().range(Ml)};var ml=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(yt),yl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(yt),xl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(yt),Ml=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(yt);Bo.scale.quantile=function(){return Qi([],[])
+},Bo.scale.quantize=function(){return no(0,1,[0,1])},Bo.scale.threshold=function(){return to([.5],[0,1])},Bo.scale.identity=function(){return eo([0,1])},Bo.svg={},Bo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+_l,a=u.apply(this,arguments)+_l,c=(o>a&&(c=o,o=a,a=c),a-o),l=Ea>c?"0":"1",s=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=bl?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*s+","+i*f+"A"+i+","+i+" 0 "+l+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+l+",0 "+n*s+","+n*f+"Z":"M"+i*s+","+i*f+"A"+i+","+i+" 0 "+l+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=ro,e=uo,r=io,u=oo;return n.innerRadius=function(e){return arguments.length?(t=kt(e),n):t},n.outerRadius=function(t){return arguments.length?(e=kt(t),n):e},n.startAngle=function(t){return arguments.length?(r=kt(t),n):r},n.endAngle=function(t){return arguments.length?(u=kt(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+_l;return[Math.cos(i)*n,Math.sin(i)*n]},n};var _l=-Ca,bl=Aa-Na;Bo.svg.line=function(){return ao(Et)};var wl=Bo.map({linear:co,"linear-closed":lo,step:so,"step-before":fo,"step-after":ho,basis:xo,"basis-open":Mo,"basis-closed":_o,bundle:bo,cardinal:vo,"cardinal-open":go,"cardinal-closed":po,monotone:Co});wl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Sl=[0,2/3,1/3,0],kl=[0,1/3,2/3,0],El=[0,1/6,2/3,1/6];Bo.svg.line.radial=function(){var n=ao(No);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},fo.reverse=ho,ho.reverse=fo,Bo.svg.area=function(){return zo(Et)},Bo.svg.area.radial=function(){var n=zo(No);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Bo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+_l,s=l.call(n,u,r)+_l;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Ea)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Lo,c=io,l=oo;return n.radius=function(t){return arguments.length?(a=kt(t),n):a},n.source=function(t){return arguments.length?(i=kt(t),n):i},n.target=function(t){return arguments.length?(o=kt(t),n):o},n.startAngle=function(t){return arguments.length?(c=kt(t),n):c},n.endAngle=function(t){return arguments.length?(l=kt(t),n):l},n},Bo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=To;return n.source=function(e){return arguments.length?(t=kt(e),n):t},n.target=function(t){return arguments.length?(e=kt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Bo.svg.diagonal.radial=function(){var n=Bo.svg.diagonal(),t=To,e=n.projection;return n.projection=function(n){return arguments.length?e(qo(t=n)):t},n},Bo.svg.symbol=function(){function n(n,r){return(Al.get(t.call(this,n,r))||Po)(e.call(this,n,r))}var t=Do,e=Ro;return n.type=function(e){return arguments.length?(t=kt(e),n):t},n.size=function(t){return arguments.length?(e=kt(t),n):e},n};var Al=Bo.map({circle:Po,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ll)),e=t*Ll;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/zl),e=t*zl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/zl),e=t*zl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Bo.svg.symbolTypes=Al.keys();var Cl,Nl,zl=Math.sqrt(3),Ll=Math.tan(30*La),Tl=[],ql=0;Tl.call=ya.call,Tl.empty=ya.empty,Tl.node=ya.node,Tl.size=ya.size,Bo.transition=function(n){return arguments.length?Cl?n.transition():n:_a.transition()},Bo.transition.prototype=Tl,Tl.select=function(n){var t,e,r,u=this.id,i=[];n=k(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],l=-1,s=c.length;++l<s;)(r=c[l])&&(e=n.call(r,r.__data__,l,o))?("__data__"in r&&(e.__data__=r.__data__),Ho(e,l,u,r.__transition__[u]),t.push(e)):t.push(null)}return Uo(i,u)},Tl.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=E(n);for(var c=-1,l=this.length;++c<l;)for(var s=this[c],f=-1,h=s.length;++f<h;)if(r=s[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&Ho(u,g,o,i),t.push(u)}return Uo(a,o)},Tl.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=U(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Uo(u,this.id)},Tl.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):F(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Tl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Fu:du,a=Bo.ns.qualify(n);return jo(this,"attr."+n,t,a.local?i:u)},Tl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Bo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Tl.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Qo.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=du(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return jo(this,"style."+n,t,u)},Tl.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Qo.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Tl.text=function(n){return jo(this,"text",n,Fo)},Tl.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Tl.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Bo.ease.apply(Bo,arguments)),F(this,function(e){e.__transition__[t].ease=n}))},Tl.delay=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].delay:F(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Tl.duration=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].duration:F(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Tl.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Nl,u=Cl;Cl=e,F(this,function(t,r,u){Nl=t.__transition__[e],n.call(t,t.__data__,r,u)}),Nl=r,Cl=u}else F(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Bo.dispatch("start","end"))).on(n,t)});return this},Tl.transition=function(){for(var n,t,e,r,u=this.id,i=++ql,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],l=0,s=t.length;s>l;l++)(e=t[l])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,Ho(e,l,i,r)),n.push(e)}return Uo(o,i)},Bo.svg.axis=function(){function n(n){n.each(function(){var n,l=Bo.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):Et:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Na),d=Bo.transition(p.exit()).style("opacity",Na).remove(),m=Bo.transition(p.order()).style("opacity",1),y=Math.max(u,0)+o,x=Pi(f),M=l.selectAll(".domain").data([0]),_=(M.enter().append("path").attr("class","domain"),Bo.transition(M));v.append("line"),v.append("text");var b,w,S,k,E=v.select("line"),A=m.select("line"),C=p.select("text").text(g),N=v.select("text"),z=m.select("text"),L="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Oo,b="x",S="y",w="x2",k="y2",C.attr("dy",0>L?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+L*i+"V0H"+x[1]+"V"+L*i)):(n=Yo,b="y",S="x",w="y2",k="x2",C.attr("dy",".32em").style("text-anchor",0>L?"end":"start"),_.attr("d","M"+L*i+","+x[0]+"H0V"+x[1]+"H"+L*i)),E.attr(k,L*u),N.attr(S,L*y),A.attr(w,0).attr(k,L*u),z.attr(b,0).attr(S,L*y),f.rangeBand){var T=f,q=T.rangeBand()/2;s=f=function(n){return T(n)+q}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=Bo.scale.linear(),r=Rl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Dl?t+"":Rl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Rl="bottom",Dl={top:1,right:1,bottom:1,left:1};Bo.svg.brush=function(){function n(i){i.each(function(){var i=Bo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,Et);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Pl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var s,f=Bo.transition(i),h=Bo.transition(o);c&&(s=Pi(c),h.attr("x",s[0]).attr("width",s[1]-s[0]),e(f)),l&&(s=Pi(l),h.attr("y",s[0]).attr("height",s[1]-s[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Bo.event.keyCode&&(C||(y=null,z[0]-=s[1],z[1]-=f[1],C=2),_())}function p(){32==Bo.event.keyCode&&2==C&&(z[0]+=s[1],z[1]+=f[1],C=0,_())}function v(){var n=Bo.mouse(M),u=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(Bo.event.altKey?(y||(y=[(s[0]+s[1])/2,(f[0]+f[1])/2]),z[0]=s[+(n[0]<y[0])],z[1]=f[+(n[1]<y[1])]):y=null),E&&d(n,c,0)&&(e(S),u=!0),A&&d(n,l,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function d(n,t,e){var r,u,a=Pi(t),c=a[0],l=a[1],p=z[e],v=e?f:s,d=v[1]-v[0];return C&&(c-=p,l-=d+p),r=(e?g:h)?Math.max(c,Math.min(l,n[e])):n[e],C?u=(r+=p)+d:(y&&(p=Math.max(c,Math.min(l,2*y[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function m(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Bo.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var y,x,M=this,b=Bo.select(Bo.event.target),w=a.of(M,arguments),S=Bo.select(M),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&l,C=b.classed("extent"),N=X(),z=Bo.mouse(M),L=Bo.select(Qo).on("keydown.brush",u).on("keyup.brush",p);if(Bo.event.changedTouches?L.on("touchmove.brush",v).on("touchend.brush",m):L.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),C)z[0]=s[0]-z[0],z[1]=f[0]-z[1];else if(k){var T=+/w$/.test(k),q=+/^n/.test(k);x=[s[1-T]-z[0],f[1-q]-z[1]],z[0]=s[T],z[1]=f[q]}else Bo.event.altKey&&(y=z.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Bo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=w(n,"brushstart","brush","brushend"),c=null,l=null,s=[0,0],f=[0,0],h=!0,g=!0,p=Ul[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:s,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Cl?Bo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,s=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=mu(s,t.x),r=mu(f,t.y);return i=o=null,function(u){s=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Ul[!c<<1|!l],n):c},n.y=function(t){return arguments.length?(l=t,p=Ul[!c<<1|!l],n):l},n.clamp=function(t){return arguments.length?(c&&l?(h=!!t[0],g=!!t[1]):c?h=!!t:l&&(g=!!t),n):c&&l?[h,g]:c?h:l?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],l&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=s[0]||r!=s[1])&&(s=[e,r])),l&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],l.invert&&(u=l(u),a=l(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),l&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],l.invert&&(u=l.invert(u),a=l.invert(a)),u>a&&(h=u,u=a,a=h))),c&&l?[[e,u],[r,a]]:c?[e,r]:l&&[u,a])},n.clear=function(){return n.empty()||(s=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!l&&f[0]==f[1]},Bo.rebind(n,a,"on")};var Pl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ul=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],jl=rc.format=lc.timeFormat,Fl=jl.utc,Hl=Fl("%Y-%m-%dT%H:%M:%S.%LZ");jl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Io:Hl,Io.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Io.toString=Hl.toString,rc.second=Ft(function(n){return new uc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),rc.seconds=rc.second.range,rc.seconds.utc=rc.second.utc.range,rc.minute=Ft(function(n){return new uc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),rc.minutes=rc.minute.range,rc.minutes.utc=rc.minute.utc.range,rc.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new uc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),rc.hours=rc.hour.range,rc.hours.utc=rc.hour.utc.range,rc.month=Ft(function(n){return n=rc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),rc.months=rc.month.range,rc.months.utc=rc.month.utc.range;var Ol=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Yl=[[rc.second,1],[rc.second,5],[rc.second,15],[rc.second,30],[rc.minute,1],[rc.minute,5],[rc.minute,15],[rc.minute,30],[rc.hour,1],[rc.hour,3],[rc.hour,6],[rc.hour,12],[rc.day,1],[rc.day,2],[rc.week,1],[rc.month,1],[rc.month,3],[rc.year,1]],Il=jl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ae]]),Zl={range:function(n,t,e){return Bo.range(Math.ceil(n/e)*e,+t,e).map(Vo)},floor:Et,ceil:Et};Yl.year=rc.year,rc.scale=function(){return Zo(Bo.scale.linear(),Yl,Il)};var Vl=Yl.map(function(n){return[n[0].utc,n[1]]}),Xl=Fl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ae]]);Vl.year=rc.year.utc,rc.scale.utc=function(){return Zo(Bo.scale.linear(),Vl,Xl)},Bo.text=At(function(n){return n.responseText}),Bo.json=function(n,t){return Ct(n,"application/json",Xo,t)},Bo.html=function(n,t){return Ct(n,"text/html",$o,t)},Bo.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Bo):"object"==typeof module&&module.exports&&(module.exports=Bo),this.d3=Bo}();
\ No newline at end of file
Index: build-system-1.2.3/html/scripts/jquery-1.10.2.js
===================================================================
--- build-system-1.2.3/html/scripts/jquery-1.10.2.js	(nonexistent)
+++ build-system-1.2.3/html/scripts/jquery-1.10.2.js	(revision 231)
@@ -0,0 +1,9789 @@
+/*!
+ * jQuery JavaScript Library v1.10.2
+ * http://jquery.com/
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ *
+ * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2013-07-03T13:48Z
+ */
+(function( window, undefined ) {
+
+// Can't do this because several apps including ASP.NET trace
+// the stack via arguments.caller.callee and Firefox dies if
+// you try to trace through "use strict" call chains. (#13335)
+// Support: Firefox 18+
+//"use strict";
+var
+	// The deferred used on DOM ready
+	readyList,
+
+	// A central reference to the root jQuery(document)
+	rootjQuery,
+
+	// Support: IE<10
+	// For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
+	core_strundefined = typeof undefined,
+
+	// Use the correct document accordingly with window argument (sandbox)
+	location = window.location,
+	document = window.document,
+	docElem = document.documentElement,
+
+	// Map over jQuery in case of overwrite
+	_jQuery = window.jQuery,
+
+	// Map over the $ in case of overwrite
+	_$ = window.$,
+
+	// [[Class]] -> type pairs
+	class2type = {},
+
+	// List of deleted data cache ids, so we can reuse them
+	core_deletedIds = [],
+
+	core_version = "1.10.2",
+
+	// Save a reference to some core methods
+	core_concat = core_deletedIds.concat,
+	core_push = core_deletedIds.push,
+	core_slice = core_deletedIds.slice,
+	core_indexOf = core_deletedIds.indexOf,
+	core_toString = class2type.toString,
+	core_hasOwn = class2type.hasOwnProperty,
+	core_trim = core_version.trim,
+
+	// Define a local copy of jQuery
+	jQuery = function( selector, context ) {
+		// The jQuery object is actually just the init constructor 'enhanced'
+		return new jQuery.fn.init( selector, context, rootjQuery );
+	},
+
+	// Used for matching numbers
+	core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
+
+	// Used for splitting on whitespace
+	core_rnotwhite = /\S+/g,
+
+	// Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)
+	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+	// A simple way to check for HTML strings
+	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+	// Strict HTML recognition (#11290: must start with <)
+	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
+
+	// Match a standalone tag
+	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
+
+	// JSON RegExp
+	rvalidchars = /^[\],:{}\s]*$/,
+	rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+	rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,
+	rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,
+
+	// Matches dashed string for camelizing
+	rmsPrefix = /^-ms-/,
+	rdashAlpha = /-([\da-z])/gi,
+
+	// Used by jQuery.camelCase as callback to replace()
+	fcamelCase = function( all, letter ) {
+		return letter.toUpperCase();
+	},
+
+	// The ready event handler
+	completed = function( event ) {
+
+		// readyState === "complete" is good enough for us to call the dom ready in oldIE
+		if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
+			detach();
+			jQuery.ready();
+		}
+	},
+	// Clean-up method for dom ready events
+	detach = function() {
+		if ( document.addEventListener ) {
+			document.removeEventListener( "DOMContentLoaded", completed, false );
+			window.removeEventListener( "load", completed, false );
+
+		} else {
+			document.detachEvent( "onreadystatechange", completed );
+			window.detachEvent( "onload", completed );
+		}
+	};
+
+jQuery.fn = jQuery.prototype = {
+	// The current version of jQuery being used
+	jquery: core_version,
+
+	constructor: jQuery,
+	init: function( selector, context, rootjQuery ) {
+		var match, elem;
+
+		// HANDLE: $(""), $(null), $(undefined), $(false)
+		if ( !selector ) {
+			return this;
+		}
+
+		// Handle HTML strings
+		if ( typeof selector === "string" ) {
+			if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
+				// Assume that strings that start and end with <> are HTML and skip the regex check
+				match = [ null, selector, null ];
+
+			} else {
+				match = rquickExpr.exec( selector );
+			}
+
+			// Match html or make sure no context is specified for #id
+			if ( match && (match[1] || !context) ) {
+
+				// HANDLE: $(html) -> $(array)
+				if ( match[1] ) {
+					context = context instanceof jQuery ? context[0] : context;
+
+					// scripts is true for back-compat
+					jQuery.merge( this, jQuery.parseHTML(
+						match[1],
+						context && context.nodeType ? context.ownerDocument || context : document,
+						true
+					) );
+
+					// HANDLE: $(html, props)
+					if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
+						for ( match in context ) {
+							// Properties of context are called as methods if possible
+							if ( jQuery.isFunction( this[ match ] ) ) {
+								this[ match ]( context[ match ] );
+
+							// ...and otherwise set as attributes
+							} else {
+								this.attr( match, context[ match ] );
+							}
+						}
+					}
+
+					return this;
+
+				// HANDLE: $(#id)
+				} else {
+					elem = document.getElementById( match[2] );
+
+					// Check parentNode to catch when Blackberry 4.6 returns
+					// nodes that are no longer in the document #6963
+					if ( elem && elem.parentNode ) {
+						// Handle the case where IE and Opera return items
+						// by name instead of ID
+						if ( elem.id !== match[2] ) {
+							return rootjQuery.find( selector );
+						}
+
+						// Otherwise, we inject the element directly into the jQuery object
+						this.length = 1;
+						this[0] = elem;
+					}
+
+					this.context = document;
+					this.selector = selector;
+					return this;
+				}
+
+			// HANDLE: $(expr, $(...))
+			} else if ( !context || context.jquery ) {
+				return ( context || rootjQuery ).find( selector );
+
+			// HANDLE: $(expr, context)
+			// (which is just equivalent to: $(context).find(expr)
+			} else {
+				return this.constructor( context ).find( selector );
+			}
+
+		// HANDLE: $(DOMElement)
+		} else if ( selector.nodeType ) {
+			this.context = this[0] = selector;
+			this.length = 1;
+			return this;
+
+		// HANDLE: $(function)
+		// Shortcut for document ready
+		} else if ( jQuery.isFunction( selector ) ) {
+			return rootjQuery.ready( selector );
+		}
+
+		if ( selector.selector !== undefined ) {
+			this.selector = selector.selector;
+			this.context = selector.context;
+		}
+
+		return jQuery.makeArray( selector, this );
+	},
+
+	// Start with an empty selector
+	selector: "",
+
+	// The default length of a jQuery object is 0
+	length: 0,
+
+	toArray: function() {
+		return core_slice.call( this );
+	},
+
+	// Get the Nth element in the matched element set OR
+	// Get the whole matched element set as a clean array
+	get: function( num ) {
+		return num == null ?
+
+			// Return a 'clean' array
+			this.toArray() :
+
+			// Return just the object
+			( num < 0 ? this[ this.length + num ] : this[ num ] );
+	},
+
+	// Take an array of elements and push it onto the stack
+	// (returning the new matched element set)
+	pushStack: function( elems ) {
+
+		// Build a new jQuery matched element set
+		var ret = jQuery.merge( this.constructor(), elems );
+
+		// Add the old object onto the stack (as a reference)
+		ret.prevObject = this;
+		ret.context = this.context;
+
+		// Return the newly-formed element set
+		return ret;
+	},
+
+	// Execute a callback for every element in the matched set.
+	// (You can seed the arguments with an array of args, but this is
+	// only used internally.)
+	each: function( callback, args ) {
+		return jQuery.each( this, callback, args );
+	},
+
+	ready: function( fn ) {
+		// Add the callback
+		jQuery.ready.promise().done( fn );
+
+		return this;
+	},
+
+	slice: function() {
+		return this.pushStack( core_slice.apply( this, arguments ) );
+	},
+
+	first: function() {
+		return this.eq( 0 );
+	},
+
+	last: function() {
+		return this.eq( -1 );
+	},
+
+	eq: function( i ) {
+		var len = this.length,
+			j = +i + ( i < 0 ? len : 0 );
+		return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
+	},
+
+	map: function( callback ) {
+		return this.pushStack( jQuery.map(this, function( elem, i ) {
+			return callback.call( elem, i, elem );
+		}));
+	},
+
+	end: function() {
+		return this.prevObject || this.constructor(null);
+	},
+
+	// For internal use only.
+	// Behaves like an Array's method, not like a jQuery method.
+	push: core_push,
+	sort: [].sort,
+	splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+	var src, copyIsArray, copy, name, options, clone,
+		target = arguments[0] || {},
+		i = 1,
+		length = arguments.length,
+		deep = false;
+
+	// Handle a deep copy situation
+	if ( typeof target === "boolean" ) {
+		deep = target;
+		target = arguments[1] || {};
+		// skip the boolean and the target
+		i = 2;
+	}
+
+	// Handle case when target is a string or something (possible in deep copy)
+	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+		target = {};
+	}
+
+	// extend jQuery itself if only one argument is passed
+	if ( length === i ) {
+		target = this;
+		--i;
+	}
+
+	for ( ; i < length; i++ ) {
+		// Only deal with non-null/undefined values
+		if ( (options = arguments[ i ]) != null ) {
+			// Extend the base object
+			for ( name in options ) {
+				src = target[ name ];
+				copy = options[ name ];
+
+				// Prevent never-ending loop
+				if ( target === copy ) {
+					continue;
+				}
+
+				// Recurse if we're merging plain objects or arrays
+				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+					if ( copyIsArray ) {
+						copyIsArray = false;
+						clone = src && jQuery.isArray(src) ? src : [];
+
+					} else {
+						clone = src && jQuery.isPlainObject(src) ? src : {};
+					}
+
+					// Never move original objects, clone them
+					target[ name ] = jQuery.extend( deep, clone, copy );
+
+				// Don't bring in undefined values
+				} else if ( copy !== undefined ) {
+					target[ name ] = copy;
+				}
+			}
+		}
+	}
+
+	// Return the modified object
+	return target;
+};
+
+jQuery.extend({
+	// Unique for each copy of jQuery on the page
+	// Non-digits removed to match rinlinejQuery
+	expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
+
+	noConflict: function( deep ) {
+		if ( window.$ === jQuery ) {
+			window.$ = _$;
+		}
+
+		if ( deep && window.jQuery === jQuery ) {
+			window.jQuery = _jQuery;
+		}
+
+		return jQuery;
+	},
+
+	// Is the DOM ready to be used? Set to true once it occurs.
+	isReady: false,
+
+	// A counter to track how many items to wait for before
+	// the ready event fires. See #6781
+	readyWait: 1,
+
+	// Hold (or release) the ready event
+	holdReady: function( hold ) {
+		if ( hold ) {
+			jQuery.readyWait++;
+		} else {
+			jQuery.ready( true );
+		}
+	},
+
+	// Handle when the DOM is ready
+	ready: function( wait ) {
+
+		// Abort if there are pending holds or we're already ready
+		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+			return;
+		}
+
+		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+		if ( !document.body ) {
+			return setTimeout( jQuery.ready );
+		}
+
+		// Remember that the DOM is ready
+		jQuery.isReady = true;
+
+		// If a normal DOM Ready event fired, decrement, and wait if need be
+		if ( wait !== true && --jQuery.readyWait > 0 ) {
+			return;
+		}
+
+		// If there are functions bound, to execute
+		readyList.resolveWith( document, [ jQuery ] );
+
+		// Trigger any bound ready events
+		if ( jQuery.fn.trigger ) {
+			jQuery( document ).trigger("ready").off("ready");
+		}
+	},
+
+	// See test/unit/core.js for details concerning isFunction.
+	// Since version 1.3, DOM methods and functions like alert
+	// aren't supported. They return false on IE (#2968).
+	isFunction: function( obj ) {
+		return jQuery.type(obj) === "function";
+	},
+
+	isArray: Array.isArray || function( obj ) {
+		return jQuery.type(obj) === "array";
+	},
+
+	isWindow: function( obj ) {
+		/* jshint eqeqeq: false */
+		return obj != null && obj == obj.window;
+	},
+
+	isNumeric: function( obj ) {
+		return !isNaN( parseFloat(obj) ) && isFinite( obj );
+	},
+
+	type: function( obj ) {
+		if ( obj == null ) {
+			return String( obj );
+		}
+		return typeof obj === "object" || typeof obj === "function" ?
+			class2type[ core_toString.call(obj) ] || "object" :
+			typeof obj;
+	},
+
+	isPlainObject: function( obj ) {
+		var key;
+
+		// Must be an Object.
+		// Because of IE, we also have to check the presence of the constructor property.
+		// Make sure that DOM nodes and window objects don't pass through, as well
+		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+			return false;
+		}
+
+		try {
+			// Not own constructor property must be Object
+			if ( obj.constructor &&
+				!core_hasOwn.call(obj, "constructor") &&
+				!core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+				return false;
+			}
+		} catch ( e ) {
+			// IE8,9 Will throw exceptions on certain host objects #9897
+			return false;
+		}
+
+		// Support: IE<9
+		// Handle iteration over inherited properties before own properties.
+		if ( jQuery.support.ownLast ) {
+			for ( key in obj ) {
+				return core_hasOwn.call( obj, key );
+			}
+		}
+
+		// Own properties are enumerated firstly, so to speed up,
+		// if last one is own, then all properties are own.
+		for ( key in obj ) {}
+
+		return key === undefined || core_hasOwn.call( obj, key );
+	},
+
+	isEmptyObject: function( obj ) {
+		var name;
+		for ( name in obj ) {
+			return false;
+		}
+		return true;
+	},
+
+	error: function( msg ) {
+		throw new Error( msg );
+	},
+
+	// data: string of html
+	// context (optional): If specified, the fragment will be created in this context, defaults to document
+	// keepScripts (optional): If true, will include scripts passed in the html string
+	parseHTML: function( data, context, keepScripts ) {
+		if ( !data || typeof data !== "string" ) {
+			return null;
+		}
+		if ( typeof context === "boolean" ) {
+			keepScripts = context;
+			context = false;
+		}
+		context = context || document;
+
+		var parsed = rsingleTag.exec( data ),
+			scripts = !keepScripts && [];
+
+		// Single tag
+		if ( parsed ) {
+			return [ context.createElement( parsed[1] ) ];
+		}
+
+		parsed = jQuery.buildFragment( [ data ], context, scripts );
+		if ( scripts ) {
+			jQuery( scripts ).remove();
+		}
+		return jQuery.merge( [], parsed.childNodes );
+	},
+
+	parseJSON: function( data ) {
+		// Attempt to parse using the native JSON parser first
+		if ( window.JSON && window.JSON.parse ) {
+			return window.JSON.parse( data );
+		}
+
+		if ( data === null ) {
+			return data;
+		}
+
+		if ( typeof data === "string" ) {
+
+			// Make sure leading/trailing whitespace is removed (IE can't handle it)
+			data = jQuery.trim( data );
+
+			if ( data ) {
+				// Make sure the incoming data is actual JSON
+				// Logic borrowed from http://json.org/json2.js
+				if ( rvalidchars.test( data.replace( rvalidescape, "@" )
+					.replace( rvalidtokens, "]" )
+					.replace( rvalidbraces, "")) ) {
+
+					return ( new Function( "return " + data ) )();
+				}
+			}
+		}
+
+		jQuery.error( "Invalid JSON: " + data );
+	},
+
+	// Cross-browser xml parsing
+	parseXML: function( data ) {
+		var xml, tmp;
+		if ( !data || typeof data !== "string" ) {
+			return null;
+		}
+		try {
+			if ( window.DOMParser ) { // Standard
+				tmp = new DOMParser();
+				xml = tmp.parseFromString( data , "text/xml" );
+			} else { // IE
+				xml = new ActiveXObject( "Microsoft.XMLDOM" );
+				xml.async = "false";
+				xml.loadXML( data );
+			}
+		} catch( e ) {
+			xml = undefined;
+		}
+		if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
+			jQuery.error( "Invalid XML: " + data );
+		}
+		return xml;
+	},
+
+	noop: function() {},
+
+	// Evaluates a script in a global context
+	// Workarounds based on findings by Jim Driscoll
+	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+	globalEval: function( data ) {
+		if ( data && jQuery.trim( data ) ) {
+			// We use execScript on Internet Explorer
+			// We use an anonymous function so that context is window
+			// rather than jQuery in Firefox
+			( window.execScript || function( data ) {
+				window[ "eval" ].call( window, data );
+			} )( data );
+		}
+	},
+
+	// Convert dashed to camelCase; used by the css and data modules
+	// Microsoft forgot to hump their vendor prefix (#9572)
+	camelCase: function( string ) {
+		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+	},
+
+	nodeName: function( elem, name ) {
+		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+	},
+
+	// args is for internal usage only
+	each: function( obj, callback, args ) {
+		var value,
+			i = 0,
+			length = obj.length,
+			isArray = isArraylike( obj );
+
+		if ( args ) {
+			if ( isArray ) {
+				for ( ; i < length; i++ ) {
+					value = callback.apply( obj[ i ], args );
+
+					if ( value === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( i in obj ) {
+					value = callback.apply( obj[ i ], args );
+
+					if ( value === false ) {
+						break;
+					}
+				}
+			}
+
+		// A special, fast, case for the most common use of each
+		} else {
+			if ( isArray ) {
+				for ( ; i < length; i++ ) {
+					value = callback.call( obj[ i ], i, obj[ i ] );
+
+					if ( value === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( i in obj ) {
+					value = callback.call( obj[ i ], i, obj[ i ] );
+
+					if ( value === false ) {
+						break;
+					}
+				}
+			}
+		}
+
+		return obj;
+	},
+
+	// Use native String.trim function wherever possible
+	trim: core_trim && !core_trim.call("\uFEFF\xA0") ?
+		function( text ) {
+			return text == null ?
+				"" :
+				core_trim.call( text );
+		} :
+
+		// Otherwise use our own trimming functionality
+		function( text ) {
+			return text == null ?
+				"" :
+				( text + "" ).replace( rtrim, "" );
+		},
+
+	// results is for internal usage only
+	makeArray: function( arr, results ) {
+		var ret = results || [];
+
+		if ( arr != null ) {
+			if ( isArraylike( Object(arr) ) ) {
+				jQuery.merge( ret,
+					typeof arr === "string" ?
+					[ arr ] : arr
+				);
+			} else {
+				core_push.call( ret, arr );
+			}
+		}
+
+		return ret;
+	},
+
+	inArray: function( elem, arr, i ) {
+		var len;
+
+		if ( arr ) {
+			if ( core_indexOf ) {
+				return core_indexOf.call( arr, elem, i );
+			}
+
+			len = arr.length;
+			i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
+
+			for ( ; i < len; i++ ) {
+				// Skip accessing in sparse arrays
+				if ( i in arr && arr[ i ] === elem ) {
+					return i;
+				}
+			}
+		}
+
+		return -1;
+	},
+
+	merge: function( first, second ) {
+		var l = second.length,
+			i = first.length,
+			j = 0;
+
+		if ( typeof l === "number" ) {
+			for ( ; j < l; j++ ) {
+				first[ i++ ] = second[ j ];
+			}
+		} else {
+			while ( second[j] !== undefined ) {
+				first[ i++ ] = second[ j++ ];
+			}
+		}
+
+		first.length = i;
+
+		return first;
+	},
+
+	grep: function( elems, callback, inv ) {
+		var retVal,
+			ret = [],
+			i = 0,
+			length = elems.length;
+		inv = !!inv;
+
+		// Go through the array, only saving the items
+		// that pass the validator function
+		for ( ; i < length; i++ ) {
+			retVal = !!callback( elems[ i ], i );
+			if ( inv !== retVal ) {
+				ret.push( elems[ i ] );
+			}
+		}
+
+		return ret;
+	},
+
+	// arg is for internal usage only
+	map: function( elems, callback, arg ) {
+		var value,
+			i = 0,
+			length = elems.length,
+			isArray = isArraylike( elems ),
+			ret = [];
+
+		// Go through the array, translating each of the items to their
+		if ( isArray ) {
+			for ( ; i < length; i++ ) {
+				value = callback( elems[ i ], i, arg );
+
+				if ( value != null ) {
+					ret[ ret.length ] = value;
+				}
+			}
+
+		// Go through every key on the object,
+		} else {
+			for ( i in elems ) {
+				value = callback( elems[ i ], i, arg );
+
+				if ( value != null ) {
+					ret[ ret.length ] = value;
+				}
+			}
+		}
+
+		// Flatten any nested arrays
+		return core_concat.apply( [], ret );
+	},
+
+	// A global GUID counter for objects
+	guid: 1,
+
+	// Bind a function to a context, optionally partially applying any
+	// arguments.
+	proxy: function( fn, context ) {
+		var args, proxy, tmp;
+
+		if ( typeof context === "string" ) {
+			tmp = fn[ context ];
+			context = fn;
+			fn = tmp;
+		}
+
+		// Quick check to determine if target is callable, in the spec
+		// this throws a TypeError, but we will just return undefined.
+		if ( !jQuery.isFunction( fn ) ) {
+			return undefined;
+		}
+
+		// Simulated bind
+		args = core_slice.call( arguments, 2 );
+		proxy = function() {
+			return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
+		};
+
+		// Set the guid of unique handler to the same of original handler, so it can be removed
+		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+		return proxy;
+	},
+
+	// Multifunctional method to get and set values of a collection
+	// The value/s can optionally be executed if it's a function
+	access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
+		var i = 0,
+			length = elems.length,
+			bulk = key == null;
+
+		// Sets many values
+		if ( jQuery.type( key ) === "object" ) {
+			chainable = true;
+			for ( i in key ) {
+				jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
+			}
+
+		// Sets one value
+		} else if ( value !== undefined ) {
+			chainable = true;
+
+			if ( !jQuery.isFunction( value ) ) {
+				raw = true;
+			}
+
+			if ( bulk ) {
+				// Bulk operations run against the entire set
+				if ( raw ) {
+					fn.call( elems, value );
+					fn = null;
+
+				// ...except when executing function values
+				} else {
+					bulk = fn;
+					fn = function( elem, key, value ) {
+						return bulk.call( jQuery( elem ), value );
+					};
+				}
+			}
+
+			if ( fn ) {
+				for ( ; i < length; i++ ) {
+					fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
+				}
+			}
+		}
+
+		return chainable ?
+			elems :
+
+			// Gets
+			bulk ?
+				fn.call( elems ) :
+				length ? fn( elems[0], key ) : emptyGet;
+	},
+
+	now: function() {
+		return ( new Date() ).getTime();
+	},
+
+	// A method for quickly swapping in/out CSS properties to get correct calculations.
+	// Note: this method belongs to the css module but it's needed here for the support module.
+	// If support gets modularized, this method should be moved back to the css module.
+	swap: function( elem, options, callback, args ) {
+		var ret, name,
+			old = {};
+
+		// Remember the old values, and insert the new ones
+		for ( name in options ) {
+			old[ name ] = elem.style[ name ];
+			elem.style[ name ] = options[ name ];
+		}
+
+		ret = callback.apply( elem, args || [] );
+
+		// Revert the old values
+		for ( name in options ) {
+			elem.style[ name ] = old[ name ];
+		}
+
+		return ret;
+	}
+});
+
+jQuery.ready.promise = function( obj ) {
+	if ( !readyList ) {
+
+		readyList = jQuery.Deferred();
+
+		// Catch cases where $(document).ready() is called after the browser event has already occurred.
+		// we once tried to use readyState "interactive" here, but it caused issues like the one
+		// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
+		if ( document.readyState === "complete" ) {
+			// Handle it asynchronously to allow scripts the opportunity to delay ready
+			setTimeout( jQuery.ready );
+
+		// Standards-based browsers support DOMContentLoaded
+		} else if ( document.addEventListener ) {
+			// Use the handy event callback
+			document.addEventListener( "DOMContentLoaded", completed, false );
+
+			// A fallback to window.onload, that will always work
+			window.addEventListener( "load", completed, false );
+
+		// If IE event model is used
+		} else {
+			// Ensure firing before onload, maybe late but safe also for iframes
+			document.attachEvent( "onreadystatechange", completed );
+
+			// A fallback to window.onload, that will always work
+			window.attachEvent( "onload", completed );
+
+			// If IE and not a frame
+			// continually check to see if the document is ready
+			var top = false;
+
+			try {
+				top = window.frameElement == null && document.documentElement;
+			} catch(e) {}
+
+			if ( top && top.doScroll ) {
+				(function doScrollCheck() {
+					if ( !jQuery.isReady ) {
+
+						try {
+							// Use the trick by Diego Perini
+							// http://javascript.nwbox.com/IEContentLoaded/
+							top.doScroll("left");
+						} catch(e) {
+							return setTimeout( doScrollCheck, 50 );
+						}
+
+						// detach all dom ready events
+						detach();
+
+						// and execute any waiting functions
+						jQuery.ready();
+					}
+				})();
+			}
+		}
+	}
+	return readyList.promise( obj );
+};
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
+	class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+function isArraylike( obj ) {
+	var length = obj.length,
+		type = jQuery.type( obj );
+
+	if ( jQuery.isWindow( obj ) ) {
+		return false;
+	}
+
+	if ( obj.nodeType === 1 && length ) {
+		return true;
+	}
+
+	return type === "array" || type !== "function" &&
+		( length === 0 ||
+		typeof length === "number" && length > 0 && ( length - 1 ) in obj );
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+/*!
+ * Sizzle CSS Selector Engine v1.10.2
+ * http://sizzlejs.com/
+ *
+ * Copyright 2013 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2013-07-03
+ */
+(function( window, undefined ) {
+
+var i,
+	support,
+	cachedruns,
+	Expr,
+	getText,
+	isXML,
+	compile,
+	outermostContext,
+	sortInput,
+
+	// Local document vars
+	setDocument,
+	document,
+	docElem,
+	documentIsHTML,
+	rbuggyQSA,
+	rbuggyMatches,
+	matches,
+	contains,
+
+	// Instance-specific data
+	expando = "sizzle" + -(new Date()),
+	preferredDoc = window.document,
+	dirruns = 0,
+	done = 0,
+	classCache = createCache(),
+	tokenCache = createCache(),
+	compilerCache = createCache(),
+	hasDuplicate = false,
+	sortOrder = function( a, b ) {
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+		}
+		return 0;
+	},
+
+	// General-purpose constants
+	strundefined = typeof undefined,
+	MAX_NEGATIVE = 1 << 31,
+
+	// Instance methods
+	hasOwn = ({}).hasOwnProperty,
+	arr = [],
+	pop = arr.pop,
+	push_native = arr.push,
+	push = arr.push,
+	slice = arr.slice,
+	// Use a stripped-down indexOf if we can't use a native one
+	indexOf = arr.indexOf || function( elem ) {
+		var i = 0,
+			len = this.length;
+		for ( ; i < len; i++ ) {
+			if ( this[i] === elem ) {
+				return i;
+			}
+		}
+		return -1;
+	},
+
+	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+	// Regular expressions
+
+	// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+	whitespace = "[\\x20\\t\\r\\n\\f]",
+	// http://www.w3.org/TR/css3-syntax/#characters
+	characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
+
+	// Loosely modeled on CSS identifier characters
+	// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
+	// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+	identifier = characterEncoding.replace( "w", "w#" ),
+
+	// Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
+	attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
+		"*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
+
+	// Prefer arguments quoted,
+	//   then not containing pseudos/brackets,
+	//   then attribute selectors/non-parenthetical expressions,
+	//   then anything else
+	// These preferences are here to reduce the number of selectors
+	//   needing tokenize in the PSEUDO preFilter
+	pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
+
+	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
+
+	rsibling = new RegExp( whitespace + "*[+~]" ),
+	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ),
+
+	rpseudo = new RegExp( pseudos ),
+	ridentifier = new RegExp( "^" + identifier + "$" ),
+
+	matchExpr = {
+		"ID": new RegExp( "^#(" + characterEncoding + ")" ),
+		"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
+		"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
+		"ATTR": new RegExp( "^" + attributes ),
+		"PSEUDO": new RegExp( "^" + pseudos ),
+		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
+		// For use in libraries implementing .is()
+		// We use this for POS matching in `select`
+		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+	},
+
+	rnative = /^[^{]+\{\s*\[native \w/,
+
+	// Easily-parseable/retrievable ID or TAG or CLASS selectors
+	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+	rinputs = /^(?:input|select|textarea|button)$/i,
+	rheader = /^h\d$/i,
+
+	rescape = /'|\\/g,
+
+	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
+	funescape = function( _, escaped, escapedWhitespace ) {
+		var high = "0x" + escaped - 0x10000;
+		// NaN means non-codepoint
+		// Support: Firefox
+		// Workaround erroneous numeric interpretation of +"0x"
+		return high !== high || escapedWhitespace ?
+			escaped :
+			// BMP codepoint
+			high < 0 ?
+				String.fromCharCode( high + 0x10000 ) :
+				// Supplemental Plane codepoint (surrogate pair)
+				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+	};
+
+// Optimize for push.apply( _, NodeList )
+try {
+	push.apply(
+		(arr = slice.call( preferredDoc.childNodes )),
+		preferredDoc.childNodes
+	);
+	// Support: Android<4.0
+	// Detect silently failing push.apply
+	arr[ preferredDoc.childNodes.length ].nodeType;
+} catch ( e ) {
+	push = { apply: arr.length ?
+
+		// Leverage slice if possible
+		function( target, els ) {
+			push_native.apply( target, slice.call(els) );
+		} :
+
+		// Support: IE<9
+		// Otherwise append directly
+		function( target, els ) {
+			var j = target.length,
+				i = 0;
+			// Can't trust NodeList.length
+			while ( (target[j++] = els[i++]) ) {}
+			target.length = j - 1;
+		}
+	};
+}
+
+function Sizzle( selector, context, results, seed ) {
+	var match, elem, m, nodeType,
+		// QSA vars
+		i, groups, old, nid, newContext, newSelector;
+
+	if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+		setDocument( context );
+	}
+
+	context = context || document;
+	results = results || [];
+
+	if ( !selector || typeof selector !== "string" ) {
+		return results;
+	}
+
+	if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
+		return [];
+	}
+
+	if ( documentIsHTML && !seed ) {
+
+		// Shortcuts
+		if ( (match = rquickExpr.exec( selector )) ) {
+			// Speed-up: Sizzle("#ID")
+			if ( (m = match[1]) ) {
+				if ( nodeType === 9 ) {
+					elem = context.getElementById( m );
+					// Check parentNode to catch when Blackberry 4.6 returns
+					// nodes that are no longer in the document #6963
+					if ( elem && elem.parentNode ) {
+						// Handle the case where IE, Opera, and Webkit return items
+						// by name instead of ID
+						if ( elem.id === m ) {
+							results.push( elem );
+							return results;
+						}
+					} else {
+						return results;
+					}
+				} else {
+					// Context is not a document
+					if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
+						contains( context, elem ) && elem.id === m ) {
+						results.push( elem );
+						return results;
+					}
+				}
+
+			// Speed-up: Sizzle("TAG")
+			} else if ( match[2] ) {
+				push.apply( results, context.getElementsByTagName( selector ) );
+				return results;
+
+			// Speed-up: Sizzle(".CLASS")
+			} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
+				push.apply( results, context.getElementsByClassName( m ) );
+				return results;
+			}
+		}
+
+		// QSA path
+		if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+			nid = old = expando;
+			newContext = context;
+			newSelector = nodeType === 9 && selector;
+
+			// qSA works strangely on Element-rooted queries
+			// We can work around this by specifying an extra ID on the root
+			// and working up from there (Thanks to Andrew Dupont for the technique)
+			// IE 8 doesn't work on object elements
+			if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+				groups = tokenize( selector );
+
+				if ( (old = context.getAttribute("id")) ) {
+					nid = old.replace( rescape, "\\$&" );
+				} else {
+					context.setAttribute( "id", nid );
+				}
+				nid = "[id='" + nid + "'] ";
+
+				i = groups.length;
+				while ( i-- ) {
+					groups[i] = nid + toSelector( groups[i] );
+				}
+				newContext = rsibling.test( selector ) && context.parentNode || context;
+				newSelector = groups.join(",");
+			}
+
+			if ( newSelector ) {
+				try {
+					push.apply( results,
+						newContext.querySelectorAll( newSelector )
+					);
+					return results;
+				} catch(qsaError) {
+				} finally {
+					if ( !old ) {
+						context.removeAttribute("id");
+					}
+				}
+			}
+		}
+	}
+
+	// All others
+	return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
+ *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ *	deleting the oldest entry
+ */
+function createCache() {
+	var keys = [];
+
+	function cache( key, value ) {
+		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+		if ( keys.push( key += " " ) > Expr.cacheLength ) {
+			// Only keep the most recent entries
+			delete cache[ keys.shift() ];
+		}
+		return (cache[ key ] = value);
+	}
+	return cache;
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+	fn[ expando ] = true;
+	return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created div and expects a boolean result
+ */
+function assert( fn ) {
+	var div = document.createElement("div");
+
+	try {
+		return !!fn( div );
+	} catch (e) {
+		return false;
+	} finally {
+		// Remove from its parent by default
+		if ( div.parentNode ) {
+			div.parentNode.removeChild( div );
+		}
+		// release memory in IE
+		div = null;
+	}
+}
+
+/**
+ * Adds the same handler for all of the specified attrs
+ * @param {String} attrs Pipe-separated list of attributes
+ * @param {Function} handler The method that will be applied
+ */
+function addHandle( attrs, handler ) {
+	var arr = attrs.split("|"),
+		i = attrs.length;
+
+	while ( i-- ) {
+		Expr.attrHandle[ arr[i] ] = handler;
+	}
+}
+
+/**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+ */
+function siblingCheck( a, b ) {
+	var cur = b && a,
+		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
+			( ~b.sourceIndex || MAX_NEGATIVE ) -
+			( ~a.sourceIndex || MAX_NEGATIVE );
+
+	// Use IE sourceIndex if available on both nodes
+	if ( diff ) {
+		return diff;
+	}
+
+	// Check if b follows a
+	if ( cur ) {
+		while ( (cur = cur.nextSibling) ) {
+			if ( cur === b ) {
+				return -1;
+			}
+		}
+	}
+
+	return a ? 1 : -1;
+}
+
+/**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+function createInputPseudo( type ) {
+	return function( elem ) {
+		var name = elem.nodeName.toLowerCase();
+		return name === "input" && elem.type === type;
+	};
+}
+
+/**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+function createButtonPseudo( type ) {
+	return function( elem ) {
+		var name = elem.nodeName.toLowerCase();
+		return (name === "input" || name === "button") && elem.type === type;
+	};
+}
+
+/**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+function createPositionalPseudo( fn ) {
+	return markFunction(function( argument ) {
+		argument = +argument;
+		return markFunction(function( seed, matches ) {
+			var j,
+				matchIndexes = fn( [], seed.length, argument ),
+				i = matchIndexes.length;
+
+			// Match elements found at the specified indexes
+			while ( i-- ) {
+				if ( seed[ (j = matchIndexes[i]) ] ) {
+					seed[j] = !(matches[j] = seed[j]);
+				}
+			}
+		});
+	});
+}
+
+/**
+ * Detect xml
+ * @param {Element|Object} elem An element or a document
+ */
+isXML = Sizzle.isXML = function( elem ) {
+	// documentElement is verified for cases where it doesn't yet exist
+	// (such as loading iframes in IE - #4833)
+	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+	return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+// Expose support vars for convenience
+support = Sizzle.support = {};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+	var doc = node ? node.ownerDocument || node : preferredDoc,
+		parent = doc.defaultView;
+
+	// If no document and documentElement is available, return
+	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+		return document;
+	}
+
+	// Set our document
+	document = doc;
+	docElem = doc.documentElement;
+
+	// Support tests
+	documentIsHTML = !isXML( doc );
+
+	// Support: IE>8
+	// If iframe document is assigned to "document" variable and if iframe has been reloaded,
+	// IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
+	// IE6-8 do not support the defaultView property so parent will be undefined
+	if ( parent && parent.attachEvent && parent !== parent.top ) {
+		parent.attachEvent( "onbeforeunload", function() {
+			setDocument();
+		});
+	}
+
+	/* Attributes
+	---------------------------------------------------------------------- */
+
+	// Support: IE<8
+	// Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
+	support.attributes = assert(function( div ) {
+		div.className = "i";
+		return !div.getAttribute("className");
+	});
+
+	/* getElement(s)By*
+	---------------------------------------------------------------------- */
+
+	// Check if getElementsByTagName("*") returns only elements
+	support.getElementsByTagName = assert(function( div ) {
+		div.appendChild( doc.createComment("") );
+		return !div.getElementsByTagName("*").length;
+	});
+
+	// Check if getElementsByClassName can be trusted
+	support.getElementsByClassName = assert(function( div ) {
+		div.innerHTML = "<div class='a'></div><div class='a i'></div>";
+
+		// Support: Safari<4
+		// Catch class over-caching
+		div.firstChild.className = "i";
+		// Support: Opera<10
+		// Catch gEBCN failure to find non-leading classes
+		return div.getElementsByClassName("i").length === 2;
+	});
+
+	// Support: IE<10
+	// Check if getElementById returns elements by name
+	// The broken getElementById methods don't pick up programatically-set names,
+	// so use a roundabout getElementsByName test
+	support.getById = assert(function( div ) {
+		docElem.appendChild( div ).id = expando;
+		return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
+	});
+
+	// ID find and filter
+	if ( support.getById ) {
+		Expr.find["ID"] = function( id, context ) {
+			if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
+				var m = context.getElementById( id );
+				// Check parentNode to catch when Blackberry 4.6 returns
+				// nodes that are no longer in the document #6963
+				return m && m.parentNode ? [m] : [];
+			}
+		};
+		Expr.filter["ID"] = function( id ) {
+			var attrId = id.replace( runescape, funescape );
+			return function( elem ) {
+				return elem.getAttribute("id") === attrId;
+			};
+		};
+	} else {
+		// Support: IE6/7
+		// getElementById is not reliable as a find shortcut
+		delete Expr.find["ID"];
+
+		Expr.filter["ID"] =  function( id ) {
+			var attrId = id.replace( runescape, funescape );
+			return function( elem ) {
+				var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
+				return node && node.value === attrId;
+			};
+		};
+	}
+
+	// Tag
+	Expr.find["TAG"] = support.getElementsByTagName ?
+		function( tag, context ) {
+			if ( typeof context.getElementsByTagName !== strundefined ) {
+				return context.getElementsByTagName( tag );
+			}
+		} :
+		function( tag, context ) {
+			var elem,
+				tmp = [],
+				i = 0,
+				results = context.getElementsByTagName( tag );
+
+			// Filter out possible comments
+			if ( tag === "*" ) {
+				while ( (elem = results[i++]) ) {
+					if ( elem.nodeType === 1 ) {
+						tmp.push( elem );
+					}
+				}
+
+				return tmp;
+			}
+			return results;
+		};
+
+	// Class
+	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
+		if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
+			return context.getElementsByClassName( className );
+		}
+	};
+
+	/* QSA/matchesSelector
+	---------------------------------------------------------------------- */
+
+	// QSA and matchesSelector support
+
+	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+	rbuggyMatches = [];
+
+	// qSa(:focus) reports false when true (Chrome 21)
+	// We allow this because of a bug in IE8/9 that throws an error
+	// whenever `document.activeElement` is accessed on an iframe
+	// So, we allow :focus to pass through QSA all the time to avoid the IE error
+	// See http://bugs.jquery.com/ticket/13378
+	rbuggyQSA = [];
+
+	if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
+		// Build QSA regex
+		// Regex strategy adopted from Diego Perini
+		assert(function( div ) {
+			// Select is set to empty string on purpose
+			// This is to test IE's treatment of not explicitly
+			// setting a boolean content attribute,
+			// since its presence should be enough
+			// http://bugs.jquery.com/ticket/12359
+			div.innerHTML = "<select><option selected=''></option></select>";
+
+			// Support: IE8
+			// Boolean attributes and "value" are not treated correctly
+			if ( !div.querySelectorAll("[selected]").length ) {
+				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
+			}
+
+			// Webkit/Opera - :checked should return selected option elements
+			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+			// IE8 throws error here and will not see later tests
+			if ( !div.querySelectorAll(":checked").length ) {
+				rbuggyQSA.push(":checked");
+			}
+		});
+
+		assert(function( div ) {
+
+			// Support: Opera 10-12/IE8
+			// ^= $= *= and empty values
+			// Should not select anything
+			// Support: Windows 8 Native Apps
+			// The type attribute is restricted during .innerHTML assignment
+			var input = doc.createElement("input");
+			input.setAttribute( "type", "hidden" );
+			div.appendChild( input ).setAttribute( "t", "" );
+
+			if ( div.querySelectorAll("[t^='']").length ) {
+				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+			}
+
+			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+			// IE8 throws error here and will not see later tests
+			if ( !div.querySelectorAll(":enabled").length ) {
+				rbuggyQSA.push( ":enabled", ":disabled" );
+			}
+
+			// Opera 10-11 does not throw on post-comma invalid pseudos
+			div.querySelectorAll("*,:x");
+			rbuggyQSA.push(",.*:");
+		});
+	}
+
+	if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
+		docElem.mozMatchesSelector ||
+		docElem.oMatchesSelector ||
+		docElem.msMatchesSelector) )) ) {
+
+		assert(function( div ) {
+			// Check to see if it's possible to do matchesSelector
+			// on a disconnected node (IE 9)
+			support.disconnectedMatch = matches.call( div, "div" );
+
+			// This should fail with an exception
+			// Gecko does not error, returns false instead
+			matches.call( div, "[s!='']:x" );
+			rbuggyMatches.push( "!=", pseudos );
+		});
+	}
+
+	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
+
+	/* Contains
+	---------------------------------------------------------------------- */
+
+	// Element contains another
+	// Purposefully does not implement inclusive descendent
+	// As in, an element does not contain itself
+	contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ?
+		function( a, b ) {
+			var adown = a.nodeType === 9 ? a.documentElement : a,
+				bup = b && b.parentNode;
+			return a === bup || !!( bup && bup.nodeType === 1 && (
+				adown.contains ?
+					adown.contains( bup ) :
+					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+			));
+		} :
+		function( a, b ) {
+			if ( b ) {
+				while ( (b = b.parentNode) ) {
+					if ( b === a ) {
+						return true;
+					}
+				}
+			}
+			return false;
+		};
+
+	/* Sorting
+	---------------------------------------------------------------------- */
+
+	// Document order sorting
+	sortOrder = docElem.compareDocumentPosition ?
+	function( a, b ) {
+
+		// Flag for duplicate removal
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+		}
+
+		var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b );
+
+		if ( compare ) {
+			// Disconnected nodes
+			if ( compare & 1 ||
+				(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
+
+				// Choose the first element that is related to our preferred document
+				if ( a === doc || contains(preferredDoc, a) ) {
+					return -1;
+				}
+				if ( b === doc || contains(preferredDoc, b) ) {
+					return 1;
+				}
+
+				// Maintain original order
+				return sortInput ?
+					( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
+					0;
+			}
+
+			return compare & 4 ? -1 : 1;
+		}
+
+		// Not directly comparable, sort on existence of method
+		return a.compareDocumentPosition ? -1 : 1;
+	} :
+	function( a, b ) {
+		var cur,
+			i = 0,
+			aup = a.parentNode,
+			bup = b.parentNode,
+			ap = [ a ],
+			bp = [ b ];
+
+		// Exit early if the nodes are identical
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+
+		// Parentless nodes are either documents or disconnected
+		} else if ( !aup || !bup ) {
+			return a === doc ? -1 :
+				b === doc ? 1 :
+				aup ? -1 :
+				bup ? 1 :
+				sortInput ?
+				( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
+				0;
+
+		// If the nodes are siblings, we can do a quick check
+		} else if ( aup === bup ) {
+			return siblingCheck( a, b );
+		}
+
+		// Otherwise we need full lists of their ancestors for comparison
+		cur = a;
+		while ( (cur = cur.parentNode) ) {
+			ap.unshift( cur );
+		}
+		cur = b;
+		while ( (cur = cur.parentNode) ) {
+			bp.unshift( cur );
+		}
+
+		// Walk down the tree looking for a discrepancy
+		while ( ap[i] === bp[i] ) {
+			i++;
+		}
+
+		return i ?
+			// Do a sibling check if the nodes have a common ancestor
+			siblingCheck( ap[i], bp[i] ) :
+
+			// Otherwise nodes in our document sort first
+			ap[i] === preferredDoc ? -1 :
+			bp[i] === preferredDoc ? 1 :
+			0;
+	};
+
+	return doc;
+};
+
+Sizzle.matches = function( expr, elements ) {
+	return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+	// Set document vars if needed
+	if ( ( elem.ownerDocument || elem ) !== document ) {
+		setDocument( elem );
+	}
+
+	// Make sure that attribute selectors are quoted
+	expr = expr.replace( rattributeQuotes, "='$1']" );
+
+	if ( support.matchesSelector && documentIsHTML &&
+		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
+		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
+
+		try {
+			var ret = matches.call( elem, expr );
+
+			// IE 9's matchesSelector returns false on disconnected nodes
+			if ( ret || support.disconnectedMatch ||
+					// As well, disconnected nodes are said to be in a document
+					// fragment in IE 9
+					elem.document && elem.document.nodeType !== 11 ) {
+				return ret;
+			}
+		} catch(e) {}
+	}
+
+	return Sizzle( expr, document, null, [elem] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+	// Set document vars if needed
+	if ( ( context.ownerDocument || context ) !== document ) {
+		setDocument( context );
+	}
+	return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+	// Set document vars if needed
+	if ( ( elem.ownerDocument || elem ) !== document ) {
+		setDocument( elem );
+	}
+
+	var fn = Expr.attrHandle[ name.toLowerCase() ],
+		// Don't get fooled by Object.prototype properties (jQuery #13807)
+		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+			fn( elem, name, !documentIsHTML ) :
+			undefined;
+
+	return val === undefined ?
+		support.attributes || !documentIsHTML ?
+			elem.getAttribute( name ) :
+			(val = elem.getAttributeNode(name)) && val.specified ?
+				val.value :
+				null :
+		val;
+};
+
+Sizzle.error = function( msg ) {
+	throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+/**
+ * Document sorting and removing duplicates
+ * @param {ArrayLike} results
+ */
+Sizzle.uniqueSort = function( results ) {
+	var elem,
+		duplicates = [],
+		j = 0,
+		i = 0;
+
+	// Unless we *know* we can detect duplicates, assume their presence
+	hasDuplicate = !support.detectDuplicates;
+	sortInput = !support.sortStable && results.slice( 0 );
+	results.sort( sortOrder );
+
+	if ( hasDuplicate ) {
+		while ( (elem = results[i++]) ) {
+			if ( elem === results[ i ] ) {
+				j = duplicates.push( i );
+			}
+		}
+		while ( j-- ) {
+			results.splice( duplicates[ j ], 1 );
+		}
+	}
+
+	return results;
+};
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+	var node,
+		ret = "",
+		i = 0,
+		nodeType = elem.nodeType;
+
+	if ( !nodeType ) {
+		// If no nodeType, this is expected to be an array
+		for ( ; (node = elem[i]); i++ ) {
+			// Do not traverse comment nodes
+			ret += getText( node );
+		}
+	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+		// Use textContent for elements
+		// innerText usage removed for consistency of new lines (see #11153)
+		if ( typeof elem.textContent === "string" ) {
+			return elem.textContent;
+		} else {
+			// Traverse its children
+			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+				ret += getText( elem );
+			}
+		}
+	} else if ( nodeType === 3 || nodeType === 4 ) {
+		return elem.nodeValue;
+	}
+	// Do not include comment or processing instruction nodes
+
+	return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+	// Can be adjusted by the user
+	cacheLength: 50,
+
+	createPseudo: markFunction,
+
+	match: matchExpr,
+
+	attrHandle: {},
+
+	find: {},
+
+	relative: {
+		">": { dir: "parentNode", first: true },
+		" ": { dir: "parentNode" },
+		"+": { dir: "previousSibling", first: true },
+		"~": { dir: "previousSibling" }
+	},
+
+	preFilter: {
+		"ATTR": function( match ) {
+			match[1] = match[1].replace( runescape, funescape );
+
+			// Move the given value to match[3] whether quoted or unquoted
+			match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
+
+			if ( match[2] === "~=" ) {
+				match[3] = " " + match[3] + " ";
+			}
+
+			return match.slice( 0, 4 );
+		},
+
+		"CHILD": function( match ) {
+			/* matches from matchExpr["CHILD"]
+				1 type (only|nth|...)
+				2 what (child|of-type)
+				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+				4 xn-component of xn+y argument ([+-]?\d*n|)
+				5 sign of xn-component
+				6 x of xn-component
+				7 sign of y-component
+				8 y of y-component
+			*/
+			match[1] = match[1].toLowerCase();
+
+			if ( match[1].slice( 0, 3 ) === "nth" ) {
+				// nth-* requires argument
+				if ( !match[3] ) {
+					Sizzle.error( match[0] );
+				}
+
+				// numeric x and y parameters for Expr.filter.CHILD
+				// remember that false/true cast respectively to 0/1
+				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
+				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+			// other types prohibit arguments
+			} else if ( match[3] ) {
+				Sizzle.error( match[0] );
+			}
+
+			return match;
+		},
+
+		"PSEUDO": function( match ) {
+			var excess,
+				unquoted = !match[5] && match[2];
+
+			if ( matchExpr["CHILD"].test( match[0] ) ) {
+				return null;
+			}
+
+			// Accept quoted arguments as-is
+			if ( match[3] && match[4] !== undefined ) {
+				match[2] = match[4];
+
+			// Strip excess characters from unquoted arguments
+			} else if ( unquoted && rpseudo.test( unquoted ) &&
+				// Get excess from tokenize (recursively)
+				(excess = tokenize( unquoted, true )) &&
+				// advance to the next closing parenthesis
+				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+				// excess is a negative index
+				match[0] = match[0].slice( 0, excess );
+				match[2] = unquoted.slice( 0, excess );
+			}
+
+			// Return only captures needed by the pseudo filter method (type and argument)
+			return match.slice( 0, 3 );
+		}
+	},
+
+	filter: {
+
+		"TAG": function( nodeNameSelector ) {
+			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
+			return nodeNameSelector === "*" ?
+				function() { return true; } :
+				function( elem ) {
+					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+				};
+		},
+
+		"CLASS": function( className ) {
+			var pattern = classCache[ className + " " ];
+
+			return pattern ||
+				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
+				classCache( className, function( elem ) {
+					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
+				});
+		},
+
+		"ATTR": function( name, operator, check ) {
+			return function( elem ) {
+				var result = Sizzle.attr( elem, name );
+
+				if ( result == null ) {
+					return operator === "!=";
+				}
+				if ( !operator ) {
+					return true;
+				}
+
+				result += "";
+
+				return operator === "=" ? result === check :
+					operator === "!=" ? result !== check :
+					operator === "^=" ? check && result.indexOf( check ) === 0 :
+					operator === "*=" ? check && result.indexOf( check ) > -1 :
+					operator === "$=" ? check && result.slice( -check.length ) === check :
+					operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
+					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+					false;
+			};
+		},
+
+		"CHILD": function( type, what, argument, first, last ) {
+			var simple = type.slice( 0, 3 ) !== "nth",
+				forward = type.slice( -4 ) !== "last",
+				ofType = what === "of-type";
+
+			return first === 1 && last === 0 ?
+
+				// Shortcut for :nth-*(n)
+				function( elem ) {
+					return !!elem.parentNode;
+				} :
+
+				function( elem, context, xml ) {
+					var cache, outerCache, node, diff, nodeIndex, start,
+						dir = simple !== forward ? "nextSibling" : "previousSibling",
+						parent = elem.parentNode,
+						name = ofType && elem.nodeName.toLowerCase(),
+						useCache = !xml && !ofType;
+
+					if ( parent ) {
+
+						// :(first|last|only)-(child|of-type)
+						if ( simple ) {
+							while ( dir ) {
+								node = elem;
+								while ( (node = node[ dir ]) ) {
+									if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
+										return false;
+									}
+								}
+								// Reverse direction for :only-* (if we haven't yet done so)
+								start = dir = type === "only" && !start && "nextSibling";
+							}
+							return true;
+						}
+
+						start = [ forward ? parent.firstChild : parent.lastChild ];
+
+						// non-xml :nth-child(...) stores cache data on `parent`
+						if ( forward && useCache ) {
+							// Seek `elem` from a previously-cached index
+							outerCache = parent[ expando ] || (parent[ expando ] = {});
+							cache = outerCache[ type ] || [];
+							nodeIndex = cache[0] === dirruns && cache[1];
+							diff = cache[0] === dirruns && cache[2];
+							node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+							while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+								// Fallback to seeking `elem` from the start
+								(diff = nodeIndex = 0) || start.pop()) ) {
+
+								// When found, cache indexes on `parent` and break
+								if ( node.nodeType === 1 && ++diff && node === elem ) {
+									outerCache[ type ] = [ dirruns, nodeIndex, diff ];
+									break;
+								}
+							}
+
+						// Use previously-cached element index if available
+						} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
+							diff = cache[1];
+
+						// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
+						} else {
+							// Use the same loop as above to seek `elem` from the start
+							while ( (node = ++nodeIndex && node && node[ dir ] ||
+								(diff = nodeIndex = 0) || start.pop()) ) {
+
+								if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
+									// Cache the index of each encountered element
+									if ( useCache ) {
+										(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
+									}
+
+									if ( node === elem ) {
+										break;
+									}
+								}
+							}
+						}
+
+						// Incorporate the offset, then check against cycle size
+						diff -= last;
+						return diff === first || ( diff % first === 0 && diff / first >= 0 );
+					}
+				};
+		},
+
+		"PSEUDO": function( pseudo, argument ) {
+			// pseudo-class names are case-insensitive
+			// http://www.w3.org/TR/selectors/#pseudo-classes
+			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+			// Remember that setFilters inherits from pseudos
+			var args,
+				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+					Sizzle.error( "unsupported pseudo: " + pseudo );
+
+			// The user may use createPseudo to indicate that
+			// arguments are needed to create the filter function
+			// just as Sizzle does
+			if ( fn[ expando ] ) {
+				return fn( argument );
+			}
+
+			// But maintain support for old signatures
+			if ( fn.length > 1 ) {
+				args = [ pseudo, pseudo, "", argument ];
+				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+					markFunction(function( seed, matches ) {
+						var idx,
+							matched = fn( seed, argument ),
+							i = matched.length;
+						while ( i-- ) {
+							idx = indexOf.call( seed, matched[i] );
+							seed[ idx ] = !( matches[ idx ] = matched[i] );
+						}
+					}) :
+					function( elem ) {
+						return fn( elem, 0, args );
+					};
+			}
+
+			return fn;
+		}
+	},
+
+	pseudos: {
+		// Potentially complex pseudos
+		"not": markFunction(function( selector ) {
+			// Trim the selector passed to compile
+			// to avoid treating leading and trailing
+			// spaces as combinators
+			var input = [],
+				results = [],
+				matcher = compile( selector.replace( rtrim, "$1" ) );
+
+			return matcher[ expando ] ?
+				markFunction(function( seed, matches, context, xml ) {
+					var elem,
+						unmatched = matcher( seed, null, xml, [] ),
+						i = seed.length;
+
+					// Match elements unmatched by `matcher`
+					while ( i-- ) {
+						if ( (elem = unmatched[i]) ) {
+							seed[i] = !(matches[i] = elem);
+						}
+					}
+				}) :
+				function( elem, context, xml ) {
+					input[0] = elem;
+					matcher( input, null, xml, results );
+					return !results.pop();
+				};
+		}),
+
+		"has": markFunction(function( selector ) {
+			return function( elem ) {
+				return Sizzle( selector, elem ).length > 0;
+			};
+		}),
+
+		"contains": markFunction(function( text ) {
+			return function( elem ) {
+				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+			};
+		}),
+
+		// "Whether an element is represented by a :lang() selector
+		// is based solely on the element's language value
+		// being equal to the identifier C,
+		// or beginning with the identifier C immediately followed by "-".
+		// The matching of C against the element's language value is performed case-insensitively.
+		// The identifier C does not have to be a valid language name."
+		// http://www.w3.org/TR/selectors/#lang-pseudo
+		"lang": markFunction( function( lang ) {
+			// lang value must be a valid identifier
+			if ( !ridentifier.test(lang || "") ) {
+				Sizzle.error( "unsupported lang: " + lang );
+			}
+			lang = lang.replace( runescape, funescape ).toLowerCase();
+			return function( elem ) {
+				var elemLang;
+				do {
+					if ( (elemLang = documentIsHTML ?
+						elem.lang :
+						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
+
+						elemLang = elemLang.toLowerCase();
+						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+					}
+				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+				return false;
+			};
+		}),
+
+		// Miscellaneous
+		"target": function( elem ) {
+			var hash = window.location && window.location.hash;
+			return hash && hash.slice( 1 ) === elem.id;
+		},
+
+		"root": function( elem ) {
+			return elem === docElem;
+		},
+
+		"focus": function( elem ) {
+			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+		},
+
+		// Boolean properties
+		"enabled": function( elem ) {
+			return elem.disabled === false;
+		},
+
+		"disabled": function( elem ) {
+			return elem.disabled === true;
+		},
+
+		"checked": function( elem ) {
+			// In CSS3, :checked should return both checked and selected elements
+			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+			var nodeName = elem.nodeName.toLowerCase();
+			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+		},
+
+		"selected": function( elem ) {
+			// Accessing this property makes selected-by-default
+			// options in Safari work properly
+			if ( elem.parentNode ) {
+				elem.parentNode.selectedIndex;
+			}
+
+			return elem.selected === true;
+		},
+
+		// Contents
+		"empty": function( elem ) {
+			// http://www.w3.org/TR/selectors/#empty-pseudo
+			// :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
+			//   not comment, processing instructions, or others
+			// Thanks to Diego Perini for the nodeName shortcut
+			//   Greater than "@" means alpha characters (specifically not starting with "#" or "?")
+			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+				if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) {
+					return false;
+				}
+			}
+			return true;
+		},
+
+		"parent": function( elem ) {
+			return !Expr.pseudos["empty"]( elem );
+		},
+
+		// Element/input types
+		"header": function( elem ) {
+			return rheader.test( elem.nodeName );
+		},
+
+		"input": function( elem ) {
+			return rinputs.test( elem.nodeName );
+		},
+
+		"button": function( elem ) {
+			var name = elem.nodeName.toLowerCase();
+			return name === "input" && elem.type === "button" || name === "button";
+		},
+
+		"text": function( elem ) {
+			var attr;
+			// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+			// use getAttribute instead to test this case
+			return elem.nodeName.toLowerCase() === "input" &&
+				elem.type === "text" &&
+				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type );
+		},
+
+		// Position-in-collection
+		"first": createPositionalPseudo(function() {
+			return [ 0 ];
+		}),
+
+		"last": createPositionalPseudo(function( matchIndexes, length ) {
+			return [ length - 1 ];
+		}),
+
+		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			return [ argument < 0 ? argument + length : argument ];
+		}),
+
+		"even": createPositionalPseudo(function( matchIndexes, length ) {
+			var i = 0;
+			for ( ; i < length; i += 2 ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"odd": createPositionalPseudo(function( matchIndexes, length ) {
+			var i = 1;
+			for ( ; i < length; i += 2 ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			var i = argument < 0 ? argument + length : argument;
+			for ( ; --i >= 0; ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			var i = argument < 0 ? argument + length : argument;
+			for ( ; ++i < length; ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		})
+	}
+};
+
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+	Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+	Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+// Easy API for creating new setFilters
+function setFilters() {}
+setFilters.prototype = Expr.filters = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+function tokenize( selector, parseOnly ) {
+	var matched, match, tokens, type,
+		soFar, groups, preFilters,
+		cached = tokenCache[ selector + " " ];
+
+	if ( cached ) {
+		return parseOnly ? 0 : cached.slice( 0 );
+	}
+
+	soFar = selector;
+	groups = [];
+	preFilters = Expr.preFilter;
+
+	while ( soFar ) {
+
+		// Comma and first run
+		if ( !matched || (match = rcomma.exec( soFar )) ) {
+			if ( match ) {
+				// Don't consume trailing commas as valid
+				soFar = soFar.slice( match[0].length ) || soFar;
+			}
+			groups.push( tokens = [] );
+		}
+
+		matched = false;
+
+		// Combinators
+		if ( (match = rcombinators.exec( soFar )) ) {
+			matched = match.shift();
+			tokens.push({
+				value: matched,
+				// Cast descendant combinators to space
+				type: match[0].replace( rtrim, " " )
+			});
+			soFar = soFar.slice( matched.length );
+		}
+
+		// Filters
+		for ( type in Expr.filter ) {
+			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+				(match = preFilters[ type ]( match ))) ) {
+				matched = match.shift();
+				tokens.push({
+					value: matched,
+					type: type,
+					matches: match
+				});
+				soFar = soFar.slice( matched.length );
+			}
+		}
+
+		if ( !matched ) {
+			break;
+		}
+	}
+
+	// Return the length of the invalid excess
+	// if we're just parsing
+	// Otherwise, throw an error or return tokens
+	return parseOnly ?
+		soFar.length :
+		soFar ?
+			Sizzle.error( selector ) :
+			// Cache the tokens
+			tokenCache( selector, groups ).slice( 0 );
+}
+
+function toSelector( tokens ) {
+	var i = 0,
+		len = tokens.length,
+		selector = "";
+	for ( ; i < len; i++ ) {
+		selector += tokens[i].value;
+	}
+	return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+	var dir = combinator.dir,
+		checkNonElements = base && dir === "parentNode",
+		doneName = done++;
+
+	return combinator.first ?
+		// Check against closest ancestor/preceding element
+		function( elem, context, xml ) {
+			while ( (elem = elem[ dir ]) ) {
+				if ( elem.nodeType === 1 || checkNonElements ) {
+					return matcher( elem, context, xml );
+				}
+			}
+		} :
+
+		// Check against all ancestor/preceding elements
+		function( elem, context, xml ) {
+			var data, cache, outerCache,
+				dirkey = dirruns + " " + doneName;
+
+			// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
+			if ( xml ) {
+				while ( (elem = elem[ dir ]) ) {
+					if ( elem.nodeType === 1 || checkNonElements ) {
+						if ( matcher( elem, context, xml ) ) {
+							return true;
+						}
+					}
+				}
+			} else {
+				while ( (elem = elem[ dir ]) ) {
+					if ( elem.nodeType === 1 || checkNonElements ) {
+						outerCache = elem[ expando ] || (elem[ expando ] = {});
+						if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) {
+							if ( (data = cache[1]) === true || data === cachedruns ) {
+								return data === true;
+							}
+						} else {
+							cache = outerCache[ dir ] = [ dirkey ];
+							cache[1] = matcher( elem, context, xml ) || cachedruns;
+							if ( cache[1] === true ) {
+								return true;
+							}
+						}
+					}
+				}
+			}
+		};
+}
+
+function elementMatcher( matchers ) {
+	return matchers.length > 1 ?
+		function( elem, context, xml ) {
+			var i = matchers.length;
+			while ( i-- ) {
+				if ( !matchers[i]( elem, context, xml ) ) {
+					return false;
+				}
+			}
+			return true;
+		} :
+		matchers[0];
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+	var elem,
+		newUnmatched = [],
+		i = 0,
+		len = unmatched.length,
+		mapped = map != null;
+
+	for ( ; i < len; i++ ) {
+		if ( (elem = unmatched[i]) ) {
+			if ( !filter || filter( elem, context, xml ) ) {
+				newUnmatched.push( elem );
+				if ( mapped ) {
+					map.push( i );
+				}
+			}
+		}
+	}
+
+	return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+	if ( postFilter && !postFilter[ expando ] ) {
+		postFilter = setMatcher( postFilter );
+	}
+	if ( postFinder && !postFinder[ expando ] ) {
+		postFinder = setMatcher( postFinder, postSelector );
+	}
+	return markFunction(function( seed, results, context, xml ) {
+		var temp, i, elem,
+			preMap = [],
+			postMap = [],
+			preexisting = results.length,
+
+			// Get initial elements from seed or context
+			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+
+			// Prefilter to get matcher input, preserving a map for seed-results synchronization
+			matcherIn = preFilter && ( seed || !selector ) ?
+				condense( elems, preMap, preFilter, context, xml ) :
+				elems,
+
+			matcherOut = matcher ?
+				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+					// ...intermediate processing is necessary
+					[] :
+
+					// ...otherwise use results directly
+					results :
+				matcherIn;
+
+		// Find primary matches
+		if ( matcher ) {
+			matcher( matcherIn, matcherOut, context, xml );
+		}
+
+		// Apply postFilter
+		if ( postFilter ) {
+			temp = condense( matcherOut, postMap );
+			postFilter( temp, [], context, xml );
+
+			// Un-match failing elements by moving them back to matcherIn
+			i = temp.length;
+			while ( i-- ) {
+				if ( (elem = temp[i]) ) {
+					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+				}
+			}
+		}
+
+		if ( seed ) {
+			if ( postFinder || preFilter ) {
+				if ( postFinder ) {
+					// Get the final matcherOut by condensing this intermediate into postFinder contexts
+					temp = [];
+					i = matcherOut.length;
+					while ( i-- ) {
+						if ( (elem = matcherOut[i]) ) {
+							// Restore matcherIn since elem is not yet a final match
+							temp.push( (matcherIn[i] = elem) );
+						}
+					}
+					postFinder( null, (matcherOut = []), temp, xml );
+				}
+
+				// Move matched elements from seed to results to keep them synchronized
+				i = matcherOut.length;
+				while ( i-- ) {
+					if ( (elem = matcherOut[i]) &&
+						(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
+
+						seed[temp] = !(results[temp] = elem);
+					}
+				}
+			}
+
+		// Add elements to results, through postFinder if defined
+		} else {
+			matcherOut = condense(
+				matcherOut === results ?
+					matcherOut.splice( preexisting, matcherOut.length ) :
+					matcherOut
+			);
+			if ( postFinder ) {
+				postFinder( null, results, matcherOut, xml );
+			} else {
+				push.apply( results, matcherOut );
+			}
+		}
+	});
+}
+
+function matcherFromTokens( tokens ) {
+	var checkContext, matcher, j,
+		len = tokens.length,
+		leadingRelative = Expr.relative[ tokens[0].type ],
+		implicitRelative = leadingRelative || Expr.relative[" "],
+		i = leadingRelative ? 1 : 0,
+
+		// The foundational matcher ensures that elements are reachable from top-level context(s)
+		matchContext = addCombinator( function( elem ) {
+			return elem === checkContext;
+		}, implicitRelative, true ),
+		matchAnyContext = addCombinator( function( elem ) {
+			return indexOf.call( checkContext, elem ) > -1;
+		}, implicitRelative, true ),
+		matchers = [ function( elem, context, xml ) {
+			return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+				(checkContext = context).nodeType ?
+					matchContext( elem, context, xml ) :
+					matchAnyContext( elem, context, xml ) );
+		} ];
+
+	for ( ; i < len; i++ ) {
+		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+		} else {
+			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+			// Return special upon seeing a positional matcher
+			if ( matcher[ expando ] ) {
+				// Find the next relative operator (if any) for proper handling
+				j = ++i;
+				for ( ; j < len; j++ ) {
+					if ( Expr.relative[ tokens[j].type ] ) {
+						break;
+					}
+				}
+				return setMatcher(
+					i > 1 && elementMatcher( matchers ),
+					i > 1 && toSelector(
+						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
+						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
+					).replace( rtrim, "$1" ),
+					matcher,
+					i < j && matcherFromTokens( tokens.slice( i, j ) ),
+					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+					j < len && toSelector( tokens )
+				);
+			}
+			matchers.push( matcher );
+		}
+	}
+
+	return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+	// A counter to specify which element is currently being matched
+	var matcherCachedRuns = 0,
+		bySet = setMatchers.length > 0,
+		byElement = elementMatchers.length > 0,
+		superMatcher = function( seed, context, xml, results, expandContext ) {
+			var elem, j, matcher,
+				setMatched = [],
+				matchedCount = 0,
+				i = "0",
+				unmatched = seed && [],
+				outermost = expandContext != null,
+				contextBackup = outermostContext,
+				// We must always have either seed elements or context
+				elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
+				// Use integer dirruns iff this is the outermost matcher
+				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1);
+
+			if ( outermost ) {
+				outermostContext = context !== document && context;
+				cachedruns = matcherCachedRuns;
+			}
+
+			// Add elements passing elementMatchers directly to results
+			// Keep `i` a string if there are no elements so `matchedCount` will be "00" below
+			for ( ; (elem = elems[i]) != null; i++ ) {
+				if ( byElement && elem ) {
+					j = 0;
+					while ( (matcher = elementMatchers[j++]) ) {
+						if ( matcher( elem, context, xml ) ) {
+							results.push( elem );
+							break;
+						}
+					}
+					if ( outermost ) {
+						dirruns = dirrunsUnique;
+						cachedruns = ++matcherCachedRuns;
+					}
+				}
+
+				// Track unmatched elements for set filters
+				if ( bySet ) {
+					// They will have gone through all possible matchers
+					if ( (elem = !matcher && elem) ) {
+						matchedCount--;
+					}
+
+					// Lengthen the array for every element, matched or not
+					if ( seed ) {
+						unmatched.push( elem );
+					}
+				}
+			}
+
+			// Apply set filters to unmatched elements
+			matchedCount += i;
+			if ( bySet && i !== matchedCount ) {
+				j = 0;
+				while ( (matcher = setMatchers[j++]) ) {
+					matcher( unmatched, setMatched, context, xml );
+				}
+
+				if ( seed ) {
+					// Reintegrate element matches to eliminate the need for sorting
+					if ( matchedCount > 0 ) {
+						while ( i-- ) {
+							if ( !(unmatched[i] || setMatched[i]) ) {
+								setMatched[i] = pop.call( results );
+							}
+						}
+					}
+
+					// Discard index placeholder values to get only actual matches
+					setMatched = condense( setMatched );
+				}
+
+				// Add matches to results
+				push.apply( results, setMatched );
+
+				// Seedless set matches succeeding multiple successful matchers stipulate sorting
+				if ( outermost && !seed && setMatched.length > 0 &&
+					( matchedCount + setMatchers.length ) > 1 ) {
+
+					Sizzle.uniqueSort( results );
+				}
+			}
+
+			// Override manipulation of globals by nested matchers
+			if ( outermost ) {
+				dirruns = dirrunsUnique;
+				outermostContext = contextBackup;
+			}
+
+			return unmatched;
+		};
+
+	return bySet ?
+		markFunction( superMatcher ) :
+		superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
+	var i,
+		setMatchers = [],
+		elementMatchers = [],
+		cached = compilerCache[ selector + " " ];
+
+	if ( !cached ) {
+		// Generate a function of recursive functions that can be used to check each element
+		if ( !group ) {
+			group = tokenize( selector );
+		}
+		i = group.length;
+		while ( i-- ) {
+			cached = matcherFromTokens( group[i] );
+			if ( cached[ expando ] ) {
+				setMatchers.push( cached );
+			} else {
+				elementMatchers.push( cached );
+			}
+		}
+
+		// Cache the compiled function
+		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+	}
+	return cached;
+};
+
+function multipleContexts( selector, contexts, results ) {
+	var i = 0,
+		len = contexts.length;
+	for ( ; i < len; i++ ) {
+		Sizzle( selector, contexts[i], results );
+	}
+	return results;
+}
+
+function select( selector, context, results, seed ) {
+	var i, tokens, token, type, find,
+		match = tokenize( selector );
+
+	if ( !seed ) {
+		// Try to minimize operations if there is only one group
+		if ( match.length === 1 ) {
+
+			// Take a shortcut and set the context if the root selector is an ID
+			tokens = match[0] = match[0].slice( 0 );
+			if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+					support.getById && context.nodeType === 9 && documentIsHTML &&
+					Expr.relative[ tokens[1].type ] ) {
+
+				context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
+				if ( !context ) {
+					return results;
+				}
+				selector = selector.slice( tokens.shift().value.length );
+			}
+
+			// Fetch a seed set for right-to-left matching
+			i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+			while ( i-- ) {
+				token = tokens[i];
+
+				// Abort if we hit a combinator
+				if ( Expr.relative[ (type = token.type) ] ) {
+					break;
+				}
+				if ( (find = Expr.find[ type ]) ) {
+					// Search, expanding context for leading sibling combinators
+					if ( (seed = find(
+						token.matches[0].replace( runescape, funescape ),
+						rsibling.test( tokens[0].type ) && context.parentNode || context
+					)) ) {
+
+						// If seed is empty or no tokens remain, we can return early
+						tokens.splice( i, 1 );
+						selector = seed.length && toSelector( tokens );
+						if ( !selector ) {
+							push.apply( results, seed );
+							return results;
+						}
+
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	// Compile and execute a filtering function
+	// Provide `match` to avoid retokenization if we modified the selector above
+	compile( selector, match )(
+		seed,
+		context,
+		!documentIsHTML,
+		results,
+		rsibling.test( selector )
+	);
+	return results;
+}
+
+// One-time assignments
+
+// Sort stability
+support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
+
+// Support: Chrome<14
+// Always assume duplicates if they aren't passed to the comparison function
+support.detectDuplicates = hasDuplicate;
+
+// Initialize against the default document
+setDocument();
+
+// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+// Detached nodes confoundingly follow *each other*
+support.sortDetached = assert(function( div1 ) {
+	// Should return 1, but returns 4 (following)
+	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
+});
+
+// Support: IE<8
+// Prevent attribute/property "interpolation"
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !assert(function( div ) {
+	div.innerHTML = "<a href='#'></a>";
+	return div.firstChild.getAttribute("href") === "#" ;
+}) ) {
+	addHandle( "type|href|height|width", function( elem, name, isXML ) {
+		if ( !isXML ) {
+			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
+		}
+	});
+}
+
+// Support: IE<9
+// Use defaultValue in place of getAttribute("value")
+if ( !support.attributes || !assert(function( div ) {
+	div.innerHTML = "<input/>";
+	div.firstChild.setAttribute( "value", "" );
+	return div.firstChild.getAttribute( "value" ) === "";
+}) ) {
+	addHandle( "value", function( elem, name, isXML ) {
+		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
+			return elem.defaultValue;
+		}
+	});
+}
+
+// Support: IE<9
+// Use getAttributeNode to fetch booleans when getAttribute lies
+if ( !assert(function( div ) {
+	return div.getAttribute("disabled") == null;
+}) ) {
+	addHandle( booleans, function( elem, name, isXML ) {
+		var val;
+		if ( !isXML ) {
+			return (val = elem.getAttributeNode( name )) && val.specified ?
+				val.value :
+				elem[ name ] === true ? name.toLowerCase() : null;
+		}
+	});
+}
+
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.pseudos;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+})( window );
+// String to Object options format cache
+var optionsCache = {};
+
+// Convert String-formatted options into Object-formatted ones and store in cache
+function createOptions( options ) {
+	var object = optionsCache[ options ] = {};
+	jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
+		object[ flag ] = true;
+	});
+	return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ *	options: an optional list of space-separated options that will change how
+ *			the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ *	once:			will ensure the callback list can only be fired once (like a Deferred)
+ *
+ *	memory:			will keep track of previous values and will call any callback added
+ *					after the list has been fired right away with the latest "memorized"
+ *					values (like a Deferred)
+ *
+ *	unique:			will ensure a callback can only be added once (no duplicate in the list)
+ *
+ *	stopOnFalse:	interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
+
+	// Convert options from String-formatted to Object-formatted if needed
+	// (we check in cache first)
+	options = typeof options === "string" ?
+		( optionsCache[ options ] || createOptions( options ) ) :
+		jQuery.extend( {}, options );
+
+	var // Flag to know if list is currently firing
+		firing,
+		// Last fire value (for non-forgettable lists)
+		memory,
+		// Flag to know if list was already fired
+		fired,
+		// End of the loop when firing
+		firingLength,
+		// Index of currently firing callback (modified by remove if needed)
+		firingIndex,
+		// First callback to fire (used internally by add and fireWith)
+		firingStart,
+		// Actual callback list
+		list = [],
+		// Stack of fire calls for repeatable lists
+		stack = !options.once && [],
+		// Fire callbacks
+		fire = function( data ) {
+			memory = options.memory && data;
+			fired = true;
+			firingIndex = firingStart || 0;
+			firingStart = 0;
+			firingLength = list.length;
+			firing = true;
+			for ( ; list && firingIndex < firingLength; firingIndex++ ) {
+				if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
+					memory = false; // To prevent further calls using add
+					break;
+				}
+			}
+			firing = false;
+			if ( list ) {
+				if ( stack ) {
+					if ( stack.length ) {
+						fire( stack.shift() );
+					}
+				} else if ( memory ) {
+					list = [];
+				} else {
+					self.disable();
+				}
+			}
+		},
+		// Actual Callbacks object
+		self = {
+			// Add a callback or a collection of callbacks to the list
+			add: function() {
+				if ( list ) {
+					// First, we save the current length
+					var start = list.length;
+					(function add( args ) {
+						jQuery.each( args, function( _, arg ) {
+							var type = jQuery.type( arg );
+							if ( type === "function" ) {
+								if ( !options.unique || !self.has( arg ) ) {
+									list.push( arg );
+								}
+							} else if ( arg && arg.length && type !== "string" ) {
+								// Inspect recursively
+								add( arg );
+							}
+						});
+					})( arguments );
+					// Do we need to add the callbacks to the
+					// current firing batch?
+					if ( firing ) {
+						firingLength = list.length;
+					// With memory, if we're not firing then
+					// we should call right away
+					} else if ( memory ) {
+						firingStart = start;
+						fire( memory );
+					}
+				}
+				return this;
+			},
+			// Remove a callback from the list
+			remove: function() {
+				if ( list ) {
+					jQuery.each( arguments, function( _, arg ) {
+						var index;
+						while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+							list.splice( index, 1 );
+							// Handle firing indexes
+							if ( firing ) {
+								if ( index <= firingLength ) {
+									firingLength--;
+								}
+								if ( index <= firingIndex ) {
+									firingIndex--;
+								}
+							}
+						}
+					});
+				}
+				return this;
+			},
+			// Check if a given callback is in the list.
+			// If no argument is given, return whether or not list has callbacks attached.
+			has: function( fn ) {
+				return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
+			},
+			// Remove all callbacks from the list
+			empty: function() {
+				list = [];
+				firingLength = 0;
+				return this;
+			},
+			// Have the list do nothing anymore
+			disable: function() {
+				list = stack = memory = undefined;
+				return this;
+			},
+			// Is it disabled?
+			disabled: function() {
+				return !list;
+			},
+			// Lock the list in its current state
+			lock: function() {
+				stack = undefined;
+				if ( !memory ) {
+					self.disable();
+				}
+				return this;
+			},
+			// Is it locked?
+			locked: function() {
+				return !stack;
+			},
+			// Call all callbacks with the given context and arguments
+			fireWith: function( context, args ) {
+				if ( list && ( !fired || stack ) ) {
+					args = args || [];
+					args = [ context, args.slice ? args.slice() : args ];
+					if ( firing ) {
+						stack.push( args );
+					} else {
+						fire( args );
+					}
+				}
+				return this;
+			},
+			// Call all the callbacks with the given arguments
+			fire: function() {
+				self.fireWith( this, arguments );
+				return this;
+			},
+			// To know if the callbacks have already been called at least once
+			fired: function() {
+				return !!fired;
+			}
+		};
+
+	return self;
+};
+jQuery.extend({
+
+	Deferred: function( func ) {
+		var tuples = [
+				// action, add listener, listener list, final state
+				[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
+				[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
+				[ "notify", "progress", jQuery.Callbacks("memory") ]
+			],
+			state = "pending",
+			promise = {
+				state: function() {
+					return state;
+				},
+				always: function() {
+					deferred.done( arguments ).fail( arguments );
+					return this;
+				},
+				then: function( /* fnDone, fnFail, fnProgress */ ) {
+					var fns = arguments;
+					return jQuery.Deferred(function( newDefer ) {
+						jQuery.each( tuples, function( i, tuple ) {
+							var action = tuple[ 0 ],
+								fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
+							// deferred[ done | fail | progress ] for forwarding actions to newDefer
+							deferred[ tuple[1] ](function() {
+								var returned = fn && fn.apply( this, arguments );
+								if ( returned && jQuery.isFunction( returned.promise ) ) {
+									returned.promise()
+										.done( newDefer.resolve )
+										.fail( newDefer.reject )
+										.progress( newDefer.notify );
+								} else {
+									newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
+								}
+							});
+						});
+						fns = null;
+					}).promise();
+				},
+				// Get a promise for this deferred
+				// If obj is provided, the promise aspect is added to the object
+				promise: function( obj ) {
+					return obj != null ? jQuery.extend( obj, promise ) : promise;
+				}
+			},
+			deferred = {};
+
+		// Keep pipe for back-compat
+		promise.pipe = promise.then;
+
+		// Add list-specific methods
+		jQuery.each( tuples, function( i, tuple ) {
+			var list = tuple[ 2 ],
+				stateString = tuple[ 3 ];
+
+			// promise[ done | fail | progress ] = list.add
+			promise[ tuple[1] ] = list.add;
+
+			// Handle state
+			if ( stateString ) {
+				list.add(function() {
+					// state = [ resolved | rejected ]
+					state = stateString;
+
+				// [ reject_list | resolve_list ].disable; progress_list.lock
+				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
+			}
+
+			// deferred[ resolve | reject | notify ]
+			deferred[ tuple[0] ] = function() {
+				deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
+				return this;
+			};
+			deferred[ tuple[0] + "With" ] = list.fireWith;
+		});
+
+		// Make the deferred a promise
+		promise.promise( deferred );
+
+		// Call given func if any
+		if ( func ) {
+			func.call( deferred, deferred );
+		}
+
+		// All done!
+		return deferred;
+	},
+
+	// Deferred helper
+	when: function( subordinate /* , ..., subordinateN */ ) {
+		var i = 0,
+			resolveValues = core_slice.call( arguments ),
+			length = resolveValues.length,
+
+			// the count of uncompleted subordinates
+			remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
+
+			// the master Deferred. If resolveValues consist of only a single Deferred, just use that.
+			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
+
+			// Update function for both resolve and progress values
+			updateFunc = function( i, contexts, values ) {
+				return function( value ) {
+					contexts[ i ] = this;
+					values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
+					if( values === progressValues ) {
+						deferred.notifyWith( contexts, values );
+					} else if ( !( --remaining ) ) {
+						deferred.resolveWith( contexts, values );
+					}
+				};
+			},
+
+			progressValues, progressContexts, resolveContexts;
+
+		// add listeners to Deferred subordinates; treat others as resolved
+		if ( length > 1 ) {
+			progressValues = new Array( length );
+			progressContexts = new Array( length );
+			resolveContexts = new Array( length );
+			for ( ; i < length; i++ ) {
+				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
+					resolveValues[ i ].promise()
+						.done( updateFunc( i, resolveContexts, resolveValues ) )
+						.fail( deferred.reject )
+						.progress( updateFunc( i, progressContexts, progressValues ) );
+				} else {
+					--remaining;
+				}
+			}
+		}
+
+		// if we're not waiting on anything, resolve the master
+		if ( !remaining ) {
+			deferred.resolveWith( resolveContexts, resolveValues );
+		}
+
+		return deferred.promise();
+	}
+});
+jQuery.support = (function( support ) {
+
+	var all, a, input, select, fragment, opt, eventName, isSupported, i,
+		div = document.createElement("div");
+
+	// Setup
+	div.setAttribute( "className", "t" );
+	div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
+
+	// Finish early in limited (non-browser) environments
+	all = div.getElementsByTagName("*") || [];
+	a = div.getElementsByTagName("a")[ 0 ];
+	if ( !a || !a.style || !all.length ) {
+		return support;
+	}
+
+	// First batch of tests
+	select = document.createElement("select");
+	opt = select.appendChild( document.createElement("option") );
+	input = div.getElementsByTagName("input")[ 0 ];
+
+	a.style.cssText = "top:1px;float:left;opacity:.5";
+
+	// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+	support.getSetAttribute = div.className !== "t";
+
+	// IE strips leading whitespace when .innerHTML is used
+	support.leadingWhitespace = div.firstChild.nodeType === 3;
+
+	// Make sure that tbody elements aren't automatically inserted
+	// IE will insert them into empty tables
+	support.tbody = !div.getElementsByTagName("tbody").length;
+
+	// Make sure that link elements get serialized correctly by innerHTML
+	// This requires a wrapper element in IE
+	support.htmlSerialize = !!div.getElementsByTagName("link").length;
+
+	// Get the style information from getAttribute
+	// (IE uses .cssText instead)
+	support.style = /top/.test( a.getAttribute("style") );
+
+	// Make sure that URLs aren't manipulated
+	// (IE normalizes it by default)
+	support.hrefNormalized = a.getAttribute("href") === "/a";
+
+	// Make sure that element opacity exists
+	// (IE uses filter instead)
+	// Use a regex to work around a WebKit issue. See #5145
+	support.opacity = /^0.5/.test( a.style.opacity );
+
+	// Verify style float existence
+	// (IE uses styleFloat instead of cssFloat)
+	support.cssFloat = !!a.style.cssFloat;
+
+	// Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
+	support.checkOn = !!input.value;
+
+	// Make sure that a selected-by-default option has a working selected property.
+	// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+	support.optSelected = opt.selected;
+
+	// Tests for enctype support on a form (#6743)
+	support.enctype = !!document.createElement("form").enctype;
+
+	// Makes sure cloning an html5 element does not cause problems
+	// Where outerHTML is undefined, this still works
+	support.html5Clone = document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>";
+
+	// Will be defined later
+	support.inlineBlockNeedsLayout = false;
+	support.shrinkWrapBlocks = false;
+	support.pixelPosition = false;
+	support.deleteExpando = true;
+	support.noCloneEvent = true;
+	support.reliableMarginRight = true;
+	support.boxSizingReliable = true;
+
+	// Make sure checked status is properly cloned
+	input.checked = true;
+	support.noCloneChecked = input.cloneNode( true ).checked;
+
+	// Make sure that the options inside disabled selects aren't marked as disabled
+	// (WebKit marks them as disabled)
+	select.disabled = true;
+	support.optDisabled = !opt.disabled;
+
+	// Support: IE<9
+	try {
+		delete div.test;
+	} catch( e ) {
+		support.deleteExpando = false;
+	}
+
+	// Check if we can trust getAttribute("value")
+	input = document.createElement("input");
+	input.setAttribute( "value", "" );
+	support.input = input.getAttribute( "value" ) === "";
+
+	// Check if an input maintains its value after becoming a radio
+	input.value = "t";
+	input.setAttribute( "type", "radio" );
+	support.radioValue = input.value === "t";
+
+	// #11217 - WebKit loses check when the name is after the checked attribute
+	input.setAttribute( "checked", "t" );
+	input.setAttribute( "name", "t" );
+
+	fragment = document.createDocumentFragment();
+	fragment.appendChild( input );
+
+	// Check if a disconnected checkbox will retain its checked
+	// value of true after appended to the DOM (IE6/7)
+	support.appendChecked = input.checked;
+
+	// WebKit doesn't clone checked state correctly in fragments
+	support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+	// Support: IE<9
+	// Opera does not clone events (and typeof div.attachEvent === undefined).
+	// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
+	if ( div.attachEvent ) {
+		div.attachEvent( "onclick", function() {
+			support.noCloneEvent = false;
+		});
+
+		div.cloneNode( true ).click();
+	}
+
+	// Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event)
+	// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
+	for ( i in { submit: true, change: true, focusin: true }) {
+		div.setAttribute( eventName = "on" + i, "t" );
+
+		support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false;
+	}
+
+	div.style.backgroundClip = "content-box";
+	div.cloneNode( true ).style.backgroundClip = "";
+	support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+	// Support: IE<9
+	// Iteration over object's inherited properties before its own.
+	for ( i in jQuery( support ) ) {
+		break;
+	}
+	support.ownLast = i !== "0";
+
+	// Run tests that need a body at doc ready
+	jQuery(function() {
+		var container, marginDiv, tds,
+			divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",
+			body = document.getElementsByTagName("body")[0];
+
+		if ( !body ) {
+			// Return for frameset docs that don't have a body
+			return;
+		}
+
+		container = document.createElement("div");
+		container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
+
+		body.appendChild( container ).appendChild( div );
+
+		// Support: IE8
+		// Check if table cells still have offsetWidth/Height when they are set
+		// to display:none and there are still other visible table cells in a
+		// table row; if so, offsetWidth/Height are not reliable for use when
+		// determining if an element has been hidden directly using
+		// display:none (it is still safe to use offsets if a parent element is
+		// hidden; don safety goggles and see bug #4512 for more information).
+		div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
+		tds = div.getElementsByTagName("td");
+		tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
+		isSupported = ( tds[ 0 ].offsetHeight === 0 );
+
+		tds[ 0 ].style.display = "";
+		tds[ 1 ].style.display = "none";
+
+		// Support: IE8
+		// Check if empty table cells still have offsetWidth/Height
+		support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
+
+		// Check box-sizing and margin behavior.
+		div.innerHTML = "";
+		div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;";
+
+		// Workaround failing boxSizing test due to offsetWidth returning wrong value
+		// with some non-1 values of body zoom, ticket #13543
+		jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() {
+			support.boxSizing = div.offsetWidth === 4;
+		});
+
+		// Use window.getComputedStyle because jsdom on node.js will break without it.
+		if ( window.getComputedStyle ) {
+			support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
+			support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
+
+			// Check if div with explicit width and no margin-right incorrectly
+			// gets computed margin-right based on width of container. (#3333)
+			// Fails in WebKit before Feb 2011 nightlies
+			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+			marginDiv = div.appendChild( document.createElement("div") );
+			marginDiv.style.cssText = div.style.cssText = divReset;
+			marginDiv.style.marginRight = marginDiv.style.width = "0";
+			div.style.width = "1px";
+
+			support.reliableMarginRight =
+				!parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
+		}
+
+		if ( typeof div.style.zoom !== core_strundefined ) {
+			// Support: IE<8
+			// Check if natively block-level elements act like inline-block
+			// elements when setting their display to 'inline' and giving
+			// them layout
+			div.innerHTML = "";
+			div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
+			support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
+
+			// Support: IE6
+			// Check if elements with layout shrink-wrap their children
+			div.style.display = "block";
+			div.innerHTML = "<div></div>";
+			div.firstChild.style.width = "5px";
+			support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
+
+			if ( support.inlineBlockNeedsLayout ) {
+				// Prevent IE 6 from affecting layout for positioned elements #11048
+				// Prevent IE from shrinking the body in IE 7 mode #12869
+				// Support: IE<8
+				body.style.zoom = 1;
+			}
+		}
+
+		body.removeChild( container );
+
+		// Null elements to avoid leaks in IE
+		container = div = tds = marginDiv = null;
+	});
+
+	// Null elements to avoid leaks in IE
+	all = select = fragment = opt = a = input = null;
+
+	return support;
+})({});
+
+var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
+	rmultiDash = /([A-Z])/g;
+
+function internalData( elem, name, data, pvt /* Internal Use Only */ ){
+	if ( !jQuery.acceptData( elem ) ) {
+		return;
+	}
+
+	var ret, thisCache,
+		internalKey = jQuery.expando,
+
+		// We have to handle DOM nodes and JS objects differently because IE6-7
+		// can't GC object references properly across the DOM-JS boundary
+		isNode = elem.nodeType,
+
+		// Only DOM nodes need the global jQuery cache; JS object data is
+		// attached directly to the object so GC can occur automatically
+		cache = isNode ? jQuery.cache : elem,
+
+		// Only defining an ID for JS objects if its cache already exists allows
+		// the code to shortcut on the same path as a DOM node with no cache
+		id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
+
+	// Avoid doing any more work than we need to when trying to get data on an
+	// object that has no data at all
+	if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) {
+		return;
+	}
+
+	if ( !id ) {
+		// Only DOM nodes need a new unique ID for each element since their data
+		// ends up in the global cache
+		if ( isNode ) {
+			id = elem[ internalKey ] = core_deletedIds.pop() || jQuery.guid++;
+		} else {
+			id = internalKey;
+		}
+	}
+
+	if ( !cache[ id ] ) {
+		// Avoid exposing jQuery metadata on plain JS objects when the object
+		// is serialized using JSON.stringify
+		cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
+	}
+
+	// An object can be passed to jQuery.data instead of a key/value pair; this gets
+	// shallow copied over onto the existing cache
+	if ( typeof name === "object" || typeof name === "function" ) {
+		if ( pvt ) {
+			cache[ id ] = jQuery.extend( cache[ id ], name );
+		} else {
+			cache[ id ].data = jQuery.extend( cache[ id ].data, name );
+		}
+	}
+
+	thisCache = cache[ id ];
+
+	// jQuery data() is stored in a separate object inside the object's internal data
+	// cache in order to avoid key collisions between internal data and user-defined
+	// data.
+	if ( !pvt ) {
+		if ( !thisCache.data ) {
+			thisCache.data = {};
+		}
+
+		thisCache = thisCache.data;
+	}
+
+	if ( data !== undefined ) {
+		thisCache[ jQuery.camelCase( name ) ] = data;
+	}
+
+	// Check for both converted-to-camel and non-converted data property names
+	// If a data property was specified
+	if ( typeof name === "string" ) {
+
+		// First Try to find as-is property data
+		ret = thisCache[ name ];
+
+		// Test for null|undefined property data
+		if ( ret == null ) {
+
+			// Try to find the camelCased property
+			ret = thisCache[ jQuery.camelCase( name ) ];
+		}
+	} else {
+		ret = thisCache;
+	}
+
+	return ret;
+}
+
+function internalRemoveData( elem, name, pvt ) {
+	if ( !jQuery.acceptData( elem ) ) {
+		return;
+	}
+
+	var thisCache, i,
+		isNode = elem.nodeType,
+
+		// See jQuery.data for more information
+		cache = isNode ? jQuery.cache : elem,
+		id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
+
+	// If there is already no cache entry for this object, there is no
+	// purpose in continuing
+	if ( !cache[ id ] ) {
+		return;
+	}
+
+	if ( name ) {
+
+		thisCache = pvt ? cache[ id ] : cache[ id ].data;
+
+		if ( thisCache ) {
+
+			// Support array or space separated string names for data keys
+			if ( !jQuery.isArray( name ) ) {
+
+				// try the string as a key before any manipulation
+				if ( name in thisCache ) {
+					name = [ name ];
+				} else {
+
+					// split the camel cased version by spaces unless a key with the spaces exists
+					name = jQuery.camelCase( name );
+					if ( name in thisCache ) {
+						name = [ name ];
+					} else {
+						name = name.split(" ");
+					}
+				}
+			} else {
+				// If "name" is an array of keys...
+				// When data is initially created, via ("key", "val") signature,
+				// keys will be converted to camelCase.
+				// Since there is no way to tell _how_ a key was added, remove
+				// both plain key and camelCase key. #12786
+				// This will only penalize the array argument path.
+				name = name.concat( jQuery.map( name, jQuery.camelCase ) );
+			}
+
+			i = name.length;
+			while ( i-- ) {
+				delete thisCache[ name[i] ];
+			}
+
+			// If there is no data left in the cache, we want to continue
+			// and let the cache object itself get destroyed
+			if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {
+				return;
+			}
+		}
+	}
+
+	// See jQuery.data for more information
+	if ( !pvt ) {
+		delete cache[ id ].data;
+
+		// Don't destroy the parent cache unless the internal data object
+		// had been the only thing left in it
+		if ( !isEmptyDataObject( cache[ id ] ) ) {
+			return;
+		}
+	}
+
+	// Destroy the cache
+	if ( isNode ) {
+		jQuery.cleanData( [ elem ], true );
+
+	// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
+	/* jshint eqeqeq: false */
+	} else if ( jQuery.support.deleteExpando || cache != cache.window ) {
+		/* jshint eqeqeq: true */
+		delete cache[ id ];
+
+	// When all else fails, null
+	} else {
+		cache[ id ] = null;
+	}
+}
+
+jQuery.extend({
+	cache: {},
+
+	// The following elements throw uncatchable exceptions if you
+	// attempt to add expando properties to them.
+	noData: {
+		"applet": true,
+		"embed": true,
+		// Ban all objects except for Flash (which handle expandos)
+		"object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
+	},
+
+	hasData: function( elem ) {
+		elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
+		return !!elem && !isEmptyDataObject( elem );
+	},
+
+	data: function( elem, name, data ) {
+		return internalData( elem, name, data );
+	},
+
+	removeData: function( elem, name ) {
+		return internalRemoveData( elem, name );
+	},
+
+	// For internal use only.
+	_data: function( elem, name, data ) {
+		return internalData( elem, name, data, true );
+	},
+
+	_removeData: function( elem, name ) {
+		return internalRemoveData( elem, name, true );
+	},
+
+	// A method for determining if a DOM node can handle the data expando
+	acceptData: function( elem ) {
+		// Do not set data on non-element because it will not be cleared (#8335).
+		if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {
+			return false;
+		}
+
+		var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+		// nodes accept data unless otherwise specified; rejection can be conditional
+		return !noData || noData !== true && elem.getAttribute("classid") === noData;
+	}
+});
+
+jQuery.fn.extend({
+	data: function( key, value ) {
+		var attrs, name,
+			data = null,
+			i = 0,
+			elem = this[0];
+
+		// Special expections of .data basically thwart jQuery.access,
+		// so implement the relevant behavior ourselves
+
+		// Gets all values
+		if ( key === undefined ) {
+			if ( this.length ) {
+				data = jQuery.data( elem );
+
+				if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
+					attrs = elem.attributes;
+					for ( ; i < attrs.length; i++ ) {
+						name = attrs[i].name;
+
+						if ( name.indexOf("data-") === 0 ) {
+							name = jQuery.camelCase( name.slice(5) );
+
+							dataAttr( elem, name, data[ name ] );
+						}
+					}
+					jQuery._data( elem, "parsedAttrs", true );
+				}
+			}
+
+			return data;
+		}
+
+		// Sets multiple values
+		if ( typeof key === "object" ) {
+			return this.each(function() {
+				jQuery.data( this, key );
+			});
+		}
+
+		return arguments.length > 1 ?
+
+			// Sets one value
+			this.each(function() {
+				jQuery.data( this, key, value );
+			}) :
+
+			// Gets one value
+			// Try to fetch any internally stored data first
+			elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null;
+	},
+
+	removeData: function( key ) {
+		return this.each(function() {
+			jQuery.removeData( this, key );
+		});
+	}
+});
+
+function dataAttr( elem, key, data ) {
+	// If nothing was found internally, try to fetch any
+	// data from the HTML5 data-* attribute
+	if ( data === undefined && elem.nodeType === 1 ) {
+
+		var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+
+		data = elem.getAttribute( name );
+
+		if ( typeof data === "string" ) {
+			try {
+				data = data === "true" ? true :
+					data === "false" ? false :
+					data === "null" ? null :
+					// Only convert to a number if it doesn't change the string
+					+data + "" === data ? +data :
+					rbrace.test( data ) ? jQuery.parseJSON( data ) :
+						data;
+			} catch( e ) {}
+
+			// Make sure we set the data so it isn't changed later
+			jQuery.data( elem, key, data );
+
+		} else {
+			data = undefined;
+		}
+	}
+
+	return data;
+}
+
+// checks a cache object for emptiness
+function isEmptyDataObject( obj ) {
+	var name;
+	for ( name in obj ) {
+
+		// if the public data object is empty, the private is still empty
+		if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
+			continue;
+		}
+		if ( name !== "toJSON" ) {
+			return false;
+		}
+	}
+
+	return true;
+}
+jQuery.extend({
+	queue: function( elem, type, data ) {
+		var queue;
+
+		if ( elem ) {
+			type = ( type || "fx" ) + "queue";
+			queue = jQuery._data( elem, type );
+
+			// Speed up dequeue by getting out quickly if this is just a lookup
+			if ( data ) {
+				if ( !queue || jQuery.isArray(data) ) {
+					queue = jQuery._data( elem, type, jQuery.makeArray(data) );
+				} else {
+					queue.push( data );
+				}
+			}
+			return queue || [];
+		}
+	},
+
+	dequeue: function( elem, type ) {
+		type = type || "fx";
+
+		var queue = jQuery.queue( elem, type ),
+			startLength = queue.length,
+			fn = queue.shift(),
+			hooks = jQuery._queueHooks( elem, type ),
+			next = function() {
+				jQuery.dequeue( elem, type );
+			};
+
+		// If the fx queue is dequeued, always remove the progress sentinel
+		if ( fn === "inprogress" ) {
+			fn = queue.shift();
+			startLength--;
+		}
+
+		if ( fn ) {
+
+			// Add a progress sentinel to prevent the fx queue from being
+			// automatically dequeued
+			if ( type === "fx" ) {
+				queue.unshift( "inprogress" );
+			}
+
+			// clear up the last queue stop function
+			delete hooks.stop;
+			fn.call( elem, next, hooks );
+		}
+
+		if ( !startLength && hooks ) {
+			hooks.empty.fire();
+		}
+	},
+
+	// not intended for public consumption - generates a queueHooks object, or returns the current one
+	_queueHooks: function( elem, type ) {
+		var key = type + "queueHooks";
+		return jQuery._data( elem, key ) || jQuery._data( elem, key, {
+			empty: jQuery.Callbacks("once memory").add(function() {
+				jQuery._removeData( elem, type + "queue" );
+				jQuery._removeData( elem, key );
+			})
+		});
+	}
+});
+
+jQuery.fn.extend({
+	queue: function( type, data ) {
+		var setter = 2;
+
+		if ( typeof type !== "string" ) {
+			data = type;
+			type = "fx";
+			setter--;
+		}
+
+		if ( arguments.length < setter ) {
+			return jQuery.queue( this[0], type );
+		}
+
+		return data === undefined ?
+			this :
+			this.each(function() {
+				var queue = jQuery.queue( this, type, data );
+
+				// ensure a hooks for this queue
+				jQuery._queueHooks( this, type );
+
+				if ( type === "fx" && queue[0] !== "inprogress" ) {
+					jQuery.dequeue( this, type );
+				}
+			});
+	},
+	dequeue: function( type ) {
+		return this.each(function() {
+			jQuery.dequeue( this, type );
+		});
+	},
+	// Based off of the plugin by Clint Helfers, with permission.
+	// http://blindsignals.com/index.php/2009/07/jquery-delay/
+	delay: function( time, type ) {
+		time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
+		type = type || "fx";
+
+		return this.queue( type, function( next, hooks ) {
+			var timeout = setTimeout( next, time );
+			hooks.stop = function() {
+				clearTimeout( timeout );
+			};
+		});
+	},
+	clearQueue: function( type ) {
+		return this.queue( type || "fx", [] );
+	},
+	// Get a promise resolved when queues of a certain type
+	// are emptied (fx is the type by default)
+	promise: function( type, obj ) {
+		var tmp,
+			count = 1,
+			defer = jQuery.Deferred(),
+			elements = this,
+			i = this.length,
+			resolve = function() {
+				if ( !( --count ) ) {
+					defer.resolveWith( elements, [ elements ] );
+				}
+			};
+
+		if ( typeof type !== "string" ) {
+			obj = type;
+			type = undefined;
+		}
+		type = type || "fx";
+
+		while( i-- ) {
+			tmp = jQuery._data( elements[ i ], type + "queueHooks" );
+			if ( tmp && tmp.empty ) {
+				count++;
+				tmp.empty.add( resolve );
+			}
+		}
+		resolve();
+		return defer.promise( obj );
+	}
+});
+var nodeHook, boolHook,
+	rclass = /[\t\r\n\f]/g,
+	rreturn = /\r/g,
+	rfocusable = /^(?:input|select|textarea|button|object)$/i,
+	rclickable = /^(?:a|area)$/i,
+	ruseDefault = /^(?:checked|selected)$/i,
+	getSetAttribute = jQuery.support.getSetAttribute,
+	getSetInput = jQuery.support.input;
+
+jQuery.fn.extend({
+	attr: function( name, value ) {
+		return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
+	},
+
+	removeAttr: function( name ) {
+		return this.each(function() {
+			jQuery.removeAttr( this, name );
+		});
+	},
+
+	prop: function( name, value ) {
+		return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
+	},
+
+	removeProp: function( name ) {
+		name = jQuery.propFix[ name ] || name;
+		return this.each(function() {
+			// try/catch handles cases where IE balks (such as removing a property on window)
+			try {
+				this[ name ] = undefined;
+				delete this[ name ];
+			} catch( e ) {}
+		});
+	},
+
+	addClass: function( value ) {
+		var classes, elem, cur, clazz, j,
+			i = 0,
+			len = this.length,
+			proceed = typeof value === "string" && value;
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function( j ) {
+				jQuery( this ).addClass( value.call( this, j, this.className ) );
+			});
+		}
+
+		if ( proceed ) {
+			// The disjunction here is for better compressibility (see removeClass)
+			classes = ( value || "" ).match( core_rnotwhite ) || [];
+
+			for ( ; i < len; i++ ) {
+				elem = this[ i ];
+				cur = elem.nodeType === 1 && ( elem.className ?
+					( " " + elem.className + " " ).replace( rclass, " " ) :
+					" "
+				);
+
+				if ( cur ) {
+					j = 0;
+					while ( (clazz = classes[j++]) ) {
+						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
+							cur += clazz + " ";
+						}
+					}
+					elem.className = jQuery.trim( cur );
+
+				}
+			}
+		}
+
+		return this;
+	},
+
+	removeClass: function( value ) {
+		var classes, elem, cur, clazz, j,
+			i = 0,
+			len = this.length,
+			proceed = arguments.length === 0 || typeof value === "string" && value;
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function( j ) {
+				jQuery( this ).removeClass( value.call( this, j, this.className ) );
+			});
+		}
+		if ( proceed ) {
+			classes = ( value || "" ).match( core_rnotwhite ) || [];
+
+			for ( ; i < len; i++ ) {
+				elem = this[ i ];
+				// This expression is here for better compressibility (see addClass)
+				cur = elem.nodeType === 1 && ( elem.className ?
+					( " " + elem.className + " " ).replace( rclass, " " ) :
+					""
+				);
+
+				if ( cur ) {
+					j = 0;
+					while ( (clazz = classes[j++]) ) {
+						// Remove *all* instances
+						while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
+							cur = cur.replace( " " + clazz + " ", " " );
+						}
+					}
+					elem.className = value ? jQuery.trim( cur ) : "";
+				}
+			}
+		}
+
+		return this;
+	},
+
+	toggleClass: function( value, stateVal ) {
+		var type = typeof value;
+
+		if ( typeof stateVal === "boolean" && type === "string" ) {
+			return stateVal ? this.addClass( value ) : this.removeClass( value );
+		}
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function( i ) {
+				jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
+			});
+		}
+
+		return this.each(function() {
+			if ( type === "string" ) {
+				// toggle individual class names
+				var className,
+					i = 0,
+					self = jQuery( this ),
+					classNames = value.match( core_rnotwhite ) || [];
+
+				while ( (className = classNames[ i++ ]) ) {
+					// check each className given, space separated list
+					if ( self.hasClass( className ) ) {
+						self.removeClass( className );
+					} else {
+						self.addClass( className );
+					}
+				}
+
+			// Toggle whole class name
+			} else if ( type === core_strundefined || type === "boolean" ) {
+				if ( this.className ) {
+					// store className if set
+					jQuery._data( this, "__className__", this.className );
+				}
+
+				// If the element has a class name or if we're passed "false",
+				// then remove the whole classname (if there was one, the above saved it).
+				// Otherwise bring back whatever was previously saved (if anything),
+				// falling back to the empty string if nothing was stored.
+				this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
+			}
+		});
+	},
+
+	hasClass: function( selector ) {
+		var className = " " + selector + " ",
+			i = 0,
+			l = this.length;
+		for ( ; i < l; i++ ) {
+			if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
+				return true;
+			}
+		}
+
+		return false;
+	},
+
+	val: function( value ) {
+		var ret, hooks, isFunction,
+			elem = this[0];
+
+		if ( !arguments.length ) {
+			if ( elem ) {
+				hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
+
+				if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
+					return ret;
+				}
+
+				ret = elem.value;
+
+				return typeof ret === "string" ?
+					// handle most common string cases
+					ret.replace(rreturn, "") :
+					// handle cases where value is null/undef or number
+					ret == null ? "" : ret;
+			}
+
+			return;
+		}
+
+		isFunction = jQuery.isFunction( value );
+
+		return this.each(function( i ) {
+			var val;
+
+			if ( this.nodeType !== 1 ) {
+				return;
+			}
+
+			if ( isFunction ) {
+				val = value.call( this, i, jQuery( this ).val() );
+			} else {
+				val = value;
+			}
+
+			// Treat null/undefined as ""; convert numbers to string
+			if ( val == null ) {
+				val = "";
+			} else if ( typeof val === "number" ) {
+				val += "";
+			} else if ( jQuery.isArray( val ) ) {
+				val = jQuery.map(val, function ( value ) {
+					return value == null ? "" : value + "";
+				});
+			}
+
+			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
+
+			// If set returns undefined, fall back to normal setting
+			if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
+				this.value = val;
+			}
+		});
+	}
+});
+
+jQuery.extend({
+	valHooks: {
+		option: {
+			get: function( elem ) {
+				// Use proper attribute retrieval(#6932, #12072)
+				var val = jQuery.find.attr( elem, "value" );
+				return val != null ?
+					val :
+					elem.text;
+			}
+		},
+		select: {
+			get: function( elem ) {
+				var value, option,
+					options = elem.options,
+					index = elem.selectedIndex,
+					one = elem.type === "select-one" || index < 0,
+					values = one ? null : [],
+					max = one ? index + 1 : options.length,
+					i = index < 0 ?
+						max :
+						one ? index : 0;
+
+				// Loop through all the selected options
+				for ( ; i < max; i++ ) {
+					option = options[ i ];
+
+					// oldIE doesn't update selected after form reset (#2551)
+					if ( ( option.selected || i === index ) &&
+							// Don't return options that are disabled or in a disabled optgroup
+							( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
+							( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
+
+						// Get the specific value for the option
+						value = jQuery( option ).val();
+
+						// We don't need an array for one selects
+						if ( one ) {
+							return value;
+						}
+
+						// Multi-Selects return an array
+						values.push( value );
+					}
+				}
+
+				return values;
+			},
+
+			set: function( elem, value ) {
+				var optionSet, option,
+					options = elem.options,
+					values = jQuery.makeArray( value ),
+					i = options.length;
+
+				while ( i-- ) {
+					option = options[ i ];
+					if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) {
+						optionSet = true;
+					}
+				}
+
+				// force browsers to behave consistently when non-matching value is set
+				if ( !optionSet ) {
+					elem.selectedIndex = -1;
+				}
+				return values;
+			}
+		}
+	},
+
+	attr: function( elem, name, value ) {
+		var hooks, ret,
+			nType = elem.nodeType;
+
+		// don't get/set attributes on text, comment and attribute nodes
+		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+			return;
+		}
+
+		// Fallback to prop when attributes are not supported
+		if ( typeof elem.getAttribute === core_strundefined ) {
+			return jQuery.prop( elem, name, value );
+		}
+
+		// All attributes are lowercase
+		// Grab necessary hook if one is defined
+		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
+			name = name.toLowerCase();
+			hooks = jQuery.attrHooks[ name ] ||
+				( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
+		}
+
+		if ( value !== undefined ) {
+
+			if ( value === null ) {
+				jQuery.removeAttr( elem, name );
+
+			} else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+				return ret;
+
+			} else {
+				elem.setAttribute( name, value + "" );
+				return value;
+			}
+
+		} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
+			return ret;
+
+		} else {
+			ret = jQuery.find.attr( elem, name );
+
+			// Non-existent attributes return null, we normalize to undefined
+			return ret == null ?
+				undefined :
+				ret;
+		}
+	},
+
+	removeAttr: function( elem, value ) {
+		var name, propName,
+			i = 0,
+			attrNames = value && value.match( core_rnotwhite );
+
+		if ( attrNames && elem.nodeType === 1 ) {
+			while ( (name = attrNames[i++]) ) {
+				propName = jQuery.propFix[ name ] || name;
+
+				// Boolean attributes get special treatment (#10870)
+				if ( jQuery.expr.match.bool.test( name ) ) {
+					// Set corresponding property to false
+					if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
+						elem[ propName ] = false;
+					// Support: IE<9
+					// Also clear defaultChecked/defaultSelected (if appropriate)
+					} else {
+						elem[ jQuery.camelCase( "default-" + name ) ] =
+							elem[ propName ] = false;
+					}
+
+				// See #9699 for explanation of this approach (setting first, then removal)
+				} else {
+					jQuery.attr( elem, name, "" );
+				}
+
+				elem.removeAttribute( getSetAttribute ? name : propName );
+			}
+		}
+	},
+
+	attrHooks: {
+		type: {
+			set: function( elem, value ) {
+				if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
+					// Setting the type on a radio button after the value resets the value in IE6-9
+					// Reset value to default in case type is set after value during creation
+					var val = elem.value;
+					elem.setAttribute( "type", value );
+					if ( val ) {
+						elem.value = val;
+					}
+					return value;
+				}
+			}
+		}
+	},
+
+	propFix: {
+		"for": "htmlFor",
+		"class": "className"
+	},
+
+	prop: function( elem, name, value ) {
+		var ret, hooks, notxml,
+			nType = elem.nodeType;
+
+		// don't get/set properties on text, comment and attribute nodes
+		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+			return;
+		}
+
+		notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+		if ( notxml ) {
+			// Fix name and attach hooks
+			name = jQuery.propFix[ name ] || name;
+			hooks = jQuery.propHooks[ name ];
+		}
+
+		if ( value !== undefined ) {
+			return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
+				ret :
+				( elem[ name ] = value );
+
+		} else {
+			return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
+				ret :
+				elem[ name ];
+		}
+	},
+
+	propHooks: {
+		tabIndex: {
+			get: function( elem ) {
+				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+				// Use proper attribute retrieval(#12072)
+				var tabindex = jQuery.find.attr( elem, "tabindex" );
+
+				return tabindex ?
+					parseInt( tabindex, 10 ) :
+					rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+						0 :
+						-1;
+			}
+		}
+	}
+});
+
+// Hooks for boolean attributes
+boolHook = {
+	set: function( elem, value, name ) {
+		if ( value === false ) {
+			// Remove boolean attributes when set to false
+			jQuery.removeAttr( elem, name );
+		} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
+			// IE<8 needs the *property* name
+			elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
+
+		// Use defaultChecked and defaultSelected for oldIE
+		} else {
+			elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
+		}
+
+		return name;
+	}
+};
+jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
+	var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr;
+
+	jQuery.expr.attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?
+		function( elem, name, isXML ) {
+			var fn = jQuery.expr.attrHandle[ name ],
+				ret = isXML ?
+					undefined :
+					/* jshint eqeqeq: false */
+					(jQuery.expr.attrHandle[ name ] = undefined) !=
+						getter( elem, name, isXML ) ?
+
+						name.toLowerCase() :
+						null;
+			jQuery.expr.attrHandle[ name ] = fn;
+			return ret;
+		} :
+		function( elem, name, isXML ) {
+			return isXML ?
+				undefined :
+				elem[ jQuery.camelCase( "default-" + name ) ] ?
+					name.toLowerCase() :
+					null;
+		};
+});
+
+// fix oldIE attroperties
+if ( !getSetInput || !getSetAttribute ) {
+	jQuery.attrHooks.value = {
+		set: function( elem, value, name ) {
+			if ( jQuery.nodeName( elem, "input" ) ) {
+				// Does not return so that setAttribute is also used
+				elem.defaultValue = value;
+			} else {
+				// Use nodeHook if defined (#1954); otherwise setAttribute is fine
+				return nodeHook && nodeHook.set( elem, value, name );
+			}
+		}
+	};
+}
+
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !getSetAttribute ) {
+
+	// Use this for any attribute in IE6/7
+	// This fixes almost every IE6/7 issue
+	nodeHook = {
+		set: function( elem, value, name ) {
+			// Set the existing or create a new attribute node
+			var ret = elem.getAttributeNode( name );
+			if ( !ret ) {
+				elem.setAttributeNode(
+					(ret = elem.ownerDocument.createAttribute( name ))
+				);
+			}
+
+			ret.value = value += "";
+
+			// Break association with cloned elements by also using setAttribute (#9646)
+			return name === "value" || value === elem.getAttribute( name ) ?
+				value :
+				undefined;
+		}
+	};
+	jQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords =
+		// Some attributes are constructed with empty-string values when not defined
+		function( elem, name, isXML ) {
+			var ret;
+			return isXML ?
+				undefined :
+				(ret = elem.getAttributeNode( name )) && ret.value !== "" ?
+					ret.value :
+					null;
+		};
+	jQuery.valHooks.button = {
+		get: function( elem, name ) {
+			var ret = elem.getAttributeNode( name );
+			return ret && ret.specified ?
+				ret.value :
+				undefined;
+		},
+		set: nodeHook.set
+	};
+
+	// Set contenteditable to false on removals(#10429)
+	// Setting to empty string throws an error as an invalid value
+	jQuery.attrHooks.contenteditable = {
+		set: function( elem, value, name ) {
+			nodeHook.set( elem, value === "" ? false : value, name );
+		}
+	};
+
+	// Set width and height to auto instead of 0 on empty string( Bug #8150 )
+	// This is for removals
+	jQuery.each([ "width", "height" ], function( i, name ) {
+		jQuery.attrHooks[ name ] = {
+			set: function( elem, value ) {
+				if ( value === "" ) {
+					elem.setAttribute( name, "auto" );
+					return value;
+				}
+			}
+		};
+	});
+}
+
+
+// Some attributes require a special call on IE
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !jQuery.support.hrefNormalized ) {
+	// href/src property should get the full normalized URL (#10299/#12915)
+	jQuery.each([ "href", "src" ], function( i, name ) {
+		jQuery.propHooks[ name ] = {
+			get: function( elem ) {
+				return elem.getAttribute( name, 4 );
+			}
+		};
+	});
+}
+
+if ( !jQuery.support.style ) {
+	jQuery.attrHooks.style = {
+		get: function( elem ) {
+			// Return undefined in the case of empty string
+			// Note: IE uppercases css property names, but if we were to .toLowerCase()
+			// .cssText, that would destroy case senstitivity in URL's, like in "background"
+			return elem.style.cssText || undefined;
+		},
+		set: function( elem, value ) {
+			return ( elem.style.cssText = value + "" );
+		}
+	};
+}
+
+// Safari mis-reports the default selected property of an option
+// Accessing the parent's selectedIndex property fixes it
+if ( !jQuery.support.optSelected ) {
+	jQuery.propHooks.selected = {
+		get: function( elem ) {
+			var parent = elem.parentNode;
+
+			if ( parent ) {
+				parent.selectedIndex;
+
+				// Make sure that it also works with optgroups, see #5701
+				if ( parent.parentNode ) {
+					parent.parentNode.selectedIndex;
+				}
+			}
+			return null;
+		}
+	};
+}
+
+jQuery.each([
+	"tabIndex",
+	"readOnly",
+	"maxLength",
+	"cellSpacing",
+	"cellPadding",
+	"rowSpan",
+	"colSpan",
+	"useMap",
+	"frameBorder",
+	"contentEditable"
+], function() {
+	jQuery.propFix[ this.toLowerCase() ] = this;
+});
+
+// IE6/7 call enctype encoding
+if ( !jQuery.support.enctype ) {
+	jQuery.propFix.enctype = "encoding";
+}
+
+// Radios and checkboxes getter/setter
+jQuery.each([ "radio", "checkbox" ], function() {
+	jQuery.valHooks[ this ] = {
+		set: function( elem, value ) {
+			if ( jQuery.isArray( value ) ) {
+				return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
+			}
+		}
+	};
+	if ( !jQuery.support.checkOn ) {
+		jQuery.valHooks[ this ].get = function( elem ) {
+			// Support: Webkit
+			// "" is returned instead of "on" if a value isn't specified
+			return elem.getAttribute("value") === null ? "on" : elem.value;
+		};
+	}
+});
+var rformElems = /^(?:input|select|textarea)$/i,
+	rkeyEvent = /^key/,
+	rmouseEvent = /^(?:mouse|contextmenu)|click/,
+	rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+	rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
+
+function returnTrue() {
+	return true;
+}
+
+function returnFalse() {
+	return false;
+}
+
+function safeActiveElement() {
+	try {
+		return document.activeElement;
+	} catch ( err ) { }
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+	global: {},
+
+	add: function( elem, types, handler, data, selector ) {
+		var tmp, events, t, handleObjIn,
+			special, eventHandle, handleObj,
+			handlers, type, namespaces, origType,
+			elemData = jQuery._data( elem );
+
+		// Don't attach events to noData or text/comment nodes (but allow plain objects)
+		if ( !elemData ) {
+			return;
+		}
+
+		// Caller can pass in an object of custom data in lieu of the handler
+		if ( handler.handler ) {
+			handleObjIn = handler;
+			handler = handleObjIn.handler;
+			selector = handleObjIn.selector;
+		}
+
+		// Make sure that the handler has a unique ID, used to find/remove it later
+		if ( !handler.guid ) {
+			handler.guid = jQuery.guid++;
+		}
+
+		// Init the element's event structure and main handler, if this is the first
+		if ( !(events = elemData.events) ) {
+			events = elemData.events = {};
+		}
+		if ( !(eventHandle = elemData.handle) ) {
+			eventHandle = elemData.handle = function( e ) {
+				// Discard the second event of a jQuery.event.trigger() and
+				// when an event is called after a page has unloaded
+				return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
+					jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
+					undefined;
+			};
+			// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
+			eventHandle.elem = elem;
+		}
+
+		// Handle multiple events separated by a space
+		types = ( types || "" ).match( core_rnotwhite ) || [""];
+		t = types.length;
+		while ( t-- ) {
+			tmp = rtypenamespace.exec( types[t] ) || [];
+			type = origType = tmp[1];
+			namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+			// There *must* be a type, no attaching namespace-only handlers
+			if ( !type ) {
+				continue;
+			}
+
+			// If event changes its type, use the special event handlers for the changed type
+			special = jQuery.event.special[ type ] || {};
+
+			// If selector defined, determine special event api type, otherwise given type
+			type = ( selector ? special.delegateType : special.bindType ) || type;
+
+			// Update special based on newly reset type
+			special = jQuery.event.special[ type ] || {};
+
+			// handleObj is passed to all event handlers
+			handleObj = jQuery.extend({
+				type: type,
+				origType: origType,
+				data: data,
+				handler: handler,
+				guid: handler.guid,
+				selector: selector,
+				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+				namespace: namespaces.join(".")
+			}, handleObjIn );
+
+			// Init the event handler queue if we're the first
+			if ( !(handlers = events[ type ]) ) {
+				handlers = events[ type ] = [];
+				handlers.delegateCount = 0;
+
+				// Only use addEventListener/attachEvent if the special events handler returns false
+				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+					// Bind the global event handler to the element
+					if ( elem.addEventListener ) {
+						elem.addEventListener( type, eventHandle, false );
+
+					} else if ( elem.attachEvent ) {
+						elem.attachEvent( "on" + type, eventHandle );
+					}
+				}
+			}
+
+			if ( special.add ) {
+				special.add.call( elem, handleObj );
+
+				if ( !handleObj.handler.guid ) {
+					handleObj.handler.guid = handler.guid;
+				}
+			}
+
+			// Add to the element's handler list, delegates in front
+			if ( selector ) {
+				handlers.splice( handlers.delegateCount++, 0, handleObj );
+			} else {
+				handlers.push( handleObj );
+			}
+
+			// Keep track of which events have ever been used, for event optimization
+			jQuery.event.global[ type ] = true;
+		}
+
+		// Nullify elem to prevent memory leaks in IE
+		elem = null;
+	},
+
+	// Detach an event or set of events from an element
+	remove: function( elem, types, handler, selector, mappedTypes ) {
+		var j, handleObj, tmp,
+			origCount, t, events,
+			special, handlers, type,
+			namespaces, origType,
+			elemData = jQuery.hasData( elem ) && jQuery._data( elem );
+
+		if ( !elemData || !(events = elemData.events) ) {
+			return;
+		}
+
+		// Once for each type.namespace in types; type may be omitted
+		types = ( types || "" ).match( core_rnotwhite ) || [""];
+		t = types.length;
+		while ( t-- ) {
+			tmp = rtypenamespace.exec( types[t] ) || [];
+			type = origType = tmp[1];
+			namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+			// Unbind all events (on this namespace, if provided) for the element
+			if ( !type ) {
+				for ( type in events ) {
+					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+				}
+				continue;
+			}
+
+			special = jQuery.event.special[ type ] || {};
+			type = ( selector ? special.delegateType : special.bindType ) || type;
+			handlers = events[ type ] || [];
+			tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
+
+			// Remove matching events
+			origCount = j = handlers.length;
+			while ( j-- ) {
+				handleObj = handlers[ j ];
+
+				if ( ( mappedTypes || origType === handleObj.origType ) &&
+					( !handler || handler.guid === handleObj.guid ) &&
+					( !tmp || tmp.test( handleObj.namespace ) ) &&
+					( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
+					handlers.splice( j, 1 );
+
+					if ( handleObj.selector ) {
+						handlers.delegateCount--;
+					}
+					if ( special.remove ) {
+						special.remove.call( elem, handleObj );
+					}
+				}
+			}
+
+			// Remove generic event handler if we removed something and no more handlers exist
+			// (avoids potential for endless recursion during removal of special event handlers)
+			if ( origCount && !handlers.length ) {
+				if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+					jQuery.removeEvent( elem, type, elemData.handle );
+				}
+
+				delete events[ type ];
+			}
+		}
+
+		// Remove the expando if it's no longer used
+		if ( jQuery.isEmptyObject( events ) ) {
+			delete elemData.handle;
+
+			// removeData also checks for emptiness and clears the expando if empty
+			// so use it instead of delete
+			jQuery._removeData( elem, "events" );
+		}
+	},
+
+	trigger: function( event, data, elem, onlyHandlers ) {
+		var handle, ontype, cur,
+			bubbleType, special, tmp, i,
+			eventPath = [ elem || document ],
+			type = core_hasOwn.call( event, "type" ) ? event.type : event,
+			namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
+
+		cur = tmp = elem = elem || document;
+
+		// Don't do events on text and comment nodes
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return;
+		}
+
+		// focus/blur morphs to focusin/out; ensure we're not firing them right now
+		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
+			return;
+		}
+
+		if ( type.indexOf(".") >= 0 ) {
+			// Namespaced trigger; create a regexp to match event type in handle()
+			namespaces = type.split(".");
+			type = namespaces.shift();
+			namespaces.sort();
+		}
+		ontype = type.indexOf(":") < 0 && "on" + type;
+
+		// Caller can pass in a jQuery.Event object, Object, or just an event type string
+		event = event[ jQuery.expando ] ?
+			event :
+			new jQuery.Event( type, typeof event === "object" && event );
+
+		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
+		event.isTrigger = onlyHandlers ? 2 : 3;
+		event.namespace = namespaces.join(".");
+		event.namespace_re = event.namespace ?
+			new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
+			null;
+
+		// Clean up the event in case it is being reused
+		event.result = undefined;
+		if ( !event.target ) {
+			event.target = elem;
+		}
+
+		// Clone any incoming data and prepend the event, creating the handler arg list
+		data = data == null ?
+			[ event ] :
+			jQuery.makeArray( data, [ event ] );
+
+		// Allow special events to draw outside the lines
+		special = jQuery.event.special[ type ] || {};
+		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
+			return;
+		}
+
+		// Determine event propagation path in advance, per W3C events spec (#9951)
+		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
+		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
+
+			bubbleType = special.delegateType || type;
+			if ( !rfocusMorph.test( bubbleType + type ) ) {
+				cur = cur.parentNode;
+			}
+			for ( ; cur; cur = cur.parentNode ) {
+				eventPath.push( cur );
+				tmp = cur;
+			}
+
+			// Only add window if we got to document (e.g., not plain obj or detached DOM)
+			if ( tmp === (elem.ownerDocument || document) ) {
+				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
+			}
+		}
+
+		// Fire handlers on the event path
+		i = 0;
+		while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
+
+			event.type = i > 1 ?
+				bubbleType :
+				special.bindType || type;
+
+			// jQuery handler
+			handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
+			if ( handle ) {
+				handle.apply( cur, data );
+			}
+
+			// Native handler
+			handle = ontype && cur[ ontype ];
+			if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
+				event.preventDefault();
+			}
+		}
+		event.type = type;
+
+		// If nobody prevented the default action, do it now
+		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
+
+			if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
+				jQuery.acceptData( elem ) ) {
+
+				// Call a native DOM method on the target with the same name name as the event.
+				// Can't use an .isFunction() check here because IE6/7 fails that test.
+				// Don't do default actions on window, that's where global variables be (#6170)
+				if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
+
+					// Don't re-trigger an onFOO event when we call its FOO() method
+					tmp = elem[ ontype ];
+
+					if ( tmp ) {
+						elem[ ontype ] = null;
+					}
+
+					// Prevent re-triggering of the same event, since we already bubbled it above
+					jQuery.event.triggered = type;
+					try {
+						elem[ type ]();
+					} catch ( e ) {
+						// IE<9 dies on focus/blur to hidden element (#1486,#12518)
+						// only reproducible on winXP IE8 native, not IE9 in IE8 mode
+					}
+					jQuery.event.triggered = undefined;
+
+					if ( tmp ) {
+						elem[ ontype ] = tmp;
+					}
+				}
+			}
+		}
+
+		return event.result;
+	},
+
+	dispatch: function( event ) {
+
+		// Make a writable jQuery.Event from the native event object
+		event = jQuery.event.fix( event );
+
+		var i, ret, handleObj, matched, j,
+			handlerQueue = [],
+			args = core_slice.call( arguments ),
+			handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
+			special = jQuery.event.special[ event.type ] || {};
+
+		// Use the fix-ed jQuery.Event rather than the (read-only) native event
+		args[0] = event;
+		event.delegateTarget = this;
+
+		// Call the preDispatch hook for the mapped type, and let it bail if desired
+		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+			return;
+		}
+
+		// Determine handlers
+		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+		// Run delegates first; they may want to stop propagation beneath us
+		i = 0;
+		while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
+			event.currentTarget = matched.elem;
+
+			j = 0;
+			while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
+
+				// Triggered event must either 1) have no namespace, or
+				// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
+				if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
+
+					event.handleObj = handleObj;
+					event.data = handleObj.data;
+
+					ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
+							.apply( matched.elem, args );
+
+					if ( ret !== undefined ) {
+						if ( (event.result = ret) === false ) {
+							event.preventDefault();
+							event.stopPropagation();
+						}
+					}
+				}
+			}
+		}
+
+		// Call the postDispatch hook for the mapped type
+		if ( special.postDispatch ) {
+			special.postDispatch.call( this, event );
+		}
+
+		return event.result;
+	},
+
+	handlers: function( event, handlers ) {
+		var sel, handleObj, matches, i,
+			handlerQueue = [],
+			delegateCount = handlers.delegateCount,
+			cur = event.target;
+
+		// Find delegate handlers
+		// Black-hole SVG <use> instance trees (#13180)
+		// Avoid non-left-click bubbling in Firefox (#3861)
+		if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
+
+			/* jshint eqeqeq: false */
+			for ( ; cur != this; cur = cur.parentNode || this ) {
+				/* jshint eqeqeq: true */
+
+				// Don't check non-elements (#13208)
+				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+				if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
+					matches = [];
+					for ( i = 0; i < delegateCount; i++ ) {
+						handleObj = handlers[ i ];
+
+						// Don't conflict with Object.prototype properties (#13203)
+						sel = handleObj.selector + " ";
+
+						if ( matches[ sel ] === undefined ) {
+							matches[ sel ] = handleObj.needsContext ?
+								jQuery( sel, this ).index( cur ) >= 0 :
+								jQuery.find( sel, this, null, [ cur ] ).length;
+						}
+						if ( matches[ sel ] ) {
+							matches.push( handleObj );
+						}
+					}
+					if ( matches.length ) {
+						handlerQueue.push({ elem: cur, handlers: matches });
+					}
+				}
+			}
+		}
+
+		// Add the remaining (directly-bound) handlers
+		if ( delegateCount < handlers.length ) {
+			handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
+		}
+
+		return handlerQueue;
+	},
+
+	fix: function( event ) {
+		if ( event[ jQuery.expando ] ) {
+			return event;
+		}
+
+		// Create a writable copy of the event object and normalize some properties
+		var i, prop, copy,
+			type = event.type,
+			originalEvent = event,
+			fixHook = this.fixHooks[ type ];
+
+		if ( !fixHook ) {
+			this.fixHooks[ type ] = fixHook =
+				rmouseEvent.test( type ) ? this.mouseHooks :
+				rkeyEvent.test( type ) ? this.keyHooks :
+				{};
+		}
+		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
+
+		event = new jQuery.Event( originalEvent );
+
+		i = copy.length;
+		while ( i-- ) {
+			prop = copy[ i ];
+			event[ prop ] = originalEvent[ prop ];
+		}
+
+		// Support: IE<9
+		// Fix target property (#1925)
+		if ( !event.target ) {
+			event.target = originalEvent.srcElement || document;
+		}
+
+		// Support: Chrome 23+, Safari?
+		// Target should not be a text node (#504, #13143)
+		if ( event.target.nodeType === 3 ) {
+			event.target = event.target.parentNode;
+		}
+
+		// Support: IE<9
+		// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
+		event.metaKey = !!event.metaKey;
+
+		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
+	},
+
+	// Includes some event props shared by KeyEvent and MouseEvent
+	props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
+
+	fixHooks: {},
+
+	keyHooks: {
+		props: "char charCode key keyCode".split(" "),
+		filter: function( event, original ) {
+
+			// Add which for key events
+			if ( event.which == null ) {
+				event.which = original.charCode != null ? original.charCode : original.keyCode;
+			}
+
+			return event;
+		}
+	},
+
+	mouseHooks: {
+		props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
+		filter: function( event, original ) {
+			var body, eventDoc, doc,
+				button = original.button,
+				fromElement = original.fromElement;
+
+			// Calculate pageX/Y if missing and clientX/Y available
+			if ( event.pageX == null && original.clientX != null ) {
+				eventDoc = event.target.ownerDocument || document;
+				doc = eventDoc.documentElement;
+				body = eventDoc.body;
+
+				event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
+				event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
+			}
+
+			// Add relatedTarget, if necessary
+			if ( !event.relatedTarget && fromElement ) {
+				event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
+			}
+
+			// Add which for click: 1 === left; 2 === middle; 3 === right
+			// Note: button is not normalized, so don't use it
+			if ( !event.which && button !== undefined ) {
+				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
+			}
+
+			return event;
+		}
+	},
+
+	special: {
+		load: {
+			// Prevent triggered image.load events from bubbling to window.load
+			noBubble: true
+		},
+		focus: {
+			// Fire native event if possible so blur/focus sequence is correct
+			trigger: function() {
+				if ( this !== safeActiveElement() && this.focus ) {
+					try {
+						this.focus();
+						return false;
+					} catch ( e ) {
+						// Support: IE<9
+						// If we error on focus to hidden element (#1486, #12518),
+						// let .trigger() run the handlers
+					}
+				}
+			},
+			delegateType: "focusin"
+		},
+		blur: {
+			trigger: function() {
+				if ( this === safeActiveElement() && this.blur ) {
+					this.blur();
+					return false;
+				}
+			},
+			delegateType: "focusout"
+		},
+		click: {
+			// For checkbox, fire native event so checked state will be right
+			trigger: function() {
+				if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
+					this.click();
+					return false;
+				}
+			},
+
+			// For cross-browser consistency, don't fire native .click() on links
+			_default: function( event ) {
+				return jQuery.nodeName( event.target, "a" );
+			}
+		},
+
+		beforeunload: {
+			postDispatch: function( event ) {
+
+				// Even when returnValue equals to undefined Firefox will still show alert
+				if ( event.result !== undefined ) {
+					event.originalEvent.returnValue = event.result;
+				}
+			}
+		}
+	},
+
+	simulate: function( type, elem, event, bubble ) {
+		// Piggyback on a donor event to simulate a different one.
+		// Fake originalEvent to avoid donor's stopPropagation, but if the
+		// simulated event prevents default then we do the same on the donor.
+		var e = jQuery.extend(
+			new jQuery.Event(),
+			event,
+			{
+				type: type,
+				isSimulated: true,
+				originalEvent: {}
+			}
+		);
+		if ( bubble ) {
+			jQuery.event.trigger( e, null, elem );
+		} else {
+			jQuery.event.dispatch.call( elem, e );
+		}
+		if ( e.isDefaultPrevented() ) {
+			event.preventDefault();
+		}
+	}
+};
+
+jQuery.removeEvent = document.removeEventListener ?
+	function( elem, type, handle ) {
+		if ( elem.removeEventListener ) {
+			elem.removeEventListener( type, handle, false );
+		}
+	} :
+	function( elem, type, handle ) {
+		var name = "on" + type;
+
+		if ( elem.detachEvent ) {
+
+			// #8545, #7054, preventing memory leaks for custom events in IE6-8
+			// detachEvent needed property on element, by name of that event, to properly expose it to GC
+			if ( typeof elem[ name ] === core_strundefined ) {
+				elem[ name ] = null;
+			}
+
+			elem.detachEvent( name, handle );
+		}
+	};
+
+jQuery.Event = function( src, props ) {
+	// Allow instantiation without the 'new' keyword
+	if ( !(this instanceof jQuery.Event) ) {
+		return new jQuery.Event( src, props );
+	}
+
+	// Event object
+	if ( src && src.type ) {
+		this.originalEvent = src;
+		this.type = src.type;
+
+		// Events bubbling up the document may have been marked as prevented
+		// by a handler lower down the tree; reflect the correct value.
+		this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
+			src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
+
+	// Event type
+	} else {
+		this.type = src;
+	}
+
+	// Put explicitly provided properties onto the event object
+	if ( props ) {
+		jQuery.extend( this, props );
+	}
+
+	// Create a timestamp if incoming event doesn't have one
+	this.timeStamp = src && src.timeStamp || jQuery.now();
+
+	// Mark it as fixed
+	this[ jQuery.expando ] = true;
+};
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+	isDefaultPrevented: returnFalse,
+	isPropagationStopped: returnFalse,
+	isImmediatePropagationStopped: returnFalse,
+
+	preventDefault: function() {
+		var e = this.originalEvent;
+
+		this.isDefaultPrevented = returnTrue;
+		if ( !e ) {
+			return;
+		}
+
+		// If preventDefault exists, run it on the original event
+		if ( e.preventDefault ) {
+			e.preventDefault();
+
+		// Support: IE
+		// Otherwise set the returnValue property of the original event to false
+		} else {
+			e.returnValue = false;
+		}
+	},
+	stopPropagation: function() {
+		var e = this.originalEvent;
+
+		this.isPropagationStopped = returnTrue;
+		if ( !e ) {
+			return;
+		}
+		// If stopPropagation exists, run it on the original event
+		if ( e.stopPropagation ) {
+			e.stopPropagation();
+		}
+
+		// Support: IE
+		// Set the cancelBubble property of the original event to true
+		e.cancelBubble = true;
+	},
+	stopImmediatePropagation: function() {
+		this.isImmediatePropagationStopped = returnTrue;
+		this.stopPropagation();
+	}
+};
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+jQuery.each({
+	mouseenter: "mouseover",
+	mouseleave: "mouseout"
+}, function( orig, fix ) {
+	jQuery.event.special[ orig ] = {
+		delegateType: fix,
+		bindType: fix,
+
+		handle: function( event ) {
+			var ret,
+				target = this,
+				related = event.relatedTarget,
+				handleObj = event.handleObj;
+
+			// For mousenter/leave call the handler if related is outside the target.
+			// NB: No relatedTarget if the mouse left/entered the browser window
+			if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
+				event.type = handleObj.origType;
+				ret = handleObj.handler.apply( this, arguments );
+				event.type = fix;
+			}
+			return ret;
+		}
+	};
+});
+
+// IE submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+	jQuery.event.special.submit = {
+		setup: function() {
+			// Only need this for delegated form submit events
+			if ( jQuery.nodeName( this, "form" ) ) {
+				return false;
+			}
+
+			// Lazy-add a submit handler when a descendant form may potentially be submitted
+			jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
+				// Node name check avoids a VML-related crash in IE (#9807)
+				var elem = e.target,
+					form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
+				if ( form && !jQuery._data( form, "submitBubbles" ) ) {
+					jQuery.event.add( form, "submit._submit", function( event ) {
+						event._submit_bubble = true;
+					});
+					jQuery._data( form, "submitBubbles", true );
+				}
+			});
+			// return undefined since we don't need an event listener
+		},
+
+		postDispatch: function( event ) {
+			// If form was submitted by the user, bubble the event up the tree
+			if ( event._submit_bubble ) {
+				delete event._submit_bubble;
+				if ( this.parentNode && !event.isTrigger ) {
+					jQuery.event.simulate( "submit", this.parentNode, event, true );
+				}
+			}
+		},
+
+		teardown: function() {
+			// Only need this for delegated form submit events
+			if ( jQuery.nodeName( this, "form" ) ) {
+				return false;
+			}
+
+			// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
+			jQuery.event.remove( this, "._submit" );
+		}
+	};
+}
+
+// IE change delegation and checkbox/radio fix
+if ( !jQuery.support.changeBubbles ) {
+
+	jQuery.event.special.change = {
+
+		setup: function() {
+
+			if ( rformElems.test( this.nodeName ) ) {
+				// IE doesn't fire change on a check/radio until blur; trigger it on click
+				// after a propertychange. Eat the blur-change in special.change.handle.
+				// This still fires onchange a second time for check/radio after blur.
+				if ( this.type === "checkbox" || this.type === "radio" ) {
+					jQuery.event.add( this, "propertychange._change", function( event ) {
+						if ( event.originalEvent.propertyName === "checked" ) {
+							this._just_changed = true;
+						}
+					});
+					jQuery.event.add( this, "click._change", function( event ) {
+						if ( this._just_changed && !event.isTrigger ) {
+							this._just_changed = false;
+						}
+						// Allow triggered, simulated change events (#11500)
+						jQuery.event.simulate( "change", this, event, true );
+					});
+				}
+				return false;
+			}
+			// Delegated event; lazy-add a change handler on descendant inputs
+			jQuery.event.add( this, "beforeactivate._change", function( e ) {
+				var elem = e.target;
+
+				if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
+					jQuery.event.add( elem, "change._change", function( event ) {
+						if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
+							jQuery.event.simulate( "change", this.parentNode, event, true );
+						}
+					});
+					jQuery._data( elem, "changeBubbles", true );
+				}
+			});
+		},
+
+		handle: function( event ) {
+			var elem = event.target;
+
+			// Swallow native change events from checkbox/radio, we already triggered them above
+			if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
+				return event.handleObj.handler.apply( this, arguments );
+			}
+		},
+
+		teardown: function() {
+			jQuery.event.remove( this, "._change" );
+
+			return !rformElems.test( this.nodeName );
+		}
+	};
+}
+
+// Create "bubbling" focus and blur events
+if ( !jQuery.support.focusinBubbles ) {
+	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+		// Attach a single capturing handler while someone wants focusin/focusout
+		var attaches = 0,
+			handler = function( event ) {
+				jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
+			};
+
+		jQuery.event.special[ fix ] = {
+			setup: function() {
+				if ( attaches++ === 0 ) {
+					document.addEventListener( orig, handler, true );
+				}
+			},
+			teardown: function() {
+				if ( --attaches === 0 ) {
+					document.removeEventListener( orig, handler, true );
+				}
+			}
+		};
+	});
+}
+
+jQuery.fn.extend({
+
+	on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
+		var type, origFn;
+
+		// Types can be a map of types/handlers
+		if ( typeof types === "object" ) {
+			// ( types-Object, selector, data )
+			if ( typeof selector !== "string" ) {
+				// ( types-Object, data )
+				data = data || selector;
+				selector = undefined;
+			}
+			for ( type in types ) {
+				this.on( type, selector, data, types[ type ], one );
+			}
+			return this;
+		}
+
+		if ( data == null && fn == null ) {
+			// ( types, fn )
+			fn = selector;
+			data = selector = undefined;
+		} else if ( fn == null ) {
+			if ( typeof selector === "string" ) {
+				// ( types, selector, fn )
+				fn = data;
+				data = undefined;
+			} else {
+				// ( types, data, fn )
+				fn = data;
+				data = selector;
+				selector = undefined;
+			}
+		}
+		if ( fn === false ) {
+			fn = returnFalse;
+		} else if ( !fn ) {
+			return this;
+		}
+
+		if ( one === 1 ) {
+			origFn = fn;
+			fn = function( event ) {
+				// Can use an empty set, since event contains the info
+				jQuery().off( event );
+				return origFn.apply( this, arguments );
+			};
+			// Use same guid so caller can remove using origFn
+			fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+		}
+		return this.each( function() {
+			jQuery.event.add( this, types, fn, data, selector );
+		});
+	},
+	one: function( types, selector, data, fn ) {
+		return this.on( types, selector, data, fn, 1 );
+	},
+	off: function( types, selector, fn ) {
+		var handleObj, type;
+		if ( types && types.preventDefault && types.handleObj ) {
+			// ( event )  dispatched jQuery.Event
+			handleObj = types.handleObj;
+			jQuery( types.delegateTarget ).off(
+				handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
+				handleObj.selector,
+				handleObj.handler
+			);
+			return this;
+		}
+		if ( typeof types === "object" ) {
+			// ( types-object [, selector] )
+			for ( type in types ) {
+				this.off( type, selector, types[ type ] );
+			}
+			return this;
+		}
+		if ( selector === false || typeof selector === "function" ) {
+			// ( types [, fn] )
+			fn = selector;
+			selector = undefined;
+		}
+		if ( fn === false ) {
+			fn = returnFalse;
+		}
+		return this.each(function() {
+			jQuery.event.remove( this, types, fn, selector );
+		});
+	},
+
+	trigger: function( type, data ) {
+		return this.each(function() {
+			jQuery.event.trigger( type, data, this );
+		});
+	},
+	triggerHandler: function( type, data ) {
+		var elem = this[0];
+		if ( elem ) {
+			return jQuery.event.trigger( type, data, elem, true );
+		}
+	}
+});
+var isSimple = /^.[^:#\[\.,]*$/,
+	rparentsprev = /^(?:parents|prev(?:Until|All))/,
+	rneedsContext = jQuery.expr.match.needsContext,
+	// methods guaranteed to produce a unique set when starting from a unique set
+	guaranteedUnique = {
+		children: true,
+		contents: true,
+		next: true,
+		prev: true
+	};
+
+jQuery.fn.extend({
+	find: function( selector ) {
+		var i,
+			ret = [],
+			self = this,
+			len = self.length;
+
+		if ( typeof selector !== "string" ) {
+			return this.pushStack( jQuery( selector ).filter(function() {
+				for ( i = 0; i < len; i++ ) {
+					if ( jQuery.contains( self[ i ], this ) ) {
+						return true;
+					}
+				}
+			}) );
+		}
+
+		for ( i = 0; i < len; i++ ) {
+			jQuery.find( selector, self[ i ], ret );
+		}
+
+		// Needed because $( selector, context ) becomes $( context ).find( selector )
+		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
+		ret.selector = this.selector ? this.selector + " " + selector : selector;
+		return ret;
+	},
+
+	has: function( target ) {
+		var i,
+			targets = jQuery( target, this ),
+			len = targets.length;
+
+		return this.filter(function() {
+			for ( i = 0; i < len; i++ ) {
+				if ( jQuery.contains( this, targets[i] ) ) {
+					return true;
+				}
+			}
+		});
+	},
+
+	not: function( selector ) {
+		return this.pushStack( winnow(this, selector || [], true) );
+	},
+
+	filter: function( selector ) {
+		return this.pushStack( winnow(this, selector || [], false) );
+	},
+
+	is: function( selector ) {
+		return !!winnow(
+			this,
+
+			// If this is a positional/relative selector, check membership in the returned set
+			// so $("p:first").is("p:last") won't return true for a doc with two "p".
+			typeof selector === "string" && rneedsContext.test( selector ) ?
+				jQuery( selector ) :
+				selector || [],
+			false
+		).length;
+	},
+
+	closest: function( selectors, context ) {
+		var cur,
+			i = 0,
+			l = this.length,
+			ret = [],
+			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
+				jQuery( selectors, context || this.context ) :
+				0;
+
+		for ( ; i < l; i++ ) {
+			for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
+				// Always skip document fragments
+				if ( cur.nodeType < 11 && (pos ?
+					pos.index(cur) > -1 :
+
+					// Don't pass non-elements to Sizzle
+					cur.nodeType === 1 &&
+						jQuery.find.matchesSelector(cur, selectors)) ) {
+
+					cur = ret.push( cur );
+					break;
+				}
+			}
+		}
+
+		return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret );
+	},
+
+	// Determine the position of an element within
+	// the matched set of elements
+	index: function( elem ) {
+
+		// No argument, return index in parent
+		if ( !elem ) {
+			return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
+		}
+
+		// index in selector
+		if ( typeof elem === "string" ) {
+			return jQuery.inArray( this[0], jQuery( elem ) );
+		}
+
+		// Locate the position of the desired element
+		return jQuery.inArray(
+			// If it receives a jQuery object, the first element is used
+			elem.jquery ? elem[0] : elem, this );
+	},
+
+	add: function( selector, context ) {
+		var set = typeof selector === "string" ?
+				jQuery( selector, context ) :
+				jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
+			all = jQuery.merge( this.get(), set );
+
+		return this.pushStack( jQuery.unique(all) );
+	},
+
+	addBack: function( selector ) {
+		return this.add( selector == null ?
+			this.prevObject : this.prevObject.filter(selector)
+		);
+	}
+});
+
+function sibling( cur, dir ) {
+	do {
+		cur = cur[ dir ];
+	} while ( cur && cur.nodeType !== 1 );
+
+	return cur;
+}
+
+jQuery.each({
+	parent: function( elem ) {
+		var parent = elem.parentNode;
+		return parent && parent.nodeType !== 11 ? parent : null;
+	},
+	parents: function( elem ) {
+		return jQuery.dir( elem, "parentNode" );
+	},
+	parentsUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "parentNode", until );
+	},
+	next: function( elem ) {
+		return sibling( elem, "nextSibling" );
+	},
+	prev: function( elem ) {
+		return sibling( elem, "previousSibling" );
+	},
+	nextAll: function( elem ) {
+		return jQuery.dir( elem, "nextSibling" );
+	},
+	prevAll: function( elem ) {
+		return jQuery.dir( elem, "previousSibling" );
+	},
+	nextUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "nextSibling", until );
+	},
+	prevUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "previousSibling", until );
+	},
+	siblings: function( elem ) {
+		return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
+	},
+	children: function( elem ) {
+		return jQuery.sibling( elem.firstChild );
+	},
+	contents: function( elem ) {
+		return jQuery.nodeName( elem, "iframe" ) ?
+			elem.contentDocument || elem.contentWindow.document :
+			jQuery.merge( [], elem.childNodes );
+	}
+}, function( name, fn ) {
+	jQuery.fn[ name ] = function( until, selector ) {
+		var ret = jQuery.map( this, fn, until );
+
+		if ( name.slice( -5 ) !== "Until" ) {
+			selector = until;
+		}
+
+		if ( selector && typeof selector === "string" ) {
+			ret = jQuery.filter( selector, ret );
+		}
+
+		if ( this.length > 1 ) {
+			// Remove duplicates
+			if ( !guaranteedUnique[ name ] ) {
+				ret = jQuery.unique( ret );
+			}
+
+			// Reverse order for parents* and prev-derivatives
+			if ( rparentsprev.test( name ) ) {
+				ret = ret.reverse();
+			}
+		}
+
+		return this.pushStack( ret );
+	};
+});
+
+jQuery.extend({
+	filter: function( expr, elems, not ) {
+		var elem = elems[ 0 ];
+
+		if ( not ) {
+			expr = ":not(" + expr + ")";
+		}
+
+		return elems.length === 1 && elem.nodeType === 1 ?
+			jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
+			jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+				return elem.nodeType === 1;
+			}));
+	},
+
+	dir: function( elem, dir, until ) {
+		var matched = [],
+			cur = elem[ dir ];
+
+		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+			if ( cur.nodeType === 1 ) {
+				matched.push( cur );
+			}
+			cur = cur[dir];
+		}
+		return matched;
+	},
+
+	sibling: function( n, elem ) {
+		var r = [];
+
+		for ( ; n; n = n.nextSibling ) {
+			if ( n.nodeType === 1 && n !== elem ) {
+				r.push( n );
+			}
+		}
+
+		return r;
+	}
+});
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, not ) {
+	if ( jQuery.isFunction( qualifier ) ) {
+		return jQuery.grep( elements, function( elem, i ) {
+			/* jshint -W018 */
+			return !!qualifier.call( elem, i, elem ) !== not;
+		});
+
+	}
+
+	if ( qualifier.nodeType ) {
+		return jQuery.grep( elements, function( elem ) {
+			return ( elem === qualifier ) !== not;
+		});
+
+	}
+
+	if ( typeof qualifier === "string" ) {
+		if ( isSimple.test( qualifier ) ) {
+			return jQuery.filter( qualifier, elements, not );
+		}
+
+		qualifier = jQuery.filter( qualifier, elements );
+	}
+
+	return jQuery.grep( elements, function( elem ) {
+		return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
+	});
+}
+function createSafeFragment( document ) {
+	var list = nodeNames.split( "|" ),
+		safeFrag = document.createDocumentFragment();
+
+	if ( safeFrag.createElement ) {
+		while ( list.length ) {
+			safeFrag.createElement(
+				list.pop()
+			);
+		}
+	}
+	return safeFrag;
+}
+
+var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
+		"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
+	rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
+	rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
+	rleadingWhitespace = /^\s+/,
+	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
+	rtagName = /<([\w:]+)/,
+	rtbody = /<tbody/i,
+	rhtml = /<|&#?\w+;/,
+	rnoInnerhtml = /<(?:script|style|link)/i,
+	manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
+	// checked="checked" or checked
+	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+	rscriptType = /^$|\/(?:java|ecma)script/i,
+	rscriptTypeMasked = /^true\/(.*)/,
+	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
+
+	// We have to close these tags to support XHTML (#13200)
+	wrapMap = {
+		option: [ 1, "<select multiple='multiple'>", "</select>" ],
+		legend: [ 1, "<fieldset>", "</fieldset>" ],
+		area: [ 1, "<map>", "</map>" ],
+		param: [ 1, "<object>", "</object>" ],
+		thead: [ 1, "<table>", "</table>" ],
+		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+
+		// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
+		// unless wrapped in a div with non-breaking characters in front of it.
+		_default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>"  ]
+	},
+	safeFragment = createSafeFragment( document ),
+	fragmentDiv = safeFragment.appendChild( document.createElement("div") );
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+jQuery.fn.extend({
+	text: function( value ) {
+		return jQuery.access( this, function( value ) {
+			return value === undefined ?
+				jQuery.text( this ) :
+				this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
+		}, null, value, arguments.length );
+	},
+
+	append: function() {
+		return this.domManip( arguments, function( elem ) {
+			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+				var target = manipulationTarget( this, elem );
+				target.appendChild( elem );
+			}
+		});
+	},
+
+	prepend: function() {
+		return this.domManip( arguments, function( elem ) {
+			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+				var target = manipulationTarget( this, elem );
+				target.insertBefore( elem, target.firstChild );
+			}
+		});
+	},
+
+	before: function() {
+		return this.domManip( arguments, function( elem ) {
+			if ( this.parentNode ) {
+				this.parentNode.insertBefore( elem, this );
+			}
+		});
+	},
+
+	after: function() {
+		return this.domManip( arguments, function( elem ) {
+			if ( this.parentNode ) {
+				this.parentNode.insertBefore( elem, this.nextSibling );
+			}
+		});
+	},
+
+	// keepData is for internal use only--do not document
+	remove: function( selector, keepData ) {
+		var elem,
+			elems = selector ? jQuery.filter( selector, this ) : this,
+			i = 0;
+
+		for ( ; (elem = elems[i]) != null; i++ ) {
+
+			if ( !keepData && elem.nodeType === 1 ) {
+				jQuery.cleanData( getAll( elem ) );
+			}
+
+			if ( elem.parentNode ) {
+				if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
+					setGlobalEval( getAll( elem, "script" ) );
+				}
+				elem.parentNode.removeChild( elem );
+			}
+		}
+
+		return this;
+	},
+
+	empty: function() {
+		var elem,
+			i = 0;
+
+		for ( ; (elem = this[i]) != null; i++ ) {
+			// Remove element nodes and prevent memory leaks
+			if ( elem.nodeType === 1 ) {
+				jQuery.cleanData( getAll( elem, false ) );
+			}
+
+			// Remove any remaining nodes
+			while ( elem.firstChild ) {
+				elem.removeChild( elem.firstChild );
+			}
+
+			// If this is a select, ensure that it displays empty (#12336)
+			// Support: IE<9
+			if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
+				elem.options.length = 0;
+			}
+		}
+
+		return this;
+	},
+
+	clone: function( dataAndEvents, deepDataAndEvents ) {
+		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+		return this.map( function () {
+			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+		});
+	},
+
+	html: function( value ) {
+		return jQuery.access( this, function( value ) {
+			var elem = this[0] || {},
+				i = 0,
+				l = this.length;
+
+			if ( value === undefined ) {
+				return elem.nodeType === 1 ?
+					elem.innerHTML.replace( rinlinejQuery, "" ) :
+					undefined;
+			}
+
+			// See if we can take a shortcut and just use innerHTML
+			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
+				( jQuery.support.htmlSerialize || !rnoshimcache.test( value )  ) &&
+				( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
+				!wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
+
+				value = value.replace( rxhtmlTag, "<$1></$2>" );
+
+				try {
+					for (; i < l; i++ ) {
+						// Remove element nodes and prevent memory leaks
+						elem = this[i] || {};
+						if ( elem.nodeType === 1 ) {
+							jQuery.cleanData( getAll( elem, false ) );
+							elem.innerHTML = value;
+						}
+					}
+
+					elem = 0;
+
+				// If using innerHTML throws an exception, use the fallback method
+				} catch(e) {}
+			}
+
+			if ( elem ) {
+				this.empty().append( value );
+			}
+		}, null, value, arguments.length );
+	},
+
+	replaceWith: function() {
+		var
+			// Snapshot the DOM in case .domManip sweeps something relevant into its fragment
+			args = jQuery.map( this, function( elem ) {
+				return [ elem.nextSibling, elem.parentNode ];
+			}),
+			i = 0;
+
+		// Make the changes, replacing each context element with the new content
+		this.domManip( arguments, function( elem ) {
+			var next = args[ i++ ],
+				parent = args[ i++ ];
+
+			if ( parent ) {
+				// Don't use the snapshot next if it has moved (#13810)
+				if ( next && next.parentNode !== parent ) {
+					next = this.nextSibling;
+				}
+				jQuery( this ).remove();
+				parent.insertBefore( elem, next );
+			}
+		// Allow new content to include elements from the context set
+		}, true );
+
+		// Force removal if there was no new content (e.g., from empty arguments)
+		return i ? this : this.remove();
+	},
+
+	detach: function( selector ) {
+		return this.remove( selector, true );
+	},
+
+	domManip: function( args, callback, allowIntersection ) {
+
+		// Flatten any nested arrays
+		args = core_concat.apply( [], args );
+
+		var first, node, hasScripts,
+			scripts, doc, fragment,
+			i = 0,
+			l = this.length,
+			set = this,
+			iNoClone = l - 1,
+			value = args[0],
+			isFunction = jQuery.isFunction( value );
+
+		// We can't cloneNode fragments that contain checked, in WebKit
+		if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) {
+			return this.each(function( index ) {
+				var self = set.eq( index );
+				if ( isFunction ) {
+					args[0] = value.call( this, index, self.html() );
+				}
+				self.domManip( args, callback, allowIntersection );
+			});
+		}
+
+		if ( l ) {
+			fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this );
+			first = fragment.firstChild;
+
+			if ( fragment.childNodes.length === 1 ) {
+				fragment = first;
+			}
+
+			if ( first ) {
+				scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
+				hasScripts = scripts.length;
+
+				// Use the original fragment for the last item instead of the first because it can end up
+				// being emptied incorrectly in certain situations (#8070).
+				for ( ; i < l; i++ ) {
+					node = fragment;
+
+					if ( i !== iNoClone ) {
+						node = jQuery.clone( node, true, true );
+
+						// Keep references to cloned scripts for later restoration
+						if ( hasScripts ) {
+							jQuery.merge( scripts, getAll( node, "script" ) );
+						}
+					}
+
+					callback.call( this[i], node, i );
+				}
+
+				if ( hasScripts ) {
+					doc = scripts[ scripts.length - 1 ].ownerDocument;
+
+					// Reenable scripts
+					jQuery.map( scripts, restoreScript );
+
+					// Evaluate executable scripts on first document insertion
+					for ( i = 0; i < hasScripts; i++ ) {
+						node = scripts[ i ];
+						if ( rscriptType.test( node.type || "" ) &&
+							!jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
+
+							if ( node.src ) {
+								// Hope ajax is available...
+								jQuery._evalUrl( node.src );
+							} else {
+								jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
+							}
+						}
+					}
+				}
+
+				// Fix #11809: Avoid leaking memory
+				fragment = first = null;
+			}
+		}
+
+		return this;
+	}
+});
+
+// Support: IE<8
+// Manipulating tables requires a tbody
+function manipulationTarget( elem, content ) {
+	return jQuery.nodeName( elem, "table" ) &&
+		jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ?
+
+		elem.getElementsByTagName("tbody")[0] ||
+			elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
+		elem;
+}
+
+// Replace/restore the type attribute of script elements for safe DOM manipulation
+function disableScript( elem ) {
+	elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type;
+	return elem;
+}
+function restoreScript( elem ) {
+	var match = rscriptTypeMasked.exec( elem.type );
+	if ( match ) {
+		elem.type = match[1];
+	} else {
+		elem.removeAttribute("type");
+	}
+	return elem;
+}
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+	var elem,
+		i = 0;
+	for ( ; (elem = elems[i]) != null; i++ ) {
+		jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
+	}
+}
+
+function cloneCopyEvent( src, dest ) {
+
+	if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
+		return;
+	}
+
+	var type, i, l,
+		oldData = jQuery._data( src ),
+		curData = jQuery._data( dest, oldData ),
+		events = oldData.events;
+
+	if ( events ) {
+		delete curData.handle;
+		curData.events = {};
+
+		for ( type in events ) {
+			for ( i = 0, l = events[ type ].length; i < l; i++ ) {
+				jQuery.event.add( dest, type, events[ type ][ i ] );
+			}
+		}
+	}
+
+	// make the cloned public data object a copy from the original
+	if ( curData.data ) {
+		curData.data = jQuery.extend( {}, curData.data );
+	}
+}
+
+function fixCloneNodeIssues( src, dest ) {
+	var nodeName, e, data;
+
+	// We do not need to do anything for non-Elements
+	if ( dest.nodeType !== 1 ) {
+		return;
+	}
+
+	nodeName = dest.nodeName.toLowerCase();
+
+	// IE6-8 copies events bound via attachEvent when using cloneNode.
+	if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) {
+		data = jQuery._data( dest );
+
+		for ( e in data.events ) {
+			jQuery.removeEvent( dest, e, data.handle );
+		}
+
+		// Event data gets referenced instead of copied if the expando gets copied too
+		dest.removeAttribute( jQuery.expando );
+	}
+
+	// IE blanks contents when cloning scripts, and tries to evaluate newly-set text
+	if ( nodeName === "script" && dest.text !== src.text ) {
+		disableScript( dest ).text = src.text;
+		restoreScript( dest );
+
+	// IE6-10 improperly clones children of object elements using classid.
+	// IE10 throws NoModificationAllowedError if parent is null, #12132.
+	} else if ( nodeName === "object" ) {
+		if ( dest.parentNode ) {
+			dest.outerHTML = src.outerHTML;
+		}
+
+		// This path appears unavoidable for IE9. When cloning an object
+		// element in IE9, the outerHTML strategy above is not sufficient.
+		// If the src has innerHTML and the destination does not,
+		// copy the src.innerHTML into the dest.innerHTML. #10324
+		if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
+			dest.innerHTML = src.innerHTML;
+		}
+
+	} else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) {
+		// IE6-8 fails to persist the checked state of a cloned checkbox
+		// or radio button. Worse, IE6-7 fail to give the cloned element
+		// a checked appearance if the defaultChecked value isn't also set
+
+		dest.defaultChecked = dest.checked = src.checked;
+
+		// IE6-7 get confused and end up setting the value of a cloned
+		// checkbox/radio button to an empty string instead of "on"
+		if ( dest.value !== src.value ) {
+			dest.value = src.value;
+		}
+
+	// IE6-8 fails to return the selected option to the default selected
+	// state when cloning options
+	} else if ( nodeName === "option" ) {
+		dest.defaultSelected = dest.selected = src.defaultSelected;
+
+	// IE6-8 fails to set the defaultValue to the correct value when
+	// cloning other types of input fields
+	} else if ( nodeName === "input" || nodeName === "textarea" ) {
+		dest.defaultValue = src.defaultValue;
+	}
+}
+
+jQuery.each({
+	appendTo: "append",
+	prependTo: "prepend",
+	insertBefore: "before",
+	insertAfter: "after",
+	replaceAll: "replaceWith"
+}, function( name, original ) {
+	jQuery.fn[ name ] = function( selector ) {
+		var elems,
+			i = 0,
+			ret = [],
+			insert = jQuery( selector ),
+			last = insert.length - 1;
+
+		for ( ; i <= last; i++ ) {
+			elems = i === last ? this : this.clone(true);
+			jQuery( insert[i] )[ original ]( elems );
+
+			// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
+			core_push.apply( ret, elems.get() );
+		}
+
+		return this.pushStack( ret );
+	};
+});
+
+function getAll( context, tag ) {
+	var elems, elem,
+		i = 0,
+		found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) :
+			typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) :
+			undefined;
+
+	if ( !found ) {
+		for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
+			if ( !tag || jQuery.nodeName( elem, tag ) ) {
+				found.push( elem );
+			} else {
+				jQuery.merge( found, getAll( elem, tag ) );
+			}
+		}
+	}
+
+	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
+		jQuery.merge( [ context ], found ) :
+		found;
+}
+
+// Used in buildFragment, fixes the defaultChecked property
+function fixDefaultChecked( elem ) {
+	if ( manipulation_rcheckableType.test( elem.type ) ) {
+		elem.defaultChecked = elem.checked;
+	}
+}
+
+jQuery.extend({
+	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+		var destElements, node, clone, i, srcElements,
+			inPage = jQuery.contains( elem.ownerDocument, elem );
+
+		if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
+			clone = elem.cloneNode( true );
+
+		// IE<=8 does not properly clone detached, unknown element nodes
+		} else {
+			fragmentDiv.innerHTML = elem.outerHTML;
+			fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
+		}
+
+		if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
+				(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
+
+			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
+			destElements = getAll( clone );
+			srcElements = getAll( elem );
+
+			// Fix all IE cloning issues
+			for ( i = 0; (node = srcElements[i]) != null; ++i ) {
+				// Ensure that the destination node is not null; Fixes #9587
+				if ( destElements[i] ) {
+					fixCloneNodeIssues( node, destElements[i] );
+				}
+			}
+		}
+
+		// Copy the events from the original to the clone
+		if ( dataAndEvents ) {
+			if ( deepDataAndEvents ) {
+				srcElements = srcElements || getAll( elem );
+				destElements = destElements || getAll( clone );
+
+				for ( i = 0; (node = srcElements[i]) != null; i++ ) {
+					cloneCopyEvent( node, destElements[i] );
+				}
+			} else {
+				cloneCopyEvent( elem, clone );
+			}
+		}
+
+		// Preserve script evaluation history
+		destElements = getAll( clone, "script" );
+		if ( destElements.length > 0 ) {
+			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
+		}
+
+		destElements = srcElements = node = null;
+
+		// Return the cloned set
+		return clone;
+	},
+
+	buildFragment: function( elems, context, scripts, selection ) {
+		var j, elem, contains,
+			tmp, tag, tbody, wrap,
+			l = elems.length,
+
+			// Ensure a safe fragment
+			safe = createSafeFragment( context ),
+
+			nodes = [],
+			i = 0;
+
+		for ( ; i < l; i++ ) {
+			elem = elems[ i ];
+
+			if ( elem || elem === 0 ) {
+
+				// Add nodes directly
+				if ( jQuery.type( elem ) === "object" ) {
+					jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+				// Convert non-html into a text node
+				} else if ( !rhtml.test( elem ) ) {
+					nodes.push( context.createTextNode( elem ) );
+
+				// Convert html into DOM nodes
+				} else {
+					tmp = tmp || safe.appendChild( context.createElement("div") );
+
+					// Deserialize a standard representation
+					tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase();
+					wrap = wrapMap[ tag ] || wrapMap._default;
+
+					tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
+
+					// Descend through wrappers to the right content
+					j = wrap[0];
+					while ( j-- ) {
+						tmp = tmp.lastChild;
+					}
+
+					// Manually add leading whitespace removed by IE
+					if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+						nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
+					}
+
+					// Remove IE's autoinserted <tbody> from table fragments
+					if ( !jQuery.support.tbody ) {
+
+						// String was a <table>, *may* have spurious <tbody>
+						elem = tag === "table" && !rtbody.test( elem ) ?
+							tmp.firstChild :
+
+							// String was a bare <thead> or <tfoot>
+							wrap[1] === "<table>" && !rtbody.test( elem ) ?
+								tmp :
+								0;
+
+						j = elem && elem.childNodes.length;
+						while ( j-- ) {
+							if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
+								elem.removeChild( tbody );
+							}
+						}
+					}
+
+					jQuery.merge( nodes, tmp.childNodes );
+
+					// Fix #12392 for WebKit and IE > 9
+					tmp.textContent = "";
+
+					// Fix #12392 for oldIE
+					while ( tmp.firstChild ) {
+						tmp.removeChild( tmp.firstChild );
+					}
+
+					// Remember the top-level container for proper cleanup
+					tmp = safe.lastChild;
+				}
+			}
+		}
+
+		// Fix #11356: Clear elements from fragment
+		if ( tmp ) {
+			safe.removeChild( tmp );
+		}
+
+		// Reset defaultChecked for any radios and checkboxes
+		// about to be appended to the DOM in IE 6/7 (#8060)
+		if ( !jQuery.support.appendChecked ) {
+			jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
+		}
+
+		i = 0;
+		while ( (elem = nodes[ i++ ]) ) {
+
+			// #4087 - If origin and destination elements are the same, and this is
+			// that element, do not do anything
+			if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
+				continue;
+			}
+
+			contains = jQuery.contains( elem.ownerDocument, elem );
+
+			// Append to fragment
+			tmp = getAll( safe.appendChild( elem ), "script" );
+
+			// Preserve script evaluation history
+			if ( contains ) {
+				setGlobalEval( tmp );
+			}
+
+			// Capture executables
+			if ( scripts ) {
+				j = 0;
+				while ( (elem = tmp[ j++ ]) ) {
+					if ( rscriptType.test( elem.type || "" ) ) {
+						scripts.push( elem );
+					}
+				}
+			}
+		}
+
+		tmp = null;
+
+		return safe;
+	},
+
+	cleanData: function( elems, /* internal */ acceptData ) {
+		var elem, type, id, data,
+			i = 0,
+			internalKey = jQuery.expando,
+			cache = jQuery.cache,
+			deleteExpando = jQuery.support.deleteExpando,
+			special = jQuery.event.special;
+
+		for ( ; (elem = elems[i]) != null; i++ ) {
+
+			if ( acceptData || jQuery.acceptData( elem ) ) {
+
+				id = elem[ internalKey ];
+				data = id && cache[ id ];
+
+				if ( data ) {
+					if ( data.events ) {
+						for ( type in data.events ) {
+							if ( special[ type ] ) {
+								jQuery.event.remove( elem, type );
+
+							// This is a shortcut to avoid jQuery.event.remove's overhead
+							} else {
+								jQuery.removeEvent( elem, type, data.handle );
+							}
+						}
+					}
+
+					// Remove cache only if it was not already removed by jQuery.event.remove
+					if ( cache[ id ] ) {
+
+						delete cache[ id ];
+
+						// IE does not allow us to delete expando properties from nodes,
+						// nor does it have a removeAttribute function on Document nodes;
+						// we must handle all of these cases
+						if ( deleteExpando ) {
+							delete elem[ internalKey ];
+
+						} else if ( typeof elem.removeAttribute !== core_strundefined ) {
+							elem.removeAttribute( internalKey );
+
+						} else {
+							elem[ internalKey ] = null;
+						}
+
+						core_deletedIds.push( id );
+					}
+				}
+			}
+		}
+	},
+
+	_evalUrl: function( url ) {
+		return jQuery.ajax({
+			url: url,
+			type: "GET",
+			dataType: "script",
+			async: false,
+			global: false,
+			"throws": true
+		});
+	}
+});
+jQuery.fn.extend({
+	wrapAll: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapAll( html.call(this, i) );
+			});
+		}
+
+		if ( this[0] ) {
+			// The elements to wrap the target around
+			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+			if ( this[0].parentNode ) {
+				wrap.insertBefore( this[0] );
+			}
+
+			wrap.map(function() {
+				var elem = this;
+
+				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+					elem = elem.firstChild;
+				}
+
+				return elem;
+			}).append( this );
+		}
+
+		return this;
+	},
+
+	wrapInner: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapInner( html.call(this, i) );
+			});
+		}
+
+		return this.each(function() {
+			var self = jQuery( this ),
+				contents = self.contents();
+
+			if ( contents.length ) {
+				contents.wrapAll( html );
+
+			} else {
+				self.append( html );
+			}
+		});
+	},
+
+	wrap: function( html ) {
+		var isFunction = jQuery.isFunction( html );
+
+		return this.each(function(i) {
+			jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
+		});
+	},
+
+	unwrap: function() {
+		return this.parent().each(function() {
+			if ( !jQuery.nodeName( this, "body" ) ) {
+				jQuery( this ).replaceWith( this.childNodes );
+			}
+		}).end();
+	}
+});
+var iframe, getStyles, curCSS,
+	ralpha = /alpha\([^)]*\)/i,
+	ropacity = /opacity\s*=\s*([^)]*)/,
+	rposition = /^(top|right|bottom|left)$/,
+	// swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
+	// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
+	rmargin = /^margin/,
+	rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
+	rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
+	rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ),
+	elemdisplay = { BODY: "block" },
+
+	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+	cssNormalTransform = {
+		letterSpacing: 0,
+		fontWeight: 400
+	},
+
+	cssExpand = [ "Top", "Right", "Bottom", "Left" ],
+	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
+
+// return a css property mapped to a potentially vendor prefixed property
+function vendorPropName( style, name ) {
+
+	// shortcut for names that are not vendor prefixed
+	if ( name in style ) {
+		return name;
+	}
+
+	// check for vendor prefixed names
+	var capName = name.charAt(0).toUpperCase() + name.slice(1),
+		origName = name,
+		i = cssPrefixes.length;
+
+	while ( i-- ) {
+		name = cssPrefixes[ i ] + capName;
+		if ( name in style ) {
+			return name;
+		}
+	}
+
+	return origName;
+}
+
+function isHidden( elem, el ) {
+	// isHidden might be called from jQuery#filter function;
+	// in that case, element will be second argument
+	elem = el || elem;
+	return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
+}
+
+function showHide( elements, show ) {
+	var display, elem, hidden,
+		values = [],
+		index = 0,
+		length = elements.length;
+
+	for ( ; index < length; index++ ) {
+		elem = elements[ index ];
+		if ( !elem.style ) {
+			continue;
+		}
+
+		values[ index ] = jQuery._data( elem, "olddisplay" );
+		display = elem.style.display;
+		if ( show ) {
+			// Reset the inline display of this element to learn if it is
+			// being hidden by cascaded rules or not
+			if ( !values[ index ] && display === "none" ) {
+				elem.style.display = "";
+			}
+
+			// Set elements which have been overridden with display: none
+			// in a stylesheet to whatever the default browser style is
+			// for such an element
+			if ( elem.style.display === "" && isHidden( elem ) ) {
+				values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
+			}
+		} else {
+
+			if ( !values[ index ] ) {
+				hidden = isHidden( elem );
+
+				if ( display && display !== "none" || !hidden ) {
+					jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
+				}
+			}
+		}
+	}
+
+	// Set the display of most of the elements in a second loop
+	// to avoid the constant reflow
+	for ( index = 0; index < length; index++ ) {
+		elem = elements[ index ];
+		if ( !elem.style ) {
+			continue;
+		}
+		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
+			elem.style.display = show ? values[ index ] || "" : "none";
+		}
+	}
+
+	return elements;
+}
+
+jQuery.fn.extend({
+	css: function( name, value ) {
+		return jQuery.access( this, function( elem, name, value ) {
+			var len, styles,
+				map = {},
+				i = 0;
+
+			if ( jQuery.isArray( name ) ) {
+				styles = getStyles( elem );
+				len = name.length;
+
+				for ( ; i < len; i++ ) {
+					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
+				}
+
+				return map;
+			}
+
+			return value !== undefined ?
+				jQuery.style( elem, name, value ) :
+				jQuery.css( elem, name );
+		}, name, value, arguments.length > 1 );
+	},
+	show: function() {
+		return showHide( this, true );
+	},
+	hide: function() {
+		return showHide( this );
+	},
+	toggle: function( state ) {
+		if ( typeof state === "boolean" ) {
+			return state ? this.show() : this.hide();
+		}
+
+		return this.each(function() {
+			if ( isHidden( this ) ) {
+				jQuery( this ).show();
+			} else {
+				jQuery( this ).hide();
+			}
+		});
+	}
+});
+
+jQuery.extend({
+	// Add in style property hooks for overriding the default
+	// behavior of getting and setting a style property
+	cssHooks: {
+		opacity: {
+			get: function( elem, computed ) {
+				if ( computed ) {
+					// We should always get a number back from opacity
+					var ret = curCSS( elem, "opacity" );
+					return ret === "" ? "1" : ret;
+				}
+			}
+		}
+	},
+
+	// Don't automatically add "px" to these possibly-unitless properties
+	cssNumber: {
+		"columnCount": true,
+		"fillOpacity": true,
+		"fontWeight": true,
+		"lineHeight": true,
+		"opacity": true,
+		"order": true,
+		"orphans": true,
+		"widows": true,
+		"zIndex": true,
+		"zoom": true
+	},
+
+	// Add in properties whose names you wish to fix before
+	// setting or getting the value
+	cssProps: {
+		// normalize float css property
+		"float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
+	},
+
+	// Get and set the style property on a DOM Node
+	style: function( elem, name, value, extra ) {
+		// Don't set styles on text and comment nodes
+		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+			return;
+		}
+
+		// Make sure that we're working with the right name
+		var ret, type, hooks,
+			origName = jQuery.camelCase( name ),
+			style = elem.style;
+
+		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
+
+		// gets hook for the prefixed version
+		// followed by the unprefixed version
+		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+		// Check if we're setting a value
+		if ( value !== undefined ) {
+			type = typeof value;
+
+			// convert relative number strings (+= or -=) to relative numbers. #7345
+			if ( type === "string" && (ret = rrelNum.exec( value )) ) {
+				value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
+				// Fixes bug #9237
+				type = "number";
+			}
+
+			// Make sure that NaN and null values aren't set. See: #7116
+			if ( value == null || type === "number" && isNaN( value ) ) {
+				return;
+			}
+
+			// If a number was passed in, add 'px' to the (except for certain CSS properties)
+			if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
+				value += "px";
+			}
+
+			// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
+			// but it would mean to define eight (for every problematic property) identical functions
+			if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
+				style[ name ] = "inherit";
+			}
+
+			// If a hook was provided, use that value, otherwise just set the specified value
+			if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
+
+				// Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+				// Fixes bug #5509
+				try {
+					style[ name ] = value;
+				} catch(e) {}
+			}
+
+		} else {
+			// If a hook was provided get the non-computed value from there
+			if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+				return ret;
+			}
+
+			// Otherwise just get the value from the style object
+			return style[ name ];
+		}
+	},
+
+	css: function( elem, name, extra, styles ) {
+		var num, val, hooks,
+			origName = jQuery.camelCase( name );
+
+		// Make sure that we're working with the right name
+		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
+
+		// gets hook for the prefixed version
+		// followed by the unprefixed version
+		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+		// If a hook was provided get the computed value from there
+		if ( hooks && "get" in hooks ) {
+			val = hooks.get( elem, true, extra );
+		}
+
+		// Otherwise, if a way to get the computed value exists, use that
+		if ( val === undefined ) {
+			val = curCSS( elem, name, styles );
+		}
+
+		//convert "normal" to computed value
+		if ( val === "normal" && name in cssNormalTransform ) {
+			val = cssNormalTransform[ name ];
+		}
+
+		// Return, converting to number if forced or a qualifier was provided and val looks numeric
+		if ( extra === "" || extra ) {
+			num = parseFloat( val );
+			return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
+		}
+		return val;
+	}
+});
+
+// NOTE: we've included the "window" in window.getComputedStyle
+// because jsdom on node.js will break without it.
+if ( window.getComputedStyle ) {
+	getStyles = function( elem ) {
+		return window.getComputedStyle( elem, null );
+	};
+
+	curCSS = function( elem, name, _computed ) {
+		var width, minWidth, maxWidth,
+			computed = _computed || getStyles( elem ),
+
+			// getPropertyValue is only needed for .css('filter') in IE9, see #12537
+			ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
+			style = elem.style;
+
+		if ( computed ) {
+
+			if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
+				ret = jQuery.style( elem, name );
+			}
+
+			// A tribute to the "awesome hack by Dean Edwards"
+			// Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
+			// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
+			// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
+			if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
+
+				// Remember the original values
+				width = style.width;
+				minWidth = style.minWidth;
+				maxWidth = style.maxWidth;
+
+				// Put in the new values to get a computed value out
+				style.minWidth = style.maxWidth = style.width = ret;
+				ret = computed.width;
+
+				// Revert the changed values
+				style.width = width;
+				style.minWidth = minWidth;
+				style.maxWidth = maxWidth;
+			}
+		}
+
+		return ret;
+	};
+} else if ( document.documentElement.currentStyle ) {
+	getStyles = function( elem ) {
+		return elem.currentStyle;
+	};
+
+	curCSS = function( elem, name, _computed ) {
+		var left, rs, rsLeft,
+			computed = _computed || getStyles( elem ),
+			ret = computed ? computed[ name ] : undefined,
+			style = elem.style;
+
+		// Avoid setting ret to empty string here
+		// so we don't default to auto
+		if ( ret == null && style && style[ name ] ) {
+			ret = style[ name ];
+		}
+
+		// From the awesome hack by Dean Edwards
+		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+		// If we're not dealing with a regular pixel number
+		// but a number that has a weird ending, we need to convert it to pixels
+		// but not position css attributes, as those are proportional to the parent element instead
+		// and we can't measure the parent instead because it might trigger a "stacking dolls" problem
+		if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
+
+			// Remember the original values
+			left = style.left;
+			rs = elem.runtimeStyle;
+			rsLeft = rs && rs.left;
+
+			// Put in the new values to get a computed value out
+			if ( rsLeft ) {
+				rs.left = elem.currentStyle.left;
+			}
+			style.left = name === "fontSize" ? "1em" : ret;
+			ret = style.pixelLeft + "px";
+
+			// Revert the changed values
+			style.left = left;
+			if ( rsLeft ) {
+				rs.left = rsLeft;
+			}
+		}
+
+		return ret === "" ? "auto" : ret;
+	};
+}
+
+function setPositiveNumber( elem, value, subtract ) {
+	var matches = rnumsplit.exec( value );
+	return matches ?
+		// Guard against undefined "subtract", e.g., when used as in cssHooks
+		Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
+		value;
+}
+
+function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
+	var i = extra === ( isBorderBox ? "border" : "content" ) ?
+		// If we already have the right measurement, avoid augmentation
+		4 :
+		// Otherwise initialize for horizontal or vertical properties
+		name === "width" ? 1 : 0,
+
+		val = 0;
+
+	for ( ; i < 4; i += 2 ) {
+		// both box models exclude margin, so add it if we want it
+		if ( extra === "margin" ) {
+			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
+		}
+
+		if ( isBorderBox ) {
+			// border-box includes padding, so remove it if we want content
+			if ( extra === "content" ) {
+				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+			}
+
+			// at this point, extra isn't border nor margin, so remove border
+			if ( extra !== "margin" ) {
+				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+			}
+		} else {
+			// at this point, extra isn't content, so add padding
+			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+
+			// at this point, extra isn't content nor padding, so add border
+			if ( extra !== "padding" ) {
+				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+			}
+		}
+	}
+
+	return val;
+}
+
+function getWidthOrHeight( elem, name, extra ) {
+
+	// Start with offset property, which is equivalent to the border-box value
+	var valueIsBorderBox = true,
+		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
+		styles = getStyles( elem ),
+		isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
+
+	// some non-html elements return undefined for offsetWidth, so check for null/undefined
+	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
+	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
+	if ( val <= 0 || val == null ) {
+		// Fall back to computed then uncomputed css if necessary
+		val = curCSS( elem, name, styles );
+		if ( val < 0 || val == null ) {
+			val = elem.style[ name ];
+		}
+
+		// Computed unit is not pixels. Stop here and return.
+		if ( rnumnonpx.test(val) ) {
+			return val;
+		}
+
+		// we need the check for style in case a browser which returns unreliable values
+		// for getComputedStyle silently falls back to the reliable elem.style
+		valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
+
+		// Normalize "", auto, and prepare for extra
+		val = parseFloat( val ) || 0;
+	}
+
+	// use the active box-sizing model to add/subtract irrelevant styles
+	return ( val +
+		augmentWidthOrHeight(
+			elem,
+			name,
+			extra || ( isBorderBox ? "border" : "content" ),
+			valueIsBorderBox,
+			styles
+		)
+	) + "px";
+}
+
+// Try to determine the default display value of an element
+function css_defaultDisplay( nodeName ) {
+	var doc = document,
+		display = elemdisplay[ nodeName ];
+
+	if ( !display ) {
+		display = actualDisplay( nodeName, doc );
+
+		// If the simple way fails, read from inside an iframe
+		if ( display === "none" || !display ) {
+			// Use the already-created iframe if possible
+			iframe = ( iframe ||
+				jQuery("<iframe frameborder='0' width='0' height='0'/>")
+				.css( "cssText", "display:block !important" )
+			).appendTo( doc.documentElement );
+
+			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
+			doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
+			doc.write("<!doctype html><html><body>");
+			doc.close();
+
+			display = actualDisplay( nodeName, doc );
+			iframe.detach();
+		}
+
+		// Store the correct default display
+		elemdisplay[ nodeName ] = display;
+	}
+
+	return display;
+}
+
+// Called ONLY from within css_defaultDisplay
+function actualDisplay( name, doc ) {
+	var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
+		display = jQuery.css( elem[0], "display" );
+	elem.remove();
+	return display;
+}
+
+jQuery.each([ "height", "width" ], function( i, name ) {
+	jQuery.cssHooks[ name ] = {
+		get: function( elem, computed, extra ) {
+			if ( computed ) {
+				// certain elements can have dimension info if we invisibly show them
+				// however, it must have a current display style that would benefit from this
+				return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
+					jQuery.swap( elem, cssShow, function() {
+						return getWidthOrHeight( elem, name, extra );
+					}) :
+					getWidthOrHeight( elem, name, extra );
+			}
+		},
+
+		set: function( elem, value, extra ) {
+			var styles = extra && getStyles( elem );
+			return setPositiveNumber( elem, value, extra ?
+				augmentWidthOrHeight(
+					elem,
+					name,
+					extra,
+					jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+					styles
+				) : 0
+			);
+		}
+	};
+});
+
+if ( !jQuery.support.opacity ) {
+	jQuery.cssHooks.opacity = {
+		get: function( elem, computed ) {
+			// IE uses filters for opacity
+			return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+				( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
+				computed ? "1" : "";
+		},
+
+		set: function( elem, value ) {
+			var style = elem.style,
+				currentStyle = elem.currentStyle,
+				opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
+				filter = currentStyle && currentStyle.filter || style.filter || "";
+
+			// IE has trouble with opacity if it does not have layout
+			// Force it by setting the zoom level
+			style.zoom = 1;
+
+			// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
+			// if value === "", then remove inline opacity #12685
+			if ( ( value >= 1 || value === "" ) &&
+					jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
+					style.removeAttribute ) {
+
+				// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
+				// if "filter:" is present at all, clearType is disabled, we want to avoid this
+				// style.removeAttribute is IE Only, but so apparently is this code path...
+				style.removeAttribute( "filter" );
+
+				// if there is no filter style applied in a css rule or unset inline opacity, we are done
+				if ( value === "" || currentStyle && !currentStyle.filter ) {
+					return;
+				}
+			}
+
+			// otherwise, set new filter values
+			style.filter = ralpha.test( filter ) ?
+				filter.replace( ralpha, opacity ) :
+				filter + " " + opacity;
+		}
+	};
+}
+
+// These hooks cannot be added until DOM ready because the support test
+// for it is not run until after DOM ready
+jQuery(function() {
+	if ( !jQuery.support.reliableMarginRight ) {
+		jQuery.cssHooks.marginRight = {
+			get: function( elem, computed ) {
+				if ( computed ) {
+					// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+					// Work around by temporarily setting element display to inline-block
+					return jQuery.swap( elem, { "display": "inline-block" },
+						curCSS, [ elem, "marginRight" ] );
+				}
+			}
+		};
+	}
+
+	// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+	// getComputedStyle returns percent when specified for top/left/bottom/right
+	// rather than make the css module depend on the offset module, we just check for it here
+	if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
+		jQuery.each( [ "top", "left" ], function( i, prop ) {
+			jQuery.cssHooks[ prop ] = {
+				get: function( elem, computed ) {
+					if ( computed ) {
+						computed = curCSS( elem, prop );
+						// if curCSS returns percentage, fallback to offset
+						return rnumnonpx.test( computed ) ?
+							jQuery( elem ).position()[ prop ] + "px" :
+							computed;
+					}
+				}
+			};
+		});
+	}
+
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+	jQuery.expr.filters.hidden = function( elem ) {
+		// Support: Opera <= 12.12
+		// Opera reports offsetWidths and offsetHeights less than zero on some elements
+		return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
+			(!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
+	};
+
+	jQuery.expr.filters.visible = function( elem ) {
+		return !jQuery.expr.filters.hidden( elem );
+	};
+}
+
+// These hooks are used by animate to expand properties
+jQuery.each({
+	margin: "",
+	padding: "",
+	border: "Width"
+}, function( prefix, suffix ) {
+	jQuery.cssHooks[ prefix + suffix ] = {
+		expand: function( value ) {
+			var i = 0,
+				expanded = {},
+
+				// assumes a single number if not a string
+				parts = typeof value === "string" ? value.split(" ") : [ value ];
+
+			for ( ; i < 4; i++ ) {
+				expanded[ prefix + cssExpand[ i ] + suffix ] =
+					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
+			}
+
+			return expanded;
+		}
+	};
+
+	if ( !rmargin.test( prefix ) ) {
+		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
+	}
+});
+var r20 = /%20/g,
+	rbracket = /\[\]$/,
+	rCRLF = /\r?\n/g,
+	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,