Commit dae5e51416b57b04e0a97bfca6b7a0bbac63ff9b

Authored by dg
1 parent 78550473

plop


git-svn-id: http://svn.net-core.org/repos/t-engine4@3053 51575b47-30f0-44d4-a5cc-537603b46e54
... ... @@ -32,16 +32,19 @@ function _M:init(t, no_default)
32 32 self.allow_backup_guardians = {}
33 33 self.world_artifacts_pool = {}
34 34 self.boss_killed = 0
  35 + self.stores_restock = 1
35 36 self.east_orc_patrols = 4
36 37 end
37 38
38   --- Number of bosses killed
  39 +--- Restock all stores
  40 +function _M:storesRestock()
  41 + self.stores_restock = self.stores_restock + 1
  42 + print("[STORES] restocking")
  43 +end
  44 +
  45 +--- Number of bosses killed
39 46 function _M:bossKilled(rank)
40   - if rank == 3.5 then
41   - self.boss_killed = self.boss_killed + 0.5
42   - else
43   - self.boss_killed = self.boss_killed + 1
44   - end
  47 + self.boss_killed = self.boss_killed + 1
45 48 end
46 49
47 50 --- Allow dropping the rod of recall
... ...
... ... @@ -52,8 +52,8 @@ end
52 52 --- Restock based on player level
53 53 function _M:canRestock()
54 54 local s = self.store
55   - if self.last_filled and self.last_filled >= game.state.boss_killed - s.restock_every then
56   - print("[STORE] not restocking yet [bosses killed]", game.state.boss_killed, s.restock_every, self.last_filled)
  55 + if self.last_filled and self.last_filled >= game.state.stores_restock then
  56 + print("[STORE] not restocking yet [stores_restock]", game.state.stores_restock, s.restock_every, self.last_filled)
57 57 return false
58 58 end
59 59 return true
... ... @@ -64,7 +64,7 @@ end
64 64 -- @param zone the zone to generate for
65 65 function _M:loadup(level, zone)
66 66 if Store.loadup(self, level, zone) then
67   - self.last_filled = game.state.boss_killed
  67 + self.last_filled = game.state.stores_restock
68 68 end
69 69 end
70 70
... ...
... ... @@ -23,8 +23,7 @@ newEntity{
23 23 display = '2', color=colors.UMBER,
24 24 store = {
25 25 purse = 25,
26   - restock_every = 3,
27   - empty_before_restock = true,
  26 + empty_before_restock = false,
28 27 min_fill = 10,
29 28 max_fill = 20,
30 29 filters = function()
... ... @@ -39,8 +38,7 @@ newEntity{
39 38 display = '3', color=colors.UMBER,
40 39 store = {
41 40 purse = 25,
42   - restock_every = 3,
43   - empty_before_restock = true,
  41 + empty_before_restock = false,
44 42 min_fill = 10,
45 43 max_fill = 20,
46 44 filters = function()
... ... @@ -55,8 +53,7 @@ newEntity{
55 53 display = '4', color=colors.LIGHT_BLUE,
56 54 store = {
57 55 purse = 10,
58   - restock_every = 3,
59   - empty_before_restock = true,
  56 + empty_before_restock = false,
60 57 min_fill = 4,
61 58 max_fill = 7,
62 59 filters = {
... ... @@ -71,8 +68,7 @@ newEntity{
71 68 display = '5', color=colors.WHITE,
72 69 store = {
73 70 purse = 10,
74   - restock_every = 3,
75   - empty_before_restock = true,
  71 + empty_before_restock = false,
76 72 min_fill = 4,
77 73 max_fill = 7,
78 74 filters = {
... ... @@ -87,8 +83,7 @@ newEntity{
87 83 display = '9', color=colors.BLUE,
88 84 store = {
89 85 purse = 30,
90   - restock_every = 3,
91   - empty_before_restock = true,
  86 + empty_before_restock = false,
92 87 min_fill = 20,
93 88 max_fill = 30,
94 89 filters = {
... ... @@ -107,8 +102,7 @@ newEntity{
107 102 display = '6', color=colors.RED,
108 103 store = {
109 104 purse = 25,
110   - restock_every = 3,
111   - empty_before_restock = true,
  105 + empty_before_restock = false,
112 106 min_fill = 15,
113 107 max_fill = 25,
114 108 filters = function()
... ... @@ -128,8 +122,7 @@ newEntity{
128 122 display = '2', color=colors.BLUE,
129 123 store = {
130 124 purse = 20,
131   - restock_every = 3,
132   - empty_before_restock = true,
  125 + empty_before_restock = false,
133 126 min_fill = 15,
134 127 max_fill = 25,
135 128 filters = {
... ... @@ -152,8 +145,7 @@ newEntity{
152 145 display = '5', color=colors.WHITE,
153 146 store = {
154 147 purse = 10,
155   - restock_every = 3,
156   - empty_before_restock = true,
  148 + empty_before_restock = false,
157 149 min_fill = 5,
158 150 max_fill = 9,
159 151 filters = {
... ... @@ -174,8 +166,7 @@ newEntity{
174 166 display = '7', color=colors.BLUE,
175 167 store = {
176 168 purse = 35,
177   - restock_every = 3,
178   - empty_before_restock = true,
  169 + empty_before_restock = false,
179 170 sell_percent = 240,
180 171 min_fill = 10,
181 172 max_fill = 20,
... ... @@ -191,8 +182,7 @@ newEntity{
191 182 display = '*', color=colors.LIGHT_RED,
192 183 store = {
193 184 purse = 5,
194   - restock_every = 3,
195   - empty_before_restock = true,
  185 + empty_before_restock = false,
196 186 min_fill = 40,
197 187 max_fill = 40,
198 188 filters = {
... ... @@ -215,8 +205,7 @@ newEntity{
215 205 display = '*', color=colors.LIGHT_RED,
216 206 store = {
217 207 purse = 5,
218   - restock_every = 3,
219   - empty_before_restock = true,
  208 + empty_before_restock = false,
220 209 min_fill = 40,
221 210 max_fill = 40,
222 211 filters = {
... ... @@ -231,8 +220,7 @@ newEntity{
231 220 display = '2', color=colors.UMBER,
232 221 store = {
233 222 purse = 25,
234   - restock_every = 3,
235   - empty_before_restock = true,
  223 + empty_before_restock = false,
236 224 min_fill = 20,
237 225 max_fill = 30,
238 226 filters = function()
... ... @@ -251,8 +239,7 @@ newEntity{
251 239 display = '3', color=colors.UMBER,
252 240 store = {
253 241 purse = 25,
254   - restock_every = 3,
255   - empty_before_restock = true,
  242 + empty_before_restock = false,
256 243 min_fill = 20,
257 244 max_fill = 30,
258 245 filters = function()
... ...
... ... @@ -73,4 +73,5 @@ start_fyrk = function(self)
73 73 world:gainAchievement("CHARRED_SCAR_SUCCESS", game.player)
74 74 end
75 75 game.player:setQuestStatus("charred-scar", engine.Quest.COMPLETED)
  76 + game.state:storesRestock()
76 77 end
... ...
... ... @@ -26,3 +26,10 @@ desc = function(self, who)
26 26 desc[#desc+1] = "Perhaps you should explore it and find the truth, and the treasures, for yourself!"
27 27 return table.concat(desc, "\n")
28 28 end
  29 +
  30 +on_status_change = function(self, who, status, sub)
  31 + if self:isCompleted() then
  32 + who:setQuestStatus(self.id, engine.Quest.DONE)
  33 + game.state:storesRestock()
  34 + end
  35 +end
... ...
... ... @@ -98,7 +98,7 @@ newEntity{ define_as = "THE_MASTER",
98 98
99 99 world:gainAchievement("VAMPIRE_CRUSHER", game.player:resolveSource())
100 100 game.player:resolveSource():grantQuest("dreadfell")
101   - game.player:resolveSource():setQuestStatus("dreadfell", engine.Quest.DONE)
  101 + game.player:resolveSource():setQuestStatus("dreadfell", engine.Quest.COMPLETED)
102 102
103 103 local ud = {}
104 104 if not profile.mod.allow_build.undead_skeleton then ud[#ud+1] = "undead_skeleton" end
... ...
  1 +# Makefile for Lua BitOp -- a bit operations library for Lua 5.1.
  2 +# To compile with MSVC please run: msvcbuild.bat
  3 +# To compile with MinGW please run: mingw32-make -f Makefile.mingw
  4 +
  5 +# Include path where lua.h, luaconf.h and lauxlib.h reside:
  6 +INCLUDES= -I/usr/local/include
  7 +
  8 +DEFINES=
  9 +# Use this if you need to compile for an old ARM ABI with swapped FPA doubles
  10 +#DEFINES= -DSWAPPED_DOUBLE
  11 +
  12 +# Lua executable name. Used to find the install path and for testing.
  13 +LUA= lua
  14 +
  15 +CC= gcc
  16 +SOCFLAGS= -fPIC
  17 +SOCC= $(CC) -shared $(SOCFLAGS)
  18 +CFLAGS= -Wall -O2 -fomit-frame-pointer $(SOCFLAGS) $(DEFINES) $(INCLUDES)
  19 +RM= rm -f
  20 +INSTALL= install -p
  21 +INSTALLPATH= $(LUA) installpath.lua
  22 +
  23 +MODNAME= bit
  24 +MODSO= $(MODNAME).so
  25 +
  26 +all: $(MODSO)
  27 +
  28 +# Alternative target for compiling on Mac OS X:
  29 +macosx:
  30 + $(MAKE) all "SOCC=MACOSX_DEPLOYMENT_TARGET=10.3 $(CC) -dynamiclib -single_module -undefined dynamic_lookup $(SOCFLAGS)"
  31 +
  32 +$(MODSO): $(MODNAME).o
  33 + $(SOCC) -o $@ $<
  34 +
  35 +install: $(MODSO)
  36 + $(INSTALL) $< `$(INSTALLPATH) $(MODNAME)`
  37 +
  38 +test: $(MODSO)
  39 + @$(LUA) bittest.lua && echo "basic test OK"
  40 + @$(LUA) nsievebits.lua && echo "nsievebits test OK"
  41 + @$(LUA) md5test.lua && echo "MD5 test OK"
  42 +
  43 +clean:
  44 + $(RM) *.o *.so *.obj *.lib *.exp *.dll *.manifest
  45 +
  46 +.PHONY: all macosx install test clean
  47 +
... ...
  1 +# Makefile for Lua BitOp -- a bit operations library for Lua 5.1.
  2 +# This is a modified Makefile for MinGW. C:\MinGW\bin must be in your PATH.
  3 +# Compile: mingw32-make -f Makefile.mingw
  4 +# Install: mingw32-make -f Makefile.mingw install
  5 +
  6 +# Lua executable name. Used for testing.
  7 +LUA= lua
  8 +
  9 +# Include path where lua.h, luaconf.h and lauxlib.h reside:
  10 +INCLUDES= "-I.."
  11 +
  12 +# Path of lua51.dll:
  13 +LUADLLPATH= "..\lua51.dll"
  14 +
  15 +# Path where C modules for Lua should be installed:
  16 +LUACMODPATH= ".."
  17 +
  18 +CC= gcc
  19 +SOCC= $(CC) -shared $(LUADLLPATH)
  20 +CFLAGS= -Wall -O2 -fomit-frame-pointer $(INCLUDES)
  21 +RM= del
  22 +STRIP= strip --strip-unneeded
  23 +INSTALL= copy
  24 +
  25 +MODNAME= bit
  26 +MODSO= $(MODNAME).dll
  27 +
  28 +all: $(MODSO)
  29 +
  30 +$(MODSO): $(MODNAME).o
  31 + $(SOCC) -o $@ $<
  32 + $(STRIP) $@
  33 +
  34 +install: $(MODSO)
  35 + $(INSTALL) $< $(LUACMODPATH)
  36 +
  37 +test: $(MODSO)
  38 + @$(LUA) bittest.lua && echo "basic test OK"
  39 + @$(LUA) nsievebits.lua && echo "nsievebits test OK"
  40 + @$(LUA) md5test.lua && echo "MD5 test OK"
  41 +
  42 +clean:
  43 + $(RM) *.o *.so *.obj *.lib *.exp *.dll *.manifest
  44 +
  45 +.PHONY: all install test clean
  46 +
... ...
  1 +README for Lua BitOp 1.0.1
  2 +--------------------------
  3 +
  4 +Lua BitOp is a C extension module for Lua 5.1 which adds
  5 +bitwise operations on numbers.
  6 +
  7 +Homepage: http://bitop.luajit.org/
  8 +
  9 +Lua BitOp is Copyright (C) 2008-2009 Mike Pall.
  10 +Lua BitOp is free software, released under the MIT/X license.
  11 +
  12 +--------------------------
  13 +
  14 +Full documentation for Lua BitOp is available in HTML format.
  15 +Please point your favourite browser to:
  16 +
  17 + doc/index.html
  18 +
  19 +Detailed installation instructions are here:
  20 +
  21 + doc/install.html
  22 +
... ...
  1 +/*
  2 +** Lua BitOp -- a bit operations library for Lua 5.1.
  3 +** http://bitop.luajit.org/
  4 +**
  5 +** Copyright (C) 2008-2009 Mike Pall. All rights reserved.
  6 +**
  7 +** Permission is hereby granted, free of charge, to any person obtaining
  8 +** a copy of this software and associated documentation files (the
  9 +** "Software"), to deal in the Software without restriction, including
  10 +** without limitation the rights to use, copy, modify, merge, publish,
  11 +** distribute, sublicense, and/or sell copies of the Software, and to
  12 +** permit persons to whom the Software is furnished to do so, subject to
  13 +** the following conditions:
  14 +**
  15 +** The above copyright notice and this permission notice shall be
  16 +** included in all copies or substantial portions of the Software.
  17 +**
  18 +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19 +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20 +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  21 +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  22 +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23 +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24 +** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25 +**
  26 +** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
  27 +*/
  28 +
  29 +#define LUA_BITOP_VERSION "1.0.1"
  30 +
  31 +#define LUA_LIB
  32 +#include "lua.h"
  33 +#include "lauxlib.h"
  34 +
  35 +#ifdef _MSC_VER
  36 +/* MSVC is stuck in the last century and doesn't have C99's stdint.h. */
  37 +typedef __int32 int32_t;
  38 +typedef unsigned __int32 uint32_t;
  39 +typedef unsigned __int64 uint64_t;
  40 +#else
  41 +#include <stdint.h>
  42 +#endif
  43 +
  44 +typedef int32_t SBits;
  45 +typedef uint32_t UBits;
  46 +
  47 +typedef union {
  48 + lua_Number n;
  49 +#ifdef LUA_NUMBER_DOUBLE
  50 + uint64_t b;
  51 +#else
  52 + UBits b;
  53 +#endif
  54 +} BitNum;
  55 +
  56 +/* Convert argument to bit type. */
  57 +static UBits barg(lua_State *L, int idx)
  58 +{
  59 + BitNum bn;
  60 + UBits b;
  61 + bn.n = lua_tonumber(L, idx);
  62 +#if defined(LUA_NUMBER_DOUBLE)
  63 + bn.n += 6755399441055744.0; /* 2^52+2^51 */
  64 +#ifdef SWAPPED_DOUBLE
  65 + b = (UBits)(bn.b >> 32);
  66 +#else
  67 + b = (UBits)bn.b;
  68 +#endif
  69 +#elif defined(LUA_NUMBER_INT) || defined(LUA_NUMBER_LONG) || \
  70 + defined(LUA_NUMBER_LONGLONG) || defined(LUA_NUMBER_LONG_LONG) || \
  71 + defined(LUA_NUMBER_LLONG)
  72 + if (sizeof(UBits) == sizeof(lua_Number))
  73 + b = bn.b;
  74 + else
  75 + b = (UBits)(SBits)bn.n;
  76 +#elif defined(LUA_NUMBER_FLOAT)
  77 +#error "A 'float' lua_Number type is incompatible with this library"
  78 +#else
  79 +#error "Unknown number type, check LUA_NUMBER_* in luaconf.h"
  80 +#endif
  81 + if (b == 0 && !lua_isnumber(L, idx))
  82 + luaL_typerror(L, idx, "number");
  83 + return b;
  84 +}
  85 +
  86 +/* Return bit type. */
  87 +#define BRET(b) lua_pushnumber(L, (lua_Number)(SBits)(b)); return 1;
  88 +
  89 +static int bit_tobit(lua_State *L) { BRET(barg(L, 1)) }
  90 +static int bit_bnot(lua_State *L) { BRET(~barg(L, 1)) }
  91 +
  92 +#define BIT_OP(func, opr) \
  93 + static int func(lua_State *L) { int i; UBits b = barg(L, 1); \
  94 + for (i = lua_gettop(L); i > 1; i--) b opr barg(L, i); BRET(b) }
  95 +BIT_OP(bit_band, &=)
  96 +BIT_OP(bit_bor, |=)
  97 +BIT_OP(bit_bxor, ^=)
  98 +
  99 +#define bshl(b, n) (b << n)
  100 +#define bshr(b, n) (b >> n)
  101 +#define bsar(b, n) ((SBits)b >> n)
  102 +#define brol(b, n) ((b << n) | (b >> (32-n)))
  103 +#define bror(b, n) ((b << (32-n)) | (b >> n))
  104 +#define BIT_SH(func, fn) \
  105 + static int func(lua_State *L) { \
  106 + UBits b = barg(L, 1); UBits n = barg(L, 2) & 31; BRET(fn(b, n)) }
  107 +BIT_SH(bit_lshift, bshl)
  108 +BIT_SH(bit_rshift, bshr)
  109 +BIT_SH(bit_arshift, bsar)
  110 +BIT_SH(bit_rol, brol)
  111 +BIT_SH(bit_ror, bror)
  112 +
  113 +static int bit_bswap(lua_State *L)
  114 +{
  115 + UBits b = barg(L, 1);
  116 + b = (b >> 24) | ((b >> 8) & 0xff00) | ((b & 0xff00) << 8) | (b << 24);
  117 + BRET(b)
  118 +}
  119 +
  120 +static int bit_tohex(lua_State *L)
  121 +{
  122 + UBits b = barg(L, 1);
  123 + SBits n = lua_isnone(L, 2) ? 8 : (SBits)barg(L, 2);
  124 + const char *hexdigits = "0123456789abcdef";
  125 + char buf[8];
  126 + int i;
  127 + if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
  128 + if (n > 8) n = 8;
  129 + for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; }
  130 + lua_pushlstring(L, buf, (size_t)n);
  131 + return 1;
  132 +}
  133 +
  134 +static const struct luaL_Reg bit_funcs[] = {
  135 + { "tobit", bit_tobit },
  136 + { "bnot", bit_bnot },
  137 + { "band", bit_band },
  138 + { "bor", bit_bor },
  139 + { "bxor", bit_bxor },
  140 + { "lshift", bit_lshift },
  141 + { "rshift", bit_rshift },
  142 + { "arshift", bit_arshift },
  143 + { "rol", bit_rol },
  144 + { "ror", bit_ror },
  145 + { "bswap", bit_bswap },
  146 + { "tohex", bit_tohex },
  147 + { NULL, NULL }
  148 +};
  149 +
  150 +/* Signed right-shifts are implementation-defined per C89/C99.
  151 +** But the de facto standard are arithmetic right-shifts on two's
  152 +** complement CPUs. This behaviour is required here, so test for it.
  153 +*/
  154 +#define BAD_SAR (bsar(-8, 2) != (SBits)-2)
  155 +
  156 +LUALIB_API int luaopen_bit(lua_State *L)
  157 +{
  158 + UBits b;
  159 + lua_pushnumber(L, (lua_Number)1437217655L);
  160 + b = barg(L, -1);
  161 + if (b != (UBits)1437217655L || BAD_SAR) { /* Perform a simple self-test. */
  162 + const char *msg = "compiled with incompatible luaconf.h";
  163 +#ifdef LUA_NUMBER_DOUBLE
  164 +#ifdef _WIN32
  165 + if (b == (UBits)1610612736L)
  166 + msg = "use D3DCREATE_FPU_PRESERVE with DirectX";
  167 +#endif
  168 + if (b == (UBits)1127743488L)
  169 + msg = "not compiled with SWAPPED_DOUBLE";
  170 +#endif
  171 + if (BAD_SAR)
  172 + msg = "arithmetic right-shift broken";
  173 + luaL_error(L, "bit library self-test failed (%s)", msg);
  174 + }
  175 + luaL_register(L, "bit", bit_funcs);
  176 + lua_pop(L, 2);
  177 + return 1;
  178 +}
  179 +
... ...
  1 +-- Microbenchmark for bit operations library. Public domain.
  2 +
  3 +local bit = require"bit"
  4 +
  5 +if not bit.rol then -- Replacement function if rotates are missing.
  6 + local bor, shl, shr = bit.bor, bit.lshift, bit.rshift
  7 + function bit.rol(a, b) return bor(shl(a, b), shr(a, 32-b)) end
  8 +end
  9 +
  10 +if not bit.bswap then -- Replacement function if bswap is missing.
  11 + local bor, band, shl, shr = bit.bor, bit.band, bit.lshift, bit.rshift
  12 + function bit.bswap(a)
  13 + return bor(shr(a, 24), band(shr(a, 8), 0xff00),
  14 + shl(band(a, 0xff00), 8), shl(a, 24));
  15 + end
  16 +end
  17 +
  18 +local base = 0
  19 +
  20 +local function bench(name, t)
  21 + local n = 2000000
  22 + repeat
  23 + local tm = os.clock()
  24 + t(n)
  25 + tm = os.clock() - tm
  26 + if tm > 1 then
  27 + local ns = tm*1000/(n/1000000)
  28 + io.write(string.format("%-15s %6.1f ns\n", name, ns-base))
  29 + return ns
  30 + end
  31 + n = n + n
  32 + until false
  33 +end
  34 +
  35 +-- The overhead for the base loop is subtracted from the other measurements.
  36 +base = bench("loop baseline", function(n)
  37 + local x = 0; for i=1,n do x = x + i end
  38 +end)
  39 +
  40 +bench("tobit", function(n)
  41 + local f = bit.tobit or bit.cast
  42 + local x = 0; for i=1,n do x = x + f(i) end
  43 +end)
  44 +
  45 +bench("bnot", function(n)
  46 + local f = bit.bnot
  47 + local x = 0; for i=1,n do x = x + f(i) end
  48 +end)
  49 +
  50 +bench("bor/band/bxor", function(n)
  51 + local f = bit.bor
  52 + local x = 0; for i=1,n do x = x + f(i, 1) end
  53 +end)
  54 +
  55 +bench("shifts", function(n)
  56 + local f = bit.lshift
  57 + local x = 0; for i=1,n do x = x + f(i, 1) end
  58 +end)
  59 +
  60 +bench("rotates", function(n)
  61 + local f = bit.rol
  62 + local x = 0; for i=1,n do x = x + f(i, 1) end
  63 +end)
  64 +
  65 +bench("bswap", function(n)
  66 + local f = bit.bswap
  67 + local x = 0; for i=1,n do x = x + f(i) end
  68 +end)
  69 +
... ...
  1 +-- Test cases for bit operations library. Public domain.
  2 +
  3 +local bit = require"bit"
  4 +
  5 +local vb = {
  6 + 0, 1, -1, 2, -2, 0x12345678, 0x87654321,
  7 + 0x33333333, 0x77777777, 0x55aa55aa, 0xaa55aa55,
  8 + 0x7fffffff, 0x80000000, 0xffffffff
  9 +}
  10 +
  11 +local function cksum(name, s, r)
  12 + local z = 0
  13 + for i=1,#s do z = (z + string.byte(s, i)*i) % 2147483629 end
  14 + if z ~= r then
  15 + error("bit."..name.." test failed (got "..z..", expected "..r..")", 0)
  16 + end
  17 +end
  18 +
  19 +local function check_unop(name, r)
  20 + local f = bit[name]
  21 + local s = ""
  22 + if pcall(f) or pcall(f, "z") or pcall(f, true) then
  23 + error("bit."..name.." fails to detect argument errors", 0)
  24 + end
  25 + for _,x in ipairs(vb) do s = s..","..tostring(f(x)) end
  26 + cksum(name, s, r)
  27 +end
  28 +
  29 +local function check_binop(name, r)
  30 + local f = bit[name]
  31 + local s = ""
  32 + if pcall(f) or pcall(f, "z") or pcall(f, true) then
  33 + error("bit."..name.." fails to detect argument errors", 0)
  34 + end
  35 + for _,x in ipairs(vb) do
  36 + for _,y in ipairs(vb) do s = s..","..tostring(f(x, y)) end
  37 + end
  38 + cksum(name, s, r)
  39 +end
  40 +
  41 +local function check_binop_range(name, r, yb, ye)
  42 + local f = bit[name]
  43 + local s = ""
  44 + if pcall(f) or pcall(f, "z") or pcall(f, true) or pcall(f, 1, true) then
  45 + error("bit."..name.." fails to detect argument errors", 0)
  46 + end
  47 + for _,x in ipairs(vb) do
  48 + for y=yb,ye do s = s..","..tostring(f(x, y)) end
  49 + end
  50 + cksum(name, s, r)
  51 +end
  52 +
  53 +local function check_shift(name, r)
  54 + check_binop_range(name, r, 0, 31)
  55 +end
  56 +
  57 +-- Minimal sanity checks.
  58 +assert(0x7fffffff == 2147483647, "broken hex literals")
  59 +assert(0xffffffff == -1 or 0xffffffff == 2^32-1, "broken hex literals")
  60 +assert(tostring(-1) == "-1", "broken tostring()")
  61 +assert(tostring(0xffffffff) == "-1" or tostring(0xffffffff) == "4294967295", "broken tostring()")
  62 +
  63 +-- Basic argument processing.
  64 +assert(bit.tobit(1) == 1)
  65 +assert(bit.band(1) == 1)
  66 +assert(bit.bxor(1,2) == 3)
  67 +assert(bit.bor(1,2,4,8,16,32,64,128) == 255)
  68 +
  69 +-- Apply operations to test vectors and compare checksums.
  70 +check_unop("tobit", 277312)
  71 +check_unop("bnot", 287870)
  72 +check_unop("bswap", 307611)
  73 +
  74 +check_binop("band", 41206764)
  75 +check_binop("bor", 51253663)
  76 +check_binop("bxor", 79322427)
  77 +
  78 +check_shift("lshift", 325260344)
  79 +check_shift("rshift", 139061800)
  80 +check_shift("arshift", 111364720)
  81 +check_shift("rol", 302401155)
  82 +check_shift("ror", 302316761)
  83 +
  84 +check_binop_range("tohex", 47880306, -8, 8)
  85 +
... ...
  1 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
  2 +<html>
  3 +<head>
  4 +<title>API Functions</title>
  5 +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  6 +<meta name="Author" content="Mike Pall">
  7 +<meta name="Copyright" content="Copyright (C) 2005-2009, Mike Pall">
  8 +<meta name="Language" content="en">
  9 +<link rel="stylesheet" type="text/css" href="bluequad.css" media="screen">
  10 +<link rel="stylesheet" type="text/css" href="bluequad-print.css" media="print">
  11 +</head>
  12 +<body>
  13 +<div id="site">
  14 +<a href="http://bitop.luajit.org"><span>Bit<span id="logo">Op</span></span></a>
  15 +</div>
  16 +<div id="head">
  17 +<h1>API Functions</h1>
  18 +</div>
  19 +<div id="nav">
  20 +<ul><li>
  21 +<a href="index.html">Lua BitOp</a>
  22 +</li><li>
  23 +<a href="install.html">Installation</a>
  24 +</li><li>
  25 +<a class="current" href="api.html">API Functions</a>
  26 +</li><li>
  27 +<a href="semantics.html">Semantics</a>
  28 +</li><li>
  29 +<a href="changes.html">Changes</a>
  30 +</li><li>
  31 +<a href="http://bitop.luajit.org/download.html">Download <span class="ext">&raquo;</span></a>
  32 +</li></ul>
  33 +</div>
  34 +<div id="main">
  35 +<p>
  36 +This list of API functions is not intended to replace a tutorial.
  37 +If you are not familiar with the terms used, you may want to study the
  38 +<a href="http://en.wikipedia.org/wiki/Bitwise_operation"><span class="ext">&raquo;</span>&nbsp;Wikipedia
  39 +article on bitwise operations</a> first.
  40 +</p>
  41 +<h2 id="loading">Loading the BitOp Module</h2>
  42 +<p>
  43 +The suggested way to use the BitOp module is to add the following
  44 +to the start of <em>every</em> Lua file that needs one of its functions:
  45 +</p>
  46 +<pre class="code">
  47 +local bit = require("bit")
  48 +</pre>
  49 +<p>
  50 +This makes the dependency explicit, limits the scope to the current file
  51 +and provides faster access to the <tt>bit.*</tt> functions, too.
  52 +It's good programming practice <em>not</em> to rely on the global variable
  53 +<tt>bit</tt> being set (assuming some other part of your application
  54 +has already loaded the module). The <tt>require</tt> function ensures
  55 +the module is only loaded once, in any case.
  56 +</p>
  57 +<h2 id="shortcuts">Defining Shortcuts</h2>
  58 +<p>
  59 +It's a common (but not a required) practice to cache often used module
  60 +functions in locals. This serves as a shortcut to save some typing
  61 +and also speeds up resolving them (only relevant if called hundreds of
  62 +thousands of times).
  63 +</p>
  64 +<pre class="code">
  65 +local bnot = bit.bnot
  66 +local band, bor, bxor = bit.band, bit.bor, bit.bxor
  67 +local lshift, rshift, rol = bit.lshift, bit.rshift, bit.rol
  68 +-- etc...
  69 +
  70 +-- Example use of the shortcuts:
  71 +local function tr_i(a, b, c, d, x, s)
  72 + return rol(bxor(c, bor(b, bnot(d))) + a + x, s) + b
  73 +end
  74 +</pre>
  75 +<p>
  76 +Remember that <b><tt>and</tt></b>, <b><tt>or</tt></b> and <b><tt>not</tt></b>
  77 +are reserved keywords in Lua. They cannot be used for variable names or
  78 +literal field names. That's why the corresponding bitwise functions have
  79 +been named <tt>band</tt>, <tt>bor</tt>, and <tt>bnot</tt>
  80 +(and <tt>bxor</tt> for consistency).
  81 +<p>
  82 +While we are at it: a common pitfall is to use <tt>bit</tt> as the
  83 +name of a local temporary variable &mdash; well, don't! :-)
  84 +</p>
  85 +<h2 id="examples">About the Examples</h2>
  86 +<p>
  87 +The examples below show small Lua one-liners. Their expected output
  88 +is shown after <tt>--&gt;</tt>. This is interpreted as a comment marker
  89 +by Lua so you can cut &amp; paste the whole line to a Lua prompt
  90 +and experiment with it.
  91 +</p>
  92 +<p>
  93 +Note that all bit operations return <em>signed</em> 32&nbsp;bit numbers
  94 +(<a href="semantics.html#range">rationale</a>). And these print
  95 +as signed decimal numbers by default.
  96 +</p>
  97 +<p>
  98 +For clarity the examples assume the definition of a helper function
  99 +<tt>printx()</tt>. This prints its argument as an <em>unsigned</em>
  100 +32&nbsp;bit hexadecimal number on all platforms:
  101 +</p>
  102 +<pre class="code">
  103 +function printx(x)
  104 + print("0x"..bit.tohex(x))
  105 +end
  106 +</pre>
  107 +
  108 +<h2 id="operations">Bit Operations</h2>
  109 +<h3 id="tobit"><tt>y = bit.tobit(x)</tt></h3>
  110 +<p>
  111 +Normalizes a number to the numeric range for bit operations and returns it.
  112 +This function is usually not needed since all bit operations already
  113 +normalize all of their input arguments. Check the
  114 +<a href="semantics.html">operational semantics</a> for details.
  115 +</p>
  116 +<pre class="code">
  117 +print(0xffffffff) --> 4294967295 (*)
  118 +print(bit.tobit(0xffffffff)) --> -1
  119 +printx(bit.tobit(0xffffffff)) --> 0xffffffff
  120 +print(bit.tobit(0xffffffff + 1)) --> 0
  121 +print(bit.tobit(2^40 + 1234)) --> 1234
  122 +</pre>
  123 +<p style="font-size: 80%;">
  124 +(*) See the treatment of <a href="semantics.html#hexlit">hex literals</a>
  125 +for an explanation why the printed numbers in the first two lines
  126 +differ (if your Lua installation uses a <tt>double</tt> number type).
  127 +</p>
  128 +
  129 +<h3 id="tohex"><tt>y = bit.tohex(x [,n])</tt></h3>
  130 +<p>
  131 +Converts its first argument to a hex string. The number of hex digits is
  132 +given by the absolute value of the optional second argument. Positive
  133 +numbers between 1 and 8 generate lowercase hex digits. Negative numbers
  134 +generate uppercase hex digits. Only the least-significant 4*|n| bits are
  135 +used. The default is to generate 8 lowercase hex digits.
  136 +</p>
  137 +<pre class="code">
  138 +print(bit.tohex(1)) --> 00000001
  139 +print(bit.tohex(-1)) --> ffffffff
  140 +print(bit.tohex(0xffffffff)) --> ffffffff
  141 +print(bit.tohex(-1, -8)) --> FFFFFFFF
  142 +print(bit.tohex(0x21, 4)) --> 0021
  143 +print(bit.tohex(0x87654321, 4)) --> 4321
  144 +</pre>
  145 +
  146 +<h3 id="bnot"><tt>y = bit.bnot(x)</tt></h3>
  147 +<p>
  148 +Returns the bitwise <b>not</b> of its argument.
  149 +</p>
  150 +<pre class="code">
  151 +print(bit.bnot(0)) --> -1
  152 +printx(bit.bnot(0)) --> 0xffffffff
  153 +print(bit.bnot(-1)) --> 0
  154 +print(bit.bnot(0xffffffff)) --> 0
  155 +printx(bit.bnot(0x12345678)) --> 0xedcba987
  156 +</pre>
  157 +
  158 +<h3 id="bor"><tt>y = bit.bor(x1 [,x2...])<br>
  159 +y = bit.band(x1 [,x2...])<br>
  160 +y = bit.bxor(x1 [,x2...])</tt></h3>
  161 +<p>
  162 +Returns either the bitwise <b>or</b>, bitwise <b>and</b>,
  163 +or bitwise <b>xor</b> of all of its arguments.
  164 +Note that more than two arguments are allowed.
  165 +</p>
  166 +<pre class="code">
  167 +print(bit.bor(1, 2, 4, 8)) --> 15
  168 +printx(bit.band(0x12345678, 0xff)) --> 0x00000078
  169 +printx(bit.bxor(0xa5a5f0f0, 0xaa55ff00)) --> 0x0ff00ff0
  170 +</pre>
  171 +
  172 +<h3 id="lshift"><tt>y = bit.lshift(x, n)<br>
  173 +y = bit.rshift(x, n)<br>
  174 +y = bit.arshift(x, n)</tt></h3>
  175 +<p>
  176 +Returns either the bitwise <b>logical left-shift</b>,
  177 +bitwise <b>logical right-shift</b>, or bitwise <b>arithmetic right-shift</b>
  178 +of its first argument by the number of bits given by the second argument.
  179 +</p>
  180 +<p>
  181 +Logical shifts treat the first argument as an unsigned number and shift in
  182 +0-bits. Arithmetic right-shift treats the most-significant bit
  183 +as a sign bit and replicates it.<br>
  184 +Only the lower 5&nbsp;bits of the shift count are used
  185 +(reduces to the range [0..31]).
  186 +</p>
  187 +<pre class="code">
  188 +print(bit.lshift(1, 0)) --> 1
  189 +print(bit.lshift(1, 8)) --> 256
  190 +print(bit.lshift(1, 40)) --> 256
  191 +print(bit.rshift(256, 8)) --> 1
  192 +print(bit.rshift(-256, 8)) --> 16777215
  193 +print(bit.arshift(256, 8)) --> 1
  194 +print(bit.arshift(-256, 8)) --> -1
  195 +printx(bit.lshift(0x87654321, 12)) --> 0x54321000
  196 +printx(bit.rshift(0x87654321, 12)) --> 0x00087654
  197 +printx(bit.arshift(0x87654321, 12)) --> 0xfff87654
  198 +</pre>
  199 +
  200 +<h3 id="rol"><tt>y = bit.rol(x, n)<br>
  201 +y = bit.ror(x, n)</tt></h3>
  202 +<p>
  203 +Returns either the bitwise <b>left rotation</b>,
  204 +or bitwise <b>right rotation</b> of its first argument by the
  205 +number of bits given by the second argument.
  206 +Bits shifted out on one side are shifted back in on the other side.<br>
  207 +Only the lower 5&nbsp;bits of the rotate count are used
  208 +(reduces to the range [0..31]).
  209 +</p>
  210 +<pre class="code">
  211 +printx(bit.rol(0x12345678, 12)) --> 0x45678123
  212 +printx(bit.ror(0x12345678, 12)) --> 0x67812345
  213 +</pre>
  214 +
  215 +<h3 id="bswap"><tt>y = bit.bswap(x)</tt></h3>
  216 +<p>
  217 +Swaps the bytes of its argument and returns it. This can be used
  218 +to convert little-endian 32&nbsp;bit numbers to big-endian 32&nbsp;bit
  219 +numbers or vice versa.
  220 +</p>
  221 +<pre class="code">
  222 +printx(bit.bswap(0x12345678)) --> 0x78563412
  223 +printx(bit.bswap(0x78563412)) --> 0x12345678
  224 +</pre>
  225 +
  226 +<h2 id="nsievebits">Example Program</h2>
  227 +<p>
  228 +This is an implementation of the (na&iuml;ve) <em>Sieve of Eratosthenes</em>
  229 +algorithm. It counts the number of primes up to some maximum number.
  230 +</p>
  231 +<p>
  232 +A Lua table is used to hold a bit-vector. Every array index has
  233 +32&nbsp;bits of the vector. Bitwise operations are used to access and
  234 +modify them. Note that the shift counts don't need to be masked
  235 +since this is already done by the BitOp shift and rotate functions.
  236 +</p>
  237 +<pre class="code">
  238 +local bit = require("bit")
  239 +local band, bxor = bit.band, bit.bxor
  240 +local rshift, rol = bit.rshift, bit.rol
  241 +
  242 +local m = tonumber(arg and arg[1]) or 100000
  243 +if m < 2 then m = 2 end
  244 +local count = 0
  245 +local p = {}
  246 +
  247 +for i=0,(m+31)/32 do p[i] = -1 end
  248 +
  249 +for i=2,m do
  250 + if band(rshift(p[rshift(i, 5)], i), 1) ~= 0 then
  251 + count = count + 1
  252 + for j=i+i,m,i do
  253 + local jx = rshift(j, 5)
  254 + p[jx] = band(p[jx], rol(-2, j))
  255 + end
  256 + end
  257 +end
  258 +
  259 +io.write(string.format("Found %d primes up to %d\n", count, m))
  260 +</pre>
  261 +<p>
  262 +Lua BitOp is quite fast. This program runs in less than
  263 +90&nbsp;milliseconds on a 3&nbsp;GHz CPU with a standard Lua installation,
  264 +but performs more than a million calls to bitwise functions.
  265 +If you're looking for even more speed,
  266 +check out <a href="http://luajit.org/"><span class="ext">&raquo;</span>&nbsp;LuaJIT</a>.
  267 +</p>
  268 +
  269 +<h2 id="caveats">Caveats</h2>
  270 +<h3>Signed Results</h3>
  271 +<p>
  272 +Returning signed numbers from bitwise operations may be surprising to
  273 +programmers coming from other programming languages which have both
  274 +signed and unsigned types. But as long as you treat the results of
  275 +bitwise operations uniformly everywhere, this shouldn't cause any problems.
  276 +</p>
  277 +<p>
  278 +Preferrably format results with <tt>bit.tohex</tt> if you want a
  279 +reliable unsigned string representation. Avoid the <tt>"%x"</tt> or
  280 +<tt>"%u"</tt> formats for <tt>string.format</tt>. They fail on some
  281 +architectures for negative numbers and can return more than 8 hex digits
  282 +on others.
  283 +</p>
  284 +<p>
  285 +You may also want to avoid the default number to string coercion,
  286 +since this is a signed conversion.
  287 +The coercion is used for string concatenation and all standard library
  288 +functions which accept string arguments (such as <tt>print()</tt> or
  289 +<tt>io.write()</tt>).
  290 +</p>
  291 +<h3>Conditionals</h3>
  292 +<p>
  293 +If you're transcribing some code from C/C++, watch out for
  294 +bit operations in conditionals. In C/C++ any non-zero value
  295 +is implicitly considered as "true". E.g. this C code:<br>
  296 +<tt>&nbsp;&nbsp;if (x & 3) ...</tt><br>
  297 +must not be turned into this Lua code:<br>
  298 +<tt>&nbsp;&nbsp;if band(x, 3) then ... -- <em>wrong!</em></tt>
  299 +</p>
  300 +<p>
  301 +In Lua all objects except <tt>nil</tt> and <tt>false</tt> are
  302 +considered "true". This includes all numbers. An explicit comparison
  303 +against zero is required in this case:<br>
  304 +<tt>&nbsp;&nbsp;if band(x, 3) ~= 0 then ... -- <em>correct!</em></tt>
  305 +</p>
  306 +<h3>Comparing Against Hex Literals</h3>
  307 +<p>
  308 +Comparing the results of bitwise operations (<em>signed</em> numbers)
  309 +against hex literals (<em>unsigned</em> numbers) needs some additional care.
  310 +The following conditional expression may or may not work right,
  311 +depending on the platform you run it on:<br>
  312 +<tt>&nbsp;&nbsp;bit.bor(x, 1) == 0xffffffff</tt><br>
  313 +E.g. it's never true on a Lua installation with the default number type.
  314 +Some simple solutions:
  315 +</p>
  316 +<ul>
  317 +<li>Either never use hex literals larger than 0x7fffffff in comparisons:<br>
  318 +<tt>&nbsp;&nbsp;bit.bor(x, 1) == -1</tt></li>
  319 +<li>Or convert them with <tt>bit.tobit()</tt> before comparing:<br>
  320 +<tt>&nbsp;&nbsp;bit.bor(x, 1) == bit.tobit(0xffffffff)</tt></li>
  321 +<li>Or use a generic workaround with <tt>bit.bxor()</tt>:<br>
  322 +<tt>&nbsp;&nbsp;bit.bxor(bit.bor(x, 1), 0xffffffff) == 0</tt></li>
  323 +<li>Or use a case-specific workaround:<br>
  324 +<tt>&nbsp;&nbsp;bit.rshift(x, 1) == 0x7fffffff</tt></li>
  325 +</ul>
  326 +<br class="flush">
  327 +</div>
  328 +<div id="foot">
  329 +<hr class="hide">
  330 +Copyright &copy; 2009 Mike Pall
  331 +<span class="noprint">
  332 +&middot;
  333 +<a href="contact.html">Contact</a>
  334 +</span>
  335 +</div>
  336 +</body>
  337 +</html>
... ...
  1 +/* Copyright (C) 2004-2009 Mike Pall.
  2 + *
  3 + * You are welcome to use the general ideas of this design for your own sites.
  4 + * But please do not steal the stylesheet, the layout or the color scheme.
  5 + */
  6 +body {
  7 + font-family: serif;
  8 + font-size: 11pt;
  9 + margin: 0 3em;
  10 + padding: 0;
  11 + border: none;
  12 +}
  13 +a:link, a:visited, a:hover, a:active {
  14 + text-decoration: none;
  15 + background: transparent;
  16 + color: #0000ff;
  17 +}
  18 +h1, h2, h3 {
  19 + font-family: sans-serif;
  20 + font-weight: bold;
  21 + text-align: left;
  22 + margin: 0.5em 0;
  23 + padding: 0;
  24 +}
  25 +h1 {
  26 + font-size: 200%;
  27 +}
  28 +h2 {
  29 + font-size: 150%;
  30 +}
  31 +h3 {
  32 + font-size: 125%;
  33 +}
  34 +p {
  35 + margin: 0 0 0.5em 0;
  36 + padding: 0;
  37 +}
  38 +ul, ol {
  39 + margin: 0.5em 0;
  40 + padding: 0 0 0 2em;
  41 +}
  42 +ul {
  43 + list-style: outside square;
  44 +}
  45 +ol {
  46 + list-style: outside decimal;
  47 +}
  48 +li {
  49 + margin: 0;
  50 + padding: 0;
  51 +}
  52 +dl {
  53 + margin: 1em 0;
  54 + padding: 1em;
  55 + border: 1px solid black;
  56 +}
  57 +dt {
  58 + font-weight: bold;
  59 + margin: 0;
  60 + padding: 0;
  61 +}
  62 +dt sup {
  63 + float: right;
  64 + margin-left: 1em;
  65 +}
  66 +dd {
  67 + margin: 0.5em 0 0 2em;
  68 + padding: 0;
  69 +}
  70 +table {
  71 + table-layout: fixed;
  72 + width: 100%;
  73 + margin: 1em 0;
  74 + padding: 0;
  75 + border: 1px solid black;
  76 + border-spacing: 0;
  77 + border-collapse: collapse;
  78 +}
  79 +tr {
  80 + margin: 0;
  81 + padding: 0;
  82 + border: none;
  83 +}
  84 +td {
  85 + text-align: left;
  86 + margin: 0;
  87 + padding: 0.2em 0.5em;
  88 + border-top: 1px solid black;
  89 + border-bottom: 1px solid black;
  90 +}
  91 +tr.separate td {
  92 + border-top: double;
  93 +}
  94 +tt, pre, code, kbd, samp {
  95 + font-family: monospace;
  96 + font-size: 75%;
  97 +}
  98 +kbd {
  99 + font-weight: bolder;
  100 +}
  101 +blockquote, pre {
  102 + margin: 1em 2em;
  103 + padding: 0;
  104 +}
  105 +img {
  106 + border: none;
  107 + vertical-align: baseline;
  108 + margin: 0;
  109 + padding: 0;
  110 +}
  111 +img.left {
  112 + float: left;
  113 + margin: 0.5em 1em 0.5em 0;
  114 +}
  115 +img.right {
  116 + float: right;
  117 + margin: 0.5em 0 0.5em 1em;
  118 +}
  119 +.flush {
  120 + clear: both;
  121 + visibility: hidden;
  122 +}
  123 +.hide, .noprint, #nav {
  124 + display: none !important;
  125 +}
  126 +.pagebreak {
  127 + page-break-before: always;
  128 +}
  129 +#site {
  130 + text-align: right;
  131 + font-family: sans-serif;
  132 + font-weight: bold;
  133 + margin: 0 1em;
  134 + border-bottom: 1pt solid black;
  135 +}
  136 +#site a {
  137 + font-size: 1.2em;
  138 +}
  139 +#site a:link, #site a:visited {
  140 + text-decoration: none;
  141 + font-weight: bold;
  142 + background: transparent;
  143 + color: #ffffff;
  144 +}
  145 +#logo {
  146 + color: #ff8000;
  147 +}
  148 +#head {
  149 + clear: both;
  150 + margin: 0 1em;
  151 +}
  152 +#main {
  153 + line-height: 1.3;
  154 + text-align: justify;
  155 + margin: 1em;
  156 +}
  157 +#foot {
  158 + clear: both;
  159 + font-size: 80%;
  160 + text-align: center;
  161 + margin: 0 1.25em;
  162 + padding: 0.5em 0 0 0;
  163 + border-top: 1pt solid black;
  164 + page-break-before: avoid;
  165 + page-break-after: avoid;
  166 +}
... ...
  1 +/* Copyright (C) 2004-2009 Mike Pall.
  2 + *
  3 + * You are welcome to use the general ideas of this design for your own sites.
  4 + * But please do not steal the stylesheet, the layout or the color scheme.
  5 + */
  6 +/* colorscheme:
  7 + *
  8 + * site | head #4162bf/white | #6078bf/#e6ecff
  9 + * ------+------ ----------------+-------------------
  10 + * nav | main #bfcfff | #e6ecff/black
  11 + *
  12 + * nav: hiback loback #c5d5ff #b9c9f9
  13 + * hiborder loborder #e6ecff #97a7d7
  14 + * link hover #2142bf #ff0000
  15 + *
  16 + * link: link visited hover #2142bf #8122bf #ff0000
  17 + *
  18 + * main: boxback boxborder #f0f4ff #bfcfff
  19 + */
  20 +body {
  21 + font-family: Verdana, Arial, Helvetica, sans-serif;
  22 + font-size: 10pt;
  23 + margin: 0;
  24 + padding: 0;
  25 + border: none;
  26 + background: #e0e0e0;
  27 + color: #000000;
  28 +}
  29 +a:link {
  30 + text-decoration: none;
  31 + background: transparent;
  32 + color: #2142bf;
  33 +}
  34 +a:visited {
  35 + text-decoration: none;
  36 + background: transparent;
  37 + color: #8122bf;
  38 +}
  39 +a:hover, a:active {
  40 + text-decoration: underline;
  41 + background: transparent;
  42 + color: #ff0000;
  43 +}
  44 +h1, h2, h3 {
  45 + font-weight: bold;
  46 + text-align: left;
  47 + margin: 0.5em 0;
  48 + padding: 0;
  49 + background: transparent;
  50 +}
  51 +h1 {
  52 + font-size: 200%;
  53 + line-height: 3em; /* really 6em relative to body, match #site span */
  54 + margin: 0;
  55 +}
  56 +h2 {
  57 + font-size: 150%;
  58 + color: #606060;
  59 +}
  60 +h3 {
  61 + font-size: 125%;
  62 + color: #404040;
  63 +}
  64 +p {
  65 + max-width: 600px;
  66 + margin: 0 0 0.5em 0;
  67 + padding: 0;
  68 +}
  69 +ul, ol {
  70 + max-width: 600px;
  71 + margin: 0.5em 0;
  72 + padding: 0 0 0 2em;
  73 +}
  74 +ul {
  75 + list-style: outside square;
  76 +}
  77 +ol {
  78 + list-style: outside decimal;
  79 +}
  80 +li {
  81 + margin: 0;
  82 + padding: 0;
  83 +}
  84 +dl {
  85 + max-width: 600px;
  86 + margin: 1em 0;
  87 + padding: 1em;
  88 + border: 1px solid #bfcfff;
  89 + background: #f0f4ff;
  90 +}
  91 +dt {
  92 + font-weight: bold;
  93 + margin: 0;
  94 + padding: 0;
  95 +}
  96 +dt sup {
  97 + float: right;
  98 + margin-left: 1em;
  99 + color: #808080;
  100 +}
  101 +dt a:visited {
  102 + text-decoration: none;
  103 + color: #2142bf;
  104 +}
  105 +dt a:hover, dt a:active {
  106 + text-decoration: none;
  107 + color: #ff0000;
  108 +}
  109 +dd {
  110 + margin: 0.5em 0 0 2em;
  111 + padding: 0;
  112 +}
  113 +div.tablewrap { /* for IE *sigh* */
  114 + max-width: 600px;
  115 +}
  116 +table {
  117 + table-layout: fixed;
  118 + border-spacing: 0;
  119 + border-collapse: collapse;
  120 + max-width: 600px;
  121 + width: 100%;
  122 + margin: 1em 0;
  123 + padding: 0;
  124 + border: 1px solid #bfcfff;
  125 +}
  126 +tr {
  127 + margin: 0;
  128 + padding: 0;
  129 + border: none;
  130 +}
  131 +tr.odd {
  132 + background: #f0f4ff;
  133 +}
  134 +tr.separate td {
  135 + border-top: 1px solid #bfcfff;
  136 +}
  137 +td {
  138 + text-align: left;
  139 + margin: 0;
  140 + padding: 0.2em 0.5em;
  141 + border: none;
  142 +}
  143 +tt, code, kbd, samp {
  144 + font-family: Courier New, Courier, monospace;
  145 + font-size: 110%;
  146 +}
  147 +kbd {
  148 + font-weight: bolder;
  149 +}
  150 +blockquote, pre {
  151 + max-width: 600px;
  152 + margin: 1em 2em;
  153 + padding: 0;
  154 +}
  155 +pre {
  156 + line-height: 1.1;
  157 +}
  158 +pre.code {
  159 + line-height: 1.4;
  160 + margin: 0.5em 0 1em 0.5em;
  161 + padding: 0.5em 1em;
  162 + border: 1px solid #bfcfff;
  163 + background: #f0f4ff;
  164 +}
  165 +img {
  166 + border: none;
  167 + vertical-align: baseline;
  168 + margin: 0;
  169 + padding: 0;
  170 +}
  171 +img.left {
  172 + float: left;
  173 + margin: 0.5em 1em 0.5em 0;
  174 +}
  175 +img.right {
  176 + float: right;
  177 + margin: 0.5em 0 0.5em 1em;
  178 +}
  179 +.indent {
  180 + padding-left: 1em;
  181 +}
  182 +.flush {
  183 + clear: both;
  184 + visibility: hidden;
  185 +}
  186 +.hide, .noscreen {
  187 + display: none !important;
  188 +}
  189 +.ext {
  190 + color: #ff8000;
  191 +}
  192 +#site {
  193 + clear: both;
  194 + float: left;
  195 + width: 13em;
  196 + text-align: center;
  197 + font-weight: bold;
  198 + margin: 0;
  199 + padding: 0;
  200 + background: transparent;
  201 + color: #ffffff;
  202 +}
  203 +#site a {
  204 + font-size: 200%;
  205 +}
  206 +#site a:link, #site a:visited {
  207 + text-decoration: none;
  208 + font-weight: bold;
  209 + background: transparent;
  210 + color: #ffffff;
  211 +}
  212 +#site span {
  213 + line-height: 3em; /* really 6em relative to body, match h1 */
  214 +}
  215 +#logo {
  216 + color: #ffb380;
  217 +}
  218 +#head {
  219 + margin: 0;
  220 + padding: 0 0 0 2em;
  221 + border-left: solid 13em #4162bf;
  222 + border-right: solid 3em #6078bf;
  223 + background: #6078bf;