\n")
+ self.mirror.root.describe(indent+2, buffer)
+ }
+ return string(buffer.Bytes())
}
// Describe will return a complete and humanly readable (albeit slightly convoluted) description of this Tree.
func (self *Tree) Describe() string {
- if self == nil {
- return ""
- }
- self.lock.RLock()
- defer self.lock.RUnlock()
- return self.describeIndented(0, 0)
+ if self == nil {
+ return ""
+ }
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ return self.describeIndented(0, 0)
}
// FakeDel will insert a tombstone at key with timestamp in this Tree.
func (self *Tree) FakeDel(key []byte, timestamp int64) (oldBytes []byte, oldTree *Tree, existed bool) {
- self.lock.Lock()
- defer self.lock.Unlock()
- var ex int
- self.root, oldBytes, oldTree, _, ex = self.root.fakeDel(nil, Rip(key), byteValue, timestamp, self.timer.ContinuousTime())
- existed = ex&byteValue != 0
- if existed {
- self.mirrorFakeDel(key, oldBytes, timestamp)
- self.log(persistence.Op{
- Key: key,
- })
- }
- return
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ var ex int
+ self.root, oldBytes, oldTree, _, ex = self.root.fakeDel(nil, Rip(key), byteValue, timestamp, self.timer.ContinuousTime())
+ existed = ex&byteValue != 0
+ if existed {
+ self.mirrorFakeDel(key, oldBytes, timestamp)
+ self.log(persistence.Op{
+ Key: key,
+ })
+ }
+ return
}
func (self *Tree) put(key []Nibble, byteValue []byte, treeValue *Tree, use int, timestamp int64) (oldBytes []byte, oldTree *Tree, existed int) {
- self.dataTimestamp = timestamp
- self.root, oldBytes, oldTree, _, existed = self.root.insert(nil, newNode(key, byteValue, treeValue, timestamp, false, use), self.timer.ContinuousTime())
- return
+ self.dataTimestamp = timestamp
+ self.root, oldBytes, oldTree, _, existed = self.root.insert(nil, newNode(key, byteValue, treeValue, timestamp, false, use), self.timer.ContinuousTime())
+ return
}
// Put will put key and value with timestamp in this Tree.
func (self *Tree) Put(key []byte, bValue []byte, timestamp int64) (oldBytes []byte, existed bool) {
- self.lock.Lock()
- defer self.lock.Unlock()
- oldBytes, _, ex := self.put(Rip(key), bValue, nil, byteValue, timestamp)
- existed = ex*byteValue != 0
- if existed {
- self.mirrorDel(key, oldBytes)
- }
- self.mirrorPut(key, bValue, timestamp)
- self.log(persistence.Op{
- Key: key,
- Value: bValue,
- Timestamp: timestamp,
- Put: true,
- })
- return
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ oldBytes, _, ex := self.put(Rip(key), bValue, nil, byteValue, timestamp)
+ existed = ex*byteValue != 0
+ if existed {
+ self.mirrorDel(key, oldBytes)
+ }
+ self.mirrorPut(key, bValue, timestamp)
+ self.log(persistence.Op{
+ Key: key,
+ Value: bValue,
+ Timestamp: timestamp,
+ Put: true,
+ })
+ return
}
// Get will return the value and timestamp at key.
func (self *Tree) Get(key []byte) (bValue []byte, timestamp int64, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- bValue, _, timestamp, ex := self.root.get(Rip(key))
- existed = ex&byteValue != 0
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ bValue, _, timestamp, ex := self.root.get(Rip(key))
+ existed = ex&byteValue != 0
+ return
}
// PrevMarker returns the previous key of tombstone or real value before key.
func (self *Tree) PrevMarker(key []byte) (prevKey []byte, existed bool) {
- if self == nil {
- return
- }
- self.lock.RLock()
- defer self.lock.RUnlock()
- self.root.reverseEachBetween(nil, nil, Rip(key), 0, 0, 0, func(k, b []byte, t *Tree, u int, v int64) bool {
- prevKey, existed = k, true
- return false
- })
- return
+ if self == nil {
+ return
+ }
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ self.root.reverseEachBetween(nil, nil, Rip(key), 0, 0, 0, func(k, b []byte, t *Tree, u int, v int64) bool {
+ prevKey, existed = k, true
+ return false
+ })
+ return
}
// NextMarker returns the next key of tombstone or real value after key.
func (self *Tree) NextMarker(key []byte) (nextKey []byte, existed bool) {
- if self == nil {
- return
- }
- self.lock.RLock()
- defer self.lock.RUnlock()
- self.root.eachBetween(nil, Rip(key), nil, 0, 0, 0, func(k, b []byte, t *Tree, u int, v int64) bool {
- nextKey, existed = k, true
- return false
- })
- return
+ if self == nil {
+ return
+ }
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ self.root.eachBetween(nil, Rip(key), nil, 0, 0, 0, func(k, b []byte, t *Tree, u int, v int64) bool {
+ nextKey, existed = k, true
+ return false
+ })
+ return
}
// MirrorPrev returns the previous key, value and timestamp before key in the mirror Tree.
func (self *Tree) MirrorPrev(key []byte) (prevKey, prevValue []byte, prevTimestamp int64, existed bool) {
- if self == nil || self.mirror == nil {
- return
- }
- prevKey, prevValue, prevTimestamp, existed = self.mirror.Prev(key)
- prevKey = prevKey[:len(prevKey)-len(escapeBytes(prevValue))-1]
- return
+ if self == nil || self.mirror == nil {
+ return
+ }
+ prevKey, prevValue, prevTimestamp, existed = self.mirror.Prev(key)
+ prevKey = prevKey[:len(prevKey)-len(escapeBytes(prevValue))-1]
+ return
}
// MirrorNext returns the next key, value and timestamp after key in the mirror Tree.
func (self *Tree) MirrorNext(key []byte) (nextKey, nextValue []byte, nextTimestamp int64, existed bool) {
- if self == nil || self.mirror == nil {
- return
- }
- nextKey, nextValue, nextTimestamp, existed = self.mirror.Next(key)
- nextKey = nextKey[:len(nextKey)-len(escapeBytes(nextValue))-1]
- return
+ if self == nil || self.mirror == nil {
+ return
+ }
+ nextKey, nextValue, nextTimestamp, existed = self.mirror.Next(key)
+ nextKey = nextKey[:len(nextKey)-len(escapeBytes(nextValue))-1]
+ return
}
// Prev will return the previous key, value and timestamp before key in this Tree.
func (self *Tree) Prev(key []byte) (prevKey, prevValue []byte, prevTimestamp int64, existed bool) {
- self.ReverseEachBetween(nil, key, false, false, func(k, v []byte, timestamp int64) bool {
- prevKey, prevValue, prevTimestamp, existed = k, v, timestamp, true
- return false
- })
- return
+ self.ReverseEachBetween(nil, key, false, false, func(k, v []byte, timestamp int64) bool {
+ prevKey, prevValue, prevTimestamp, existed = k, v, timestamp, true
+ return false
+ })
+ return
}
// Next will return the next key, value and timestamp after key in this Tree.
func (self *Tree) Next(key []byte) (nextKey, nextValue []byte, nextTimestamp int64, existed bool) {
- self.EachBetween(key, nil, false, false, func(k, v []byte, timestamp int64) bool {
- nextKey, nextValue, nextTimestamp, existed = k, v, timestamp, true
- return false
- })
- return
+ self.EachBetween(key, nil, false, false, func(k, v []byte, timestamp int64) bool {
+ nextKey, nextValue, nextTimestamp, existed = k, v, timestamp, true
+ return false
+ })
+ return
}
// NextMarkerIndex will return the next key of tombstone or real value after the given index in this Tree.
func (self *Tree) NextMarkerIndex(index int) (key []byte, existed bool) {
- if self == nil {
- return
- }
- self.lock.RLock()
- defer self.lock.RUnlock()
- self.root.eachBetweenIndex(nil, 0, &index, nil, 0, func(k, b []byte, t *Tree, u int, v int64, i int) bool {
- key, existed = k, true
- return false
- })
- return
+ if self == nil {
+ return
+ }
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ self.root.eachBetweenIndex(nil, 0, &index, nil, 0, func(k, b []byte, t *Tree, u int, v int64, i int) bool {
+ key, existed = k, true
+ return false
+ })
+ return
}
// PrevMarkerIndex will return the previous key of tombstone or real value before the given index in this Tree.
func (self *Tree) PrevMarkerIndex(index int) (key []byte, existed bool) {
- if self == nil {
- return
- }
- self.lock.RLock()
- defer self.lock.RUnlock()
- self.root.reverseEachBetweenIndex(nil, 0, nil, &index, 0, func(k, b []byte, t *Tree, u int, v int64, i int) bool {
- key, existed = k, true
- return false
- })
- return
+ if self == nil {
+ return
+ }
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ self.root.reverseEachBetweenIndex(nil, 0, nil, &index, 0, func(k, b []byte, t *Tree, u int, v int64, i int) bool {
+ key, existed = k, true
+ return false
+ })
+ return
}
// MirrorNextIndex will return the next key, value, timestamp and index after index in the mirror Tree.
func (self *Tree) MirrorNextIndex(index int) (key, value []byte, timestamp int64, ind int, existed bool) {
- if self == nil || self.mirror == nil {
- return
- }
- key, value, timestamp, ind, existed = self.mirror.NextIndex(index)
- if existed {
- key = key[:len(key)-len(escapeBytes(value))-1]
- }
- return
+ if self == nil || self.mirror == nil {
+ return
+ }
+ key, value, timestamp, ind, existed = self.mirror.NextIndex(index)
+ if existed {
+ key = key[:len(key)-len(escapeBytes(value))-1]
+ }
+ return
}
// MirrorPrevIndex will return the previous key, value, timestamp and index before index in the mirror Tree.
func (self *Tree) MirrorPrevIndex(index int) (key, value []byte, timestamp int64, ind int, existed bool) {
- if self == nil || self.mirror == nil {
- return
- }
- key, value, timestamp, ind, existed = self.mirror.PrevIndex(index)
- if existed {
- key = key[:len(key)-len(escapeBytes(value))-1]
- }
- return
+ if self == nil || self.mirror == nil {
+ return
+ }
+ key, value, timestamp, ind, existed = self.mirror.PrevIndex(index)
+ if existed {
+ key = key[:len(key)-len(escapeBytes(value))-1]
+ }
+ return
}
// NextIndex will return the next key, value, timestamp and index after index in this Tree.
func (self *Tree) NextIndex(index int) (key, value []byte, timestamp int64, ind int, existed bool) {
- n := index + 1
- self.EachBetweenIndex(&n, &n, func(k, v []byte, t int64, i int) bool {
- key, value, timestamp, ind, existed = k, v, t, i, true
- return false
- })
- return
+ n := index + 1
+ self.EachBetweenIndex(&n, &n, func(k, v []byte, t int64, i int) bool {
+ key, value, timestamp, ind, existed = k, v, t, i, true
+ return false
+ })
+ return
}
// PrevIndex will return the previous key, value, timestamp and index before index in this Tree.
func (self *Tree) PrevIndex(index int) (key, value []byte, timestamp int64, ind int, existed bool) {
- p := index - 1
- self.EachBetweenIndex(&p, &p, func(k, v []byte, t int64, i int) bool {
- key, value, timestamp, ind, existed = k, v, t, i, true
- return false
- })
- return
+ p := index - 1
+ self.EachBetweenIndex(&p, &p, func(k, v []byte, t int64, i int) bool {
+ key, value, timestamp, ind, existed = k, v, t, i, true
+ return false
+ })
+ return
}
// MirrorFirst will return the first key, value and timestamp of the mirror Tree.
func (self *Tree) MirrorFirst() (key, byteValue []byte, timestamp int64, existed bool) {
- if self == nil || self.mirror == nil {
- return
- }
- key, byteValue, timestamp, existed = self.mirror.First()
- key = key[:len(key)-len(escapeBytes(byteValue))-1]
- return
+ if self == nil || self.mirror == nil {
+ return
+ }
+ key, byteValue, timestamp, existed = self.mirror.First()
+ key = key[:len(key)-len(escapeBytes(byteValue))-1]
+ return
}
// MirrorLast will return the last key, value and timestamp of the mirror Tree.
func (self *Tree) MirrorLast() (key, byteValue []byte, timestamp int64, existed bool) {
- if self == nil || self.mirror == nil {
- return
- }
- key, byteValue, timestamp, existed = self.mirror.Last()
- key = key[:len(key)-len(escapeBytes(byteValue))-1]
- return
+ if self == nil || self.mirror == nil {
+ return
+ }
+ key, byteValue, timestamp, existed = self.mirror.Last()
+ key = key[:len(key)-len(escapeBytes(byteValue))-1]
+ return
}
// First returns the first key, value and timestamp in this Tree.
func (self *Tree) First() (key, byteValue []byte, timestamp int64, existed bool) {
- self.Each(func(k []byte, b []byte, ver int64) bool {
- key, byteValue, timestamp, existed = k, b, ver, true
- return false
- })
- return
+ self.Each(func(k []byte, b []byte, ver int64) bool {
+ key, byteValue, timestamp, existed = k, b, ver, true
+ return false
+ })
+ return
}
// Last returns the last key, value and timestamp in this Tree.
func (self *Tree) Last() (key, byteValue []byte, timestamp int64, existed bool) {
- self.ReverseEach(func(k []byte, b []byte, ver int64) bool {
- key, byteValue, timestamp, existed = k, b, ver, true
- return false
- })
- return
+ self.ReverseEach(func(k []byte, b []byte, ver int64) bool {
+ key, byteValue, timestamp, existed = k, b, ver, true
+ return false
+ })
+ return
}
// MirrorIndex returns the key, value and timestamp at index in the mirror Tree.
func (self *Tree) MirrorIndex(n int) (key, byteValue []byte, timestamp int64, existed bool) {
- if self == nil || self.mirror == nil {
- return
- }
- key, byteValue, timestamp, existed = self.mirror.Index(n)
- key = key[:len(key)-len(escapeBytes(byteValue))-1]
- return
+ if self == nil || self.mirror == nil {
+ return
+ }
+ key, byteValue, timestamp, existed = self.mirror.Index(n)
+ key = key[:len(key)-len(escapeBytes(byteValue))-1]
+ return
}
// MirrorReverseIndex returns the key, value and timestamp at index from the end in the mirror Tree.
func (self *Tree) MirrorReverseIndex(n int) (key, byteValue []byte, timestamp int64, existed bool) {
- if self == nil || self.mirror == nil {
- return
- }
- key, byteValue, timestamp, existed = self.mirror.Index(n)
- key = key[:len(key)-len(escapeBytes(byteValue))-1]
- return
+ if self == nil || self.mirror == nil {
+ return
+ }
+ key, byteValue, timestamp, existed = self.mirror.Index(n)
+ key = key[:len(key)-len(escapeBytes(byteValue))-1]
+ return
}
// Index returns the key, value and timestamp at index in this Tree.
func (self *Tree) Index(n int) (key []byte, byteValue []byte, timestamp int64, existed bool) {
- self.EachBetweenIndex(&n, &n, func(k []byte, b []byte, ver int64, index int) bool {
- key, byteValue, timestamp, existed = k, b, ver, true
- return false
- })
- return
+ self.EachBetweenIndex(&n, &n, func(k []byte, b []byte, ver int64, index int) bool {
+ key, byteValue, timestamp, existed = k, b, ver, true
+ return false
+ })
+ return
}
// ReverseIndex returns the key, value and timestamp at index from the end in this Tree.
func (self *Tree) ReverseIndex(n int) (key []byte, byteValue []byte, timestamp int64, existed bool) {
- self.ReverseEachBetweenIndex(&n, &n, func(k []byte, b []byte, ver int64, index int) bool {
- key, byteValue, timestamp, existed = k, b, ver, true
- return false
- })
- return
+ self.ReverseEachBetweenIndex(&n, &n, func(k []byte, b []byte, ver int64, index int) bool {
+ key, byteValue, timestamp, existed = k, b, ver, true
+ return false
+ })
+ return
}
-// Clear will remove all content of this Tree (including tombstones and sub trees) and any mirror Tree and replace the all with one giant tombstone, and clear any persistence.Logger assigned to this Tree.
+// Clear will remove all content of this Tree (including tombstones and sub trees) and any mirror Tree, replace them all with one giant tombstone,
+// and clear any persistence.Logger assigned to this Tree.
func (self *Tree) Clear(timestamp int64) {
- self.lock.Lock()
- defer self.lock.Unlock()
- self.dataTimestamp, self.root = timestamp, nil
- self.root, _, _, _, _ = self.root.insert(nil, newNode(nil, nil, nil, 0, true, 0), self.timer.ContinuousTime())
- self.mirrorClear(timestamp)
- if self.logger != nil {
- self.logger.Clear()
- }
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ self.dataTimestamp, self.root = timestamp, nil
+ self.root, _, _, _, _ = self.root.insert(nil, newNode(nil, nil, nil, 0, true, 0), self.timer.ContinuousTime())
+ self.mirrorClear(timestamp)
+ if self.logger != nil {
+ self.logger.Clear()
+ }
}
func (self *Tree) del(key []Nibble, use int) (oldBytes []byte, existed bool) {
- var ex int
- self.root, oldBytes, _, _, ex = self.root.del(nil, key, use, self.timer.ContinuousTime())
- existed = ex&byteValue != 0
- return
+ var ex int
+ self.root, oldBytes, _, _, ex = self.root.del(nil, key, use, self.timer.ContinuousTime())
+ existed = ex&byteValue != 0
+ return
}
// Del will remove key from this Tree without keeping a tombstone.
func (self *Tree) Del(key []byte) (oldBytes []byte, existed bool) {
- self.lock.Lock()
- defer self.lock.Unlock()
- oldBytes, existed = self.del(Rip(key), byteValue)
- if existed {
- self.mirrorDel(key, oldBytes)
- self.log(persistence.Op{
- Key: key,
- })
- }
- return
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ oldBytes, existed = self.del(Rip(key), byteValue)
+ if existed {
+ self.mirrorDel(key, oldBytes)
+ self.log(persistence.Op{
+ Key: key,
+ })
+ }
+ return
}
func (self *Tree) SubMirrorReverseIndexOf(key, subKey []byte) (index int, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- index, existed = subTree.MirrorReverseIndexOf(subKey)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ index, existed = subTree.MirrorReverseIndexOf(subKey)
+ }
+ return
}
func (self *Tree) SubMirrorIndexOf(key, subKey []byte) (index int, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- index, existed = subTree.MirrorIndexOf(subKey)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ index, existed = subTree.MirrorIndexOf(subKey)
+ }
+ return
}
func (self *Tree) SubReverseIndexOf(key, subKey []byte) (index int, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- index, existed = subTree.ReverseIndexOf(subKey)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ index, existed = subTree.ReverseIndexOf(subKey)
+ }
+ return
}
func (self *Tree) SubIndexOf(key, subKey []byte) (index int, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- index, existed = subTree.IndexOf(subKey)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ index, existed = subTree.IndexOf(subKey)
+ }
+ return
}
func (self *Tree) SubMirrorPrevIndex(key []byte, index int) (foundKey, foundValue []byte, foundTimestamp int64, foundIndex int, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- foundKey, foundValue, foundTimestamp, foundIndex, existed = subTree.MirrorPrevIndex(index)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ foundKey, foundValue, foundTimestamp, foundIndex, existed = subTree.MirrorPrevIndex(index)
+ }
+ return
}
func (self *Tree) SubMirrorNextIndex(key []byte, index int) (foundKey, foundValue []byte, foundTimestamp int64, foundIndex int, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- foundKey, foundValue, foundTimestamp, foundIndex, existed = subTree.MirrorNextIndex(index)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ foundKey, foundValue, foundTimestamp, foundIndex, existed = subTree.MirrorNextIndex(index)
+ }
+ return
}
func (self *Tree) SubPrevIndex(key []byte, index int) (foundKey, foundValue []byte, foundTimestamp int64, foundIndex int, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- foundKey, foundValue, foundTimestamp, foundIndex, existed = subTree.PrevIndex(index)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ foundKey, foundValue, foundTimestamp, foundIndex, existed = subTree.PrevIndex(index)
+ }
+ return
}
func (self *Tree) SubNextIndex(key []byte, index int) (foundKey, foundValue []byte, foundTimestamp int64, foundIndex int, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- foundKey, foundValue, foundTimestamp, foundIndex, existed = subTree.NextIndex(index)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ foundKey, foundValue, foundTimestamp, foundIndex, existed = subTree.NextIndex(index)
+ }
+ return
}
func (self *Tree) SubMirrorFirst(key []byte) (firstKey []byte, firstBytes []byte, firstTimestamp int64, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- firstKey, firstBytes, firstTimestamp, existed = subTree.MirrorFirst()
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ firstKey, firstBytes, firstTimestamp, existed = subTree.MirrorFirst()
+ }
+ return
}
func (self *Tree) SubMirrorLast(key []byte) (lastKey []byte, lastBytes []byte, lastTimestamp int64, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- lastKey, lastBytes, lastTimestamp, existed = subTree.MirrorLast()
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ lastKey, lastBytes, lastTimestamp, existed = subTree.MirrorLast()
+ }
+ return
}
func (self *Tree) SubFirst(key []byte) (firstKey []byte, firstBytes []byte, firstTimestamp int64, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- firstKey, firstBytes, firstTimestamp, existed = subTree.First()
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ firstKey, firstBytes, firstTimestamp, existed = subTree.First()
+ }
+ return
}
func (self *Tree) SubLast(key []byte) (lastKey []byte, lastBytes []byte, lastTimestamp int64, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- lastKey, lastBytes, lastTimestamp, existed = subTree.Last()
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ lastKey, lastBytes, lastTimestamp, existed = subTree.Last()
+ }
+ return
}
func (self *Tree) SubMirrorPrev(key, subKey []byte) (prevKey, prevValue []byte, prevTimestamp int64, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- prevKey, prevValue, prevTimestamp, existed = subTree.MirrorPrev(subKey)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ prevKey, prevValue, prevTimestamp, existed = subTree.MirrorPrev(subKey)
+ }
+ return
}
func (self *Tree) SubMirrorNext(key, subKey []byte) (nextKey, nextValue []byte, nextTimestamp int64, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- nextKey, nextValue, nextTimestamp, existed = subTree.MirrorNext(subKey)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ nextKey, nextValue, nextTimestamp, existed = subTree.MirrorNext(subKey)
+ }
+ return
}
func (self *Tree) SubPrev(key, subKey []byte) (prevKey, prevValue []byte, prevTimestamp int64, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- prevKey, prevValue, prevTimestamp, existed = subTree.Prev(subKey)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ prevKey, prevValue, prevTimestamp, existed = subTree.Prev(subKey)
+ }
+ return
}
func (self *Tree) SubNext(key, subKey []byte) (nextKey, nextValue []byte, nextTimestamp int64, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- nextKey, nextValue, nextTimestamp, existed = subTree.Next(subKey)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ nextKey, nextValue, nextTimestamp, existed = subTree.Next(subKey)
+ }
+ return
}
func (self *Tree) SubSize(key []byte) (result int) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- result = subTree.Size()
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ result = subTree.Size()
+ }
+ return
}
func (self *Tree) SubMirrorSizeBetween(key, min, max []byte, mininc, maxinc bool) (result int) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- result = subTree.MirrorSizeBetween(min, max, mininc, maxinc)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ result = subTree.MirrorSizeBetween(min, max, mininc, maxinc)
+ }
+ return
}
func (self *Tree) SubSizeBetween(key, min, max []byte, mininc, maxinc bool) (result int) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- result = subTree.SizeBetween(min, max, mininc, maxinc)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ result = subTree.SizeBetween(min, max, mininc, maxinc)
+ }
+ return
}
func (self *Tree) SubGet(key, subKey []byte) (byteValue []byte, timestamp int64, existed bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- byteValue, timestamp, existed = subTree.Get(subKey)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ byteValue, timestamp, existed = subTree.Get(subKey)
+ }
+ return
}
func (self *Tree) SubMirrorReverseEachBetween(key, min, max []byte, mininc, maxinc bool, f TreeIterator) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- subTree.MirrorReverseEachBetween(min, max, mininc, maxinc, f)
- }
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ subTree.MirrorReverseEachBetween(min, max, mininc, maxinc, f)
+ }
}
func (self *Tree) SubMirrorEachBetween(key, min, max []byte, mininc, maxinc bool, f TreeIterator) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- subTree.MirrorEachBetween(min, max, mininc, maxinc, f)
- }
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ subTree.MirrorEachBetween(min, max, mininc, maxinc, f)
+ }
}
func (self *Tree) SubMirrorReverseEachBetweenIndex(key []byte, min, max *int, f TreeIndexIterator) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- subTree.MirrorReverseEachBetweenIndex(min, max, f)
- }
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ subTree.MirrorReverseEachBetweenIndex(min, max, f)
+ }
}
func (self *Tree) SubMirrorEachBetweenIndex(key []byte, min, max *int, f TreeIndexIterator) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- subTree.MirrorEachBetweenIndex(min, max, f)
- }
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ subTree.MirrorEachBetweenIndex(min, max, f)
+ }
}
func (self *Tree) SubReverseEachBetween(key, min, max []byte, mininc, maxinc bool, f TreeIterator) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- subTree.ReverseEachBetween(min, max, mininc, maxinc, f)
- }
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ subTree.ReverseEachBetween(min, max, mininc, maxinc, f)
+ }
}
func (self *Tree) SubEachBetween(key, min, max []byte, mininc, maxinc bool, f TreeIterator) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- subTree.EachBetween(min, max, mininc, maxinc, f)
- }
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ subTree.EachBetween(min, max, mininc, maxinc, f)
+ }
}
func (self *Tree) SubReverseEachBetweenIndex(key []byte, min, max *int, f TreeIndexIterator) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- subTree.ReverseEachBetweenIndex(min, max, f)
- }
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ subTree.ReverseEachBetweenIndex(min, max, f)
+ }
}
func (self *Tree) SubEachBetweenIndex(key []byte, min, max *int, f TreeIndexIterator) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- subTree.EachBetweenIndex(min, max, f)
- }
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ subTree.EachBetweenIndex(min, max, f)
+ }
}
func (self *Tree) SubPut(key, subKey []byte, byteValue []byte, timestamp int64) (oldBytes []byte, existed bool) {
- self.lock.Lock()
- defer self.lock.Unlock()
- ripped := Rip(key)
- _, subTree, subTreeTimestamp, ex := self.root.get(ripped)
- if ex&treeValue == 0 || subTree == nil {
- subTree = self.newTreeWith(Rip(subKey), byteValue, timestamp)
- } else {
- oldBytes, existed = subTree.Put(subKey, byteValue, timestamp)
- }
- self.put(ripped, nil, subTree, treeValue, subTreeTimestamp)
- self.log(persistence.Op{
- Key: key,
- SubKey: subKey,
- Value: byteValue,
- Timestamp: timestamp,
- Put: true,
- })
- return
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ ripped := Rip(key)
+ _, subTree, subTreeTimestamp, ex := self.root.get(ripped)
+ if ex&treeValue == 0 || subTree == nil {
+ subTree = self.newTreeWith(Rip(subKey), byteValue, timestamp)
+ } else {
+ oldBytes, existed = subTree.Put(subKey, byteValue, timestamp)
+ }
+ self.put(ripped, nil, subTree, treeValue, subTreeTimestamp)
+ self.log(persistence.Op{
+ Key: key,
+ SubKey: subKey,
+ Value: byteValue,
+ Timestamp: timestamp,
+ Put: true,
+ })
+ return
}
func (self *Tree) SubDel(key, subKey []byte) (oldBytes []byte, existed bool) {
- self.lock.Lock()
- defer self.lock.Unlock()
- ripped := Rip(key)
- if _, subTree, subTreeTimestamp, ex := self.root.get(ripped); ex&treeValue != 0 && subTree != nil {
- oldBytes, existed = subTree.Del(subKey)
- if subTree.RealSize() == 0 {
- self.del(ripped, treeValue)
- } else {
- self.put(ripped, nil, subTree, treeValue, subTreeTimestamp)
- }
- }
- if existed {
- self.log(persistence.Op{
- Key: key,
- SubKey: subKey,
- })
- }
- return
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ ripped := Rip(key)
+ if _, subTree, subTreeTimestamp, ex := self.root.get(ripped); ex&treeValue != 0 && subTree != nil {
+ oldBytes, existed = subTree.Del(subKey)
+ if subTree.RealSize() == 0 {
+ self.del(ripped, treeValue)
+ } else {
+ self.put(ripped, nil, subTree, treeValue, subTreeTimestamp)
+ }
+ }
+ if existed {
+ self.log(persistence.Op{
+ Key: key,
+ SubKey: subKey,
+ })
+ }
+ return
}
func (self *Tree) SubFakeDel(key, subKey []byte, timestamp int64) (oldBytes []byte, existed bool) {
- self.lock.Lock()
- defer self.lock.Unlock()
- ripped := Rip(key)
- if _, subTree, subTreeTimestamp, ex := self.root.get(ripped); ex&treeValue != 0 && subTree != nil {
- oldBytes, _, existed = subTree.FakeDel(subKey, timestamp)
- self.put(ripped, nil, subTree, treeValue, subTreeTimestamp)
- }
- if existed {
- self.log(persistence.Op{
- Key: key,
- SubKey: subKey,
- })
- }
- return
-}
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ ripped := Rip(key)
+ if _, subTree, subTreeTimestamp, ex := self.root.get(ripped); ex&treeValue != 0 && subTree != nil {
+ oldBytes, _, existed = subTree.FakeDel(subKey, timestamp)
+ self.put(ripped, nil, subTree, treeValue, subTreeTimestamp)
+ }
+ if existed {
+ self.log(persistence.Op{
+ Key: key,
+ SubKey: subKey,
+ })
+ }
+ return
+}
+
+// SubClear does Clear on the sub tree.
func (self *Tree) SubClear(key []byte, timestamp int64) (deleted int) {
- self.lock.Lock()
- defer self.lock.Unlock()
- ripped := Rip(key)
- if _, subTree, subTreeTimestamp, ex := self.root.get(ripped); ex&treeValue != 0 && subTree != nil {
- deleted = subTree.Size()
- subTree.Clear(timestamp)
- self.put(ripped, nil, subTree, treeValue, subTreeTimestamp)
- }
- if deleted > 0 {
- self.log(persistence.Op{
- Key: key,
- Clear: true,
- Timestamp: timestamp,
- })
- }
- return
-}
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ ripped := Rip(key)
+ if _, subTree, subTreeTimestamp, ex := self.root.get(ripped); ex&treeValue != 0 && subTree != nil {
+ deleted = subTree.Size()
+ subTree.Clear(timestamp)
+ self.put(ripped, nil, subTree, treeValue, subTreeTimestamp)
+ }
+ if deleted > 0 {
+ self.log(persistence.Op{
+ Key: key,
+ Clear: true,
+ Timestamp: timestamp,
+ })
+ }
+ return
+}
+
+// SubKill will completely remove the sub tree.
func (self *Tree) SubKill(key []byte) (deleted int) {
- self.lock.Lock()
- defer self.lock.Unlock()
- ripped := Rip(key)
- if _, subTree, _, ex := self.root.get(ripped); ex&treeValue != 0 && subTree != nil {
- deleted = subTree.Size()
- self.del(ripped, treeValue)
- }
- if deleted > 0 {
- self.log(persistence.Op{
- Key: key,
- Clear: true,
- })
- }
- return
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ ripped := Rip(key)
+ if _, subTree, _, ex := self.root.get(ripped); ex&treeValue != 0 && subTree != nil {
+ deleted = subTree.Size()
+ self.del(ripped, treeValue)
+ }
+ if deleted > 0 {
+ self.log(persistence.Op{
+ Key: key,
+ Clear: true,
+ })
+ }
+ return
}
func (self *Tree) Finger(key []Nibble) *Print {
- self.lock.RLock()
- defer self.lock.RUnlock()
- return self.root.finger(&Print{}, key)
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ return self.root.finger(&Print{}, key)
}
func (self *Tree) GetTimestamp(key []Nibble) (bValue []byte, timestamp int64, present bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- bValue, _, timestamp, ex := self.root.get(key)
- present = ex&byteValue != 0
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ bValue, _, timestamp, ex := self.root.get(key)
+ present = ex&byteValue != 0
+ return
}
func (self *Tree) putTimestamp(key []Nibble, bValue []byte, treeValue *Tree, nodeUse, insertUse int, expected, timestamp int64) (result bool, oldBytes []byte) {
- if _, _, current, _ := self.root.get(key); current == expected {
- self.dataTimestamp, result = timestamp, true
- self.root, oldBytes, _, _, _ = self.root.insertHelp(nil, newNode(key, bValue, treeValue, timestamp, false, nodeUse), insertUse, self.timer.ContinuousTime())
- }
- return
+ if _, _, current, _ := self.root.get(key); current == expected {
+ self.dataTimestamp, result = timestamp, true
+ self.root, oldBytes, _, _, _ = self.root.insertHelp(nil, newNode(key, bValue, treeValue, timestamp, false, nodeUse), insertUse, self.timer.ContinuousTime())
+ }
+ return
}
func (self *Tree) PutTimestamp(key []Nibble, bValue []byte, present bool, expected, timestamp int64) (result bool) {
- self.lock.Lock()
- defer self.lock.Unlock()
- nodeUse := 0
- if present {
- nodeUse = byteValue
- }
- var oldBytes []byte
- result, oldBytes = self.putTimestamp(key, bValue, nil, nodeUse, byteValue, expected, timestamp)
- if result {
- stitched := Stitch(key)
- self.mirrorDel(stitched, oldBytes)
- self.mirrorPut(stitched, bValue, timestamp)
- self.log(persistence.Op{
- Key: Stitch(key),
- Value: bValue,
- Timestamp: timestamp,
- Put: true,
- })
- }
- return
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ nodeUse := 0
+ if present {
+ nodeUse = byteValue
+ }
+ var oldBytes []byte
+ result, oldBytes = self.putTimestamp(key, bValue, nil, nodeUse, byteValue, expected, timestamp)
+ if result {
+ stitched := Stitch(key)
+ self.mirrorDel(stitched, oldBytes)
+ self.mirrorPut(stitched, bValue, timestamp)
+ self.log(persistence.Op{
+ Key: Stitch(key),
+ Value: bValue,
+ Timestamp: timestamp,
+ Put: true,
+ })
+ }
+ return
}
func (self *Tree) delTimestamp(key []Nibble, use int, expected int64) (result bool, oldBytes []byte) {
- if _, _, current, _ := self.root.get(key); current == expected {
- result = true
- self.root, oldBytes, _, _, _ = self.root.del(nil, key, use, self.timer.ContinuousTime())
- }
- return
+ if _, _, current, _ := self.root.get(key); current == expected {
+ result = true
+ self.root, oldBytes, _, _, _ = self.root.del(nil, key, use, self.timer.ContinuousTime())
+ }
+ return
}
func (self *Tree) DelTimestamp(key []Nibble, expected int64) (result bool) {
- self.lock.Lock()
- defer self.lock.Unlock()
- var oldBytes []byte
- result, oldBytes = self.delTimestamp(key, byteValue, expected)
- if result {
- self.mirrorDel(Stitch(key), oldBytes)
- self.log(persistence.Op{
- Key: Stitch(key),
- })
- }
- return
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ var oldBytes []byte
+ result, oldBytes = self.delTimestamp(key, byteValue, expected)
+ if result {
+ self.mirrorDel(Stitch(key), oldBytes)
+ self.log(persistence.Op{
+ Key: Stitch(key),
+ })
+ }
+ return
}
func (self *Tree) subConfiguration(key []byte) (conf map[string]string, timestamp int64) {
- if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
- conf, timestamp = subTree.Configuration()
- } else {
- conf = make(map[string]string)
- }
- return
+ if _, subTree, _, ex := self.root.get(Rip(key)); ex&treeValue != 0 && subTree != nil {
+ conf, timestamp = subTree.Configuration()
+ } else {
+ conf = make(map[string]string)
+ }
+ return
}
func (self *Tree) SubConfiguration(key []byte) (conf map[string]string, timestamp int64) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- return self.subConfiguration(key)
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ return self.subConfiguration(key)
}
func (self *Tree) subConfigure(key []byte, conf map[string]string, timestamp int64) {
- ripped := Rip(key)
- _, subTree, subTreeTimestamp, ex := self.root.get(ripped)
- if ex&treeValue == 0 || subTree == nil {
- subTree = NewTreeTimer(self.timer)
- }
- subTree.Configure(conf, timestamp)
- self.put(ripped, nil, subTree, treeValue, subTreeTimestamp)
- self.log(persistence.Op{
- Key: key,
- Configuration: conf,
- Timestamp: timestamp,
- })
+ ripped := Rip(key)
+ _, subTree, subTreeTimestamp, ex := self.root.get(ripped)
+ if ex&treeValue == 0 || subTree == nil {
+ subTree = NewTreeTimer(self.timer)
+ }
+ subTree.Configure(conf, timestamp)
+ self.put(ripped, nil, subTree, treeValue, subTreeTimestamp)
+ self.log(persistence.Op{
+ Key: key,
+ Configuration: conf,
+ Timestamp: timestamp,
+ })
}
func (self *Tree) SubConfigure(key []byte, conf map[string]string, timestamp int64) {
- self.lock.Lock()
- defer self.lock.Unlock()
- self.subConfigure(key, conf, timestamp)
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ self.subConfigure(key, conf, timestamp)
}
func (self *Tree) SubAddConfiguration(treeKey []byte, ts int64, key, value string) bool {
- self.lock.Lock()
- defer self.lock.Unlock()
- oldConf, _ := self.subConfiguration(treeKey)
- if oldConf[key] != value {
- oldConf[key] = value
- self.subConfigure(treeKey, oldConf, ts)
- return true
- }
- return false
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ oldConf, _ := self.subConfiguration(treeKey)
+ if oldConf[key] != value {
+ oldConf[key] = value
+ self.subConfigure(treeKey, oldConf, ts)
+ return true
+ }
+ return false
}
func (self *Tree) SubFinger(key, subKey []Nibble) (result *Print) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(key); ex&treeValue != 0 && subTree != nil {
- result = subTree.Finger(subKey)
- } else {
- result = &Print{}
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(key); ex&treeValue != 0 && subTree != nil {
+ result = subTree.Finger(subKey)
+ } else {
+ result = &Print{}
+ }
+ return
}
func (self *Tree) SubGetTimestamp(key, subKey []Nibble) (byteValue []byte, timestamp int64, present bool) {
- self.lock.RLock()
- defer self.lock.RUnlock()
- if _, subTree, _, ex := self.root.get(key); ex&treeValue != 0 && subTree != nil {
- byteValue, timestamp, present = subTree.GetTimestamp(subKey)
- }
- return
+ self.lock.RLock()
+ defer self.lock.RUnlock()
+ if _, subTree, _, ex := self.root.get(key); ex&treeValue != 0 && subTree != nil {
+ byteValue, timestamp, present = subTree.GetTimestamp(subKey)
+ }
+ return
}
func (self *Tree) SubPutTimestamp(key, subKey []Nibble, bValue []byte, present bool, subExpected, subTimestamp int64) (result bool) {
- self.lock.Lock()
- defer self.lock.Unlock()
- _, subTree, subTreeTimestamp, _ := self.root.get(key)
- if subTree == nil {
- result = true
- subTree = self.newTreeWith(subKey, bValue, subTimestamp)
- } else {
- result = subTree.PutTimestamp(subKey, bValue, present, subExpected, subTimestamp)
- }
- self.putTimestamp(key, nil, subTree, treeValue, treeValue, subTreeTimestamp, subTreeTimestamp)
- if result {
- self.log(persistence.Op{
- Key: Stitch(key),
- SubKey: Stitch(subKey),
- Value: bValue,
- Timestamp: subTimestamp,
- Put: true,
- })
- }
- return
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ _, subTree, subTreeTimestamp, _ := self.root.get(key)
+ if subTree == nil {
+ result = true
+ subTree = self.newTreeWith(subKey, bValue, subTimestamp)
+ } else {
+ result = subTree.PutTimestamp(subKey, bValue, present, subExpected, subTimestamp)
+ }
+ self.putTimestamp(key, nil, subTree, treeValue, treeValue, subTreeTimestamp, subTreeTimestamp)
+ if result {
+ self.log(persistence.Op{
+ Key: Stitch(key),
+ SubKey: Stitch(subKey),
+ Value: bValue,
+ Timestamp: subTimestamp,
+ Put: true,
+ })
+ }
+ return
}
func (self *Tree) SubDelTimestamp(key, subKey []Nibble, subExpected int64) (result bool) {
- self.lock.Lock()
- defer self.lock.Unlock()
- if _, subTree, subTreeTimestamp, ex := self.root.get(key); ex&treeValue != 0 && subTree != nil {
- result = subTree.DelTimestamp(subKey, subExpected)
- if subTree.Size() == 0 {
- self.delTimestamp(key, treeValue, subTreeTimestamp)
- } else {
- self.putTimestamp(key, nil, subTree, treeValue, treeValue, subTreeTimestamp, subTreeTimestamp)
- }
- }
- if result {
- self.log(persistence.Op{
- Key: Stitch(key),
- SubKey: Stitch(subKey),
- })
- }
- return
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ if _, subTree, subTreeTimestamp, ex := self.root.get(key); ex&treeValue != 0 && subTree != nil {
+ result = subTree.DelTimestamp(subKey, subExpected)
+ if subTree.Size() == 0 {
+ self.delTimestamp(key, treeValue, subTreeTimestamp)
+ } else {
+ self.putTimestamp(key, nil, subTree, treeValue, treeValue, subTreeTimestamp, subTreeTimestamp)
+ }
+ }
+ if result {
+ self.log(persistence.Op{
+ Key: Stitch(key),
+ SubKey: Stitch(subKey),
+ })
+ }
+ return
}
func (self *Tree) SubClearTimestamp(key []Nibble, expected, timestamp int64) (deleted int) {
- self.lock.Lock()
- defer self.lock.Unlock()
- if _, subTree, subTreeTimestamp, ex := self.root.get(key); ex&treeValue != 0 && subTree != nil && subTree.DataTimestamp() == expected {
- deleted = subTree.Size()
- subTree.Clear(timestamp)
- self.putTimestamp(key, nil, subTree, treeValue, treeValue, subTreeTimestamp, subTreeTimestamp)
- }
- if deleted > 0 {
- self.log(persistence.Op{
- Key: Stitch(key),
- Clear: true,
- Timestamp: timestamp,
- })
- }
- return
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ if _, subTree, subTreeTimestamp, ex := self.root.get(key); ex&treeValue != 0 && subTree != nil && subTree.DataTimestamp() == expected {
+ deleted = subTree.Size()
+ subTree.Clear(timestamp)
+ self.putTimestamp(key, nil, subTree, treeValue, treeValue, subTreeTimestamp, subTreeTimestamp)
+ }
+ if deleted > 0 {
+ self.log(persistence.Op{
+ Key: Stitch(key),
+ Clear: true,
+ Timestamp: timestamp,
+ })
+ }
+ return
}
func (self *Tree) SubKillTimestamp(key []Nibble, expected int64) (deleted int) {
- self.lock.Lock()
- defer self.lock.Unlock()
- if _, subTree, subTreeTimestamp, ex := self.root.get(key); ex&treeValue != 0 && subTree != nil && subTree.DataTimestamp() == expected {
- deleted = subTree.Size()
- self.delTimestamp(key, treeValue, subTreeTimestamp)
- }
- if deleted > 0 {
- self.log(persistence.Op{
- Key: Stitch(key),
- Clear: true,
- })
- }
- return
+ self.lock.Lock()
+ defer self.lock.Unlock()
+ if _, subTree, subTreeTimestamp, ex := self.root.get(key); ex&treeValue != 0 && subTree != nil && subTree.DataTimestamp() == expected {
+ deleted = subTree.Size()
+ self.delTimestamp(key, treeValue, subTreeTimestamp)
+ }
+ if deleted > 0 {
+ self.log(persistence.Op{
+ Key: Stitch(key),
+ Clear: true,
+ })
+ }
+ return
}
diff --git a/setop/README.md b/setop/README.md
deleted file mode 100644
index 4f98f34..0000000
--- a/setop/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-setop
-===
-
-A bunch of functionality that does set operations on sorted and skippable sets.
diff --git a/setop/merges.go b/setop/merges.go
deleted file mode 100644
index cc9a049..0000000
--- a/setop/merges.go
+++ /dev/null
@@ -1,335 +0,0 @@
-package setop
-
-import (
- "bytes"
- "encoding/binary"
- "fmt"
- "github.com/zond/god/common"
- "math/big"
-)
-
-type mergeFunc func(oldValues [][]byte, newValues [][]byte, weightForNewValues float64) (result [][]byte)
-
-func getMerger(m SetOpMerge) mergeFunc {
- switch m {
- case Append:
- return _append
- case ConCat:
- return conCat
- case IntegerSum:
- return integerSum
- case IntegerDiv:
- return integerDiv
- case IntegerMul:
- return integerMul
- case FloatSum:
- return floatSum
- case FloatDiv:
- return floatDiv
- case FloatMul:
- return floatMul
- case BigIntAnd:
- return bigIntAnd
- case BigIntAdd:
- return bigIntAdd
- case BigIntAndNot:
- return bigIntAndNot
- case BigIntDiv:
- return bigIntDiv
- case BigIntMod:
- return bigIntMod
- case BigIntMul:
- return bigIntMul
- case BigIntOr:
- return bigIntOr
- case BigIntRem:
- return bigIntRem
- case BigIntXor:
- return bigIntXor
- case First:
- return first
- case Last:
- return last
- }
- panic(fmt.Errorf("Unknown SetOpType %v", int(m)))
-}
-
-func last(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- return [][]byte{newValues[len(newValues)-1]}
-}
-func first(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- if oldValues == nil {
- return [][]byte{newValues[0]}
- }
- return [][]byte{oldValues[0]}
-}
-func _append(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- result = oldValues
- for i := 0; i < int(w); i++ {
- result = append(result, newValues...)
- }
- return
-}
-func conCat(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- var res []byte
- for _, b := range oldValues {
- res = append(res, b...)
- }
- for i := 0; i < int(w); i++ {
- for _, b := range newValues {
- res = append(res, b...)
- }
- }
- return [][]byte{res}
-}
-func integerSum(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- var sum int64
- var tmp int64
- var err error
- for _, b := range oldValues {
- if tmp, err = common.DecodeInt64(b); err == nil {
- sum += tmp
- }
- }
- for _, b := range newValues {
- if tmp, err = common.DecodeInt64(b); err == nil {
- sum += (tmp * int64(w))
- }
- }
- res := new(bytes.Buffer)
- binary.Write(res, binary.BigEndian, sum)
- return [][]byte{res.Bytes()}
-}
-func integerDiv(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- var sum int64
- var tmp int64
- var err error
- if oldValues != nil {
- if tmp, err = common.DecodeInt64(oldValues[0]); err == nil {
- sum = tmp
- }
- for _, b := range newValues {
- if tmp, err = common.DecodeInt64(b); err == nil {
- sum /= (tmp * int64(w))
- }
- }
- } else {
- if tmp, err = common.DecodeInt64(newValues[0]); err == nil {
- sum = (tmp * int64(w))
- }
- for _, b := range newValues[1:] {
- if tmp, err = common.DecodeInt64(b); err == nil {
- sum /= (tmp * int64(w))
- }
- }
- }
- res := new(bytes.Buffer)
- binary.Write(res, binary.BigEndian, sum)
- return [][]byte{res.Bytes()}
-}
-func integerMul(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- var sum int64 = 1
- var tmp int64
- var err error
- for _, b := range oldValues {
- if tmp, err = common.DecodeInt64(b); err == nil {
- sum *= tmp
- }
- }
- for _, b := range newValues {
- if tmp, err = common.DecodeInt64(b); err == nil {
- sum *= (tmp * int64(w))
- }
- }
- res := new(bytes.Buffer)
- binary.Write(res, binary.BigEndian, sum)
- return [][]byte{res.Bytes()}
-}
-func floatSum(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- var sum float64
- var tmp float64
- var err error
- for _, b := range oldValues {
- if tmp, err = common.DecodeFloat64(b); err == nil {
- sum += tmp
- }
- }
- for _, b := range newValues {
- if tmp, err = common.DecodeFloat64(b); err == nil {
- sum += (tmp * w)
- }
- }
- res := new(bytes.Buffer)
- binary.Write(res, binary.BigEndian, sum)
- return [][]byte{res.Bytes()}
-}
-func floatDiv(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- var sum float64
- var tmp float64
- var err error
- if oldValues != nil {
- if tmp, err = common.DecodeFloat64(oldValues[0]); err == nil {
- sum = tmp
- }
- for _, b := range newValues {
- if tmp, err = common.DecodeFloat64(b); err == nil {
- sum /= (tmp * w)
- }
- }
- } else {
- if tmp, err = common.DecodeFloat64(newValues[0]); err == nil {
- sum = (tmp * w)
- }
- for _, b := range newValues[1:] {
- if tmp, err = common.DecodeFloat64(b); err == nil {
- sum /= (tmp * w)
- }
- }
- }
- res := new(bytes.Buffer)
- binary.Write(res, binary.BigEndian, sum)
- return [][]byte{res.Bytes()}
-}
-func floatMul(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- var sum float64 = 1
- var tmp float64
- var err error
- for _, b := range oldValues {
- if tmp, err = common.DecodeFloat64(b); err == nil {
- sum *= tmp
- }
- }
- for _, b := range newValues {
- if tmp, err = common.DecodeFloat64(b); err == nil {
- sum *= (tmp * w)
- }
- }
- res := new(bytes.Buffer)
- binary.Write(res, binary.BigEndian, sum)
- return [][]byte{res.Bytes()}
-}
-func bigIntAnd(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- var sum *big.Int
- if oldValues != nil {
- sum = new(big.Int).SetBytes(oldValues[0])
- for _, b := range newValues {
- sum.And(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- } else {
- sum = new(big.Int).Mul(new(big.Int).SetBytes(newValues[0]), big.NewInt(int64(w)))
- for _, b := range newValues[1:] {
- sum.And(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- }
- return [][]byte{sum.Bytes()}
-}
-func bigIntAdd(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- sum := new(big.Int)
- for _, b := range oldValues {
- sum.Add(sum, common.DecodeBigInt(b))
- }
- for _, b := range newValues {
- sum.Add(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- return [][]byte{sum.Bytes()}
-}
-func bigIntAndNot(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- var sum *big.Int
- if oldValues != nil {
- sum = new(big.Int).SetBytes(oldValues[0])
- for _, b := range newValues {
- sum.AndNot(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- } else {
- sum = new(big.Int).Mul(new(big.Int).SetBytes(newValues[0]), big.NewInt(int64(w)))
- for _, b := range newValues[1:] {
- sum.AndNot(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- }
- return [][]byte{sum.Bytes()}
-}
-func bigIntDiv(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- var sum *big.Int
- if oldValues != nil {
- sum = new(big.Int).SetBytes(oldValues[0])
- for _, b := range newValues {
- sum.Div(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- } else {
- sum = new(big.Int).Mul(new(big.Int).SetBytes(newValues[0]), big.NewInt(int64(w)))
- for _, b := range newValues[1:] {
- sum.Div(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- }
- return [][]byte{sum.Bytes()}
-}
-func bigIntMod(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- var sum *big.Int
- if oldValues != nil {
- sum = new(big.Int).SetBytes(oldValues[0])
- for _, b := range newValues {
- sum.Mod(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- } else {
- sum = new(big.Int).Mul(new(big.Int).SetBytes(newValues[0]), big.NewInt(int64(w)))
- for _, b := range newValues[1:] {
- sum.Mod(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- }
- return [][]byte{sum.Bytes()}
-}
-func bigIntMul(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- sum := big.NewInt(1)
- for _, b := range oldValues {
- sum.Mul(sum, common.DecodeBigInt(b))
- }
- for _, b := range newValues {
- sum.Mul(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- return [][]byte{sum.Bytes()}
-}
-func bigIntOr(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- var sum *big.Int
- if oldValues != nil {
- sum = new(big.Int).SetBytes(oldValues[0])
- for _, b := range newValues {
- sum.Or(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- } else {
- sum = new(big.Int).Mul(new(big.Int).SetBytes(newValues[0]), big.NewInt(int64(w)))
- for _, b := range newValues[1:] {
- sum.Or(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- }
- return [][]byte{sum.Bytes()}
-}
-func bigIntRem(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- var sum *big.Int
- if oldValues != nil {
- sum = new(big.Int).SetBytes(oldValues[0])
- for _, b := range newValues {
- sum.Rem(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- } else {
- sum = new(big.Int).Mul(new(big.Int).SetBytes(newValues[0]), big.NewInt(int64(w)))
- for _, b := range newValues[1:] {
- sum.Rem(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- }
- return [][]byte{sum.Bytes()}
-}
-func bigIntXor(oldValues [][]byte, newValues [][]byte, w float64) (result [][]byte) {
- var sum *big.Int
- if oldValues != nil {
- sum = new(big.Int).SetBytes(oldValues[0])
- for _, b := range newValues {
- sum.Xor(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- } else {
- sum = new(big.Int).Mul(new(big.Int).SetBytes(newValues[0]), big.NewInt(int64(w)))
- for _, b := range newValues[1:] {
- sum.Xor(sum, new(big.Int).Mul(common.DecodeBigInt(b), big.NewInt(int64(w))))
- }
- }
- return [][]byte{sum.Bytes()}
-}
diff --git a/setop/operations.go b/setop/operations.go
deleted file mode 100644
index 3cb53c5..0000000
--- a/setop/operations.go
+++ /dev/null
@@ -1,305 +0,0 @@
-package setop
-
-import (
- "bytes"
- "fmt"
-)
-
-type Skipper interface {
- // skip returns a value matching the min and inclusive criteria.
- // If the last yielded value matches the criteria the same value will be returned again.
- Skip(min []byte, inc bool) (result *SetOpResult, err error)
-}
-
-func createSkippersAndWeights(r RawSourceCreator, sources []SetOpSource) (skippers []Skipper, weights []float64) {
- skippers = make([]Skipper, len(sources))
- weights = make([]float64, len(sources))
- for index, source := range sources {
- if source.Key != nil {
- skippers[index] = r(source.Key)
- } else {
- skippers[index] = createSkipper(r, source.SetOp)
- }
- if source.Weight != nil {
- weights[index] = *source.Weight
- } else {
- weights[index] = 1
- }
- }
- return
-}
-
-func createSkipper(r RawSourceCreator, op *SetOp) (result Skipper) {
- skippers, weights := createSkippersAndWeights(r, op.Sources)
- switch op.Type {
- case Union:
- result = &unionOp{
- skippers: skippers,
- weights: weights,
- merger: getMerger(op.Merge),
- }
- case Intersection:
- result = &interOp{
- skippers: skippers,
- weights: weights,
- merger: getMerger(op.Merge),
- }
- case Difference:
- result = &diffOp{
- skippers: skippers,
- weights: weights,
- merger: getMerger(op.Merge),
- }
- case Xor:
- result = &xorOp{
- skippers: skippers,
- weights: weights,
- merger: getMerger(op.Merge),
- }
- default:
- panic(fmt.Errorf("Unknown SetOp Type %v", op.Type))
- }
- return
-}
-
-type xorOp struct {
- skippers []Skipper
- weights []float64
- curr *SetOpResult
- merger mergeFunc
-}
-
-func (self *xorOp) Skip(min []byte, inc bool) (result *SetOpResult, err error) {
- gt := 0
- if inc {
- gt = -1
- }
-
- if self.curr != nil && bytes.Compare(self.curr.Key, min) > gt {
- result = self.curr
- return
- }
-
- newSkippers := make([]Skipper, 0, len(self.skippers))
-
- var res *SetOpResult
- var cmp int
- var multi bool
-
- for result == nil {
- for index, thisSkipper := range self.skippers {
- if res, err = thisSkipper.Skip(min, inc); err != nil {
- result = nil
- self.curr = nil
- return
- }
- if res != nil {
- newSkippers = append(newSkippers, thisSkipper)
- if result == nil {
- result = res.ShallowCopy()
- result.Values = self.merger(nil, result.Values, self.weights[index])
- multi = false
- } else {
- cmp = bytes.Compare(res.Key, result.Key)
- if cmp < 0 {
- multi = false
- result = res.ShallowCopy()
- result.Values = self.merger(nil, result.Values, self.weights[index])
- } else if cmp == 0 {
- multi = true
- }
- }
- }
- }
-
- if len(newSkippers) == 0 {
- result = nil
- self.curr = nil
- return
- }
-
- if result != nil && multi {
- min = result.Key
- inc = false
- result = nil
- }
-
- self.skippers = newSkippers
- newSkippers = newSkippers[:0]
-
- }
-
- self.curr = result
-
- return
-}
-
-type unionOp struct {
- skippers []Skipper
- weights []float64
- curr *SetOpResult
- merger mergeFunc
-}
-
-func (self *unionOp) Skip(min []byte, inc bool) (result *SetOpResult, err error) {
- gt := 0
- if inc {
- gt = -1
- }
-
- if self.curr != nil && bytes.Compare(self.curr.Key, min) > gt {
- result = self.curr
- return
- }
-
- newSkippers := make([]Skipper, 0, len(self.skippers))
-
- var cmp int
- var res *SetOpResult
-
- for index, thisSkipper := range self.skippers {
- if res, err = thisSkipper.Skip(min, inc); err != nil {
- result = nil
- self.curr = nil
- return
- }
- if res != nil {
- newSkippers = append(newSkippers, thisSkipper)
- if result == nil {
- result = res.ShallowCopy()
- result.Values = self.merger(nil, result.Values, self.weights[index])
- } else {
- cmp = bytes.Compare(res.Key, result.Key)
- if cmp < 0 {
- result = res.ShallowCopy()
- result.Values = self.merger(nil, result.Values, self.weights[index])
- } else if cmp == 0 {
- result.Values = self.merger(result.Values, res.Values, self.weights[index])
- }
- }
- }
- }
-
- self.skippers = newSkippers
-
- self.curr = result
-
- return
-}
-
-type interOp struct {
- skippers []Skipper
- weights []float64
- curr *SetOpResult
- merger mergeFunc
-}
-
-func (self *interOp) Skip(min []byte, inc bool) (result *SetOpResult, err error) {
- gt := 0
- if inc {
- gt = -1
- }
-
- if self.curr != nil && bytes.Compare(self.curr.Key, min) > gt {
- result = self.curr
- return
- }
-
- var maxKey []byte
- var res *SetOpResult
- var cmp int
-
- for result == nil {
- maxKey = nil
- for index, thisSkipper := range self.skippers {
- if res, err = thisSkipper.Skip(min, inc); res == nil || err != nil {
- result = nil
- self.curr = nil
- return
- }
- if maxKey == nil {
- maxKey = res.Key
- result = res.ShallowCopy()
- result.Values = self.merger(nil, result.Values, self.weights[index])
- } else {
- cmp = bytes.Compare(res.Key, maxKey)
- if cmp != 0 {
- if cmp > 0 {
- maxKey = res.Key
- }
- result = nil
- } else {
- result.Values = self.merger(result.Values, res.Values, self.weights[index])
- }
- }
- }
-
- min = maxKey
- inc = true
- }
-
- self.curr = result
-
- return
-}
-
-type diffOp struct {
- skippers []Skipper
- weights []float64
- curr *SetOpResult
- merger mergeFunc
-}
-
-func (self *diffOp) Skip(min []byte, inc bool) (result *SetOpResult, err error) {
- gt := 0
- if inc {
- gt = -1
- }
-
- if self.curr != nil && bytes.Compare(self.curr.Key, min) > gt {
- result = self.curr
- return
- }
-
- var newSkippers = make([]Skipper, 0, len(self.skippers))
- var res *SetOpResult
-
- for result == nil {
- for index, thisSkipper := range self.skippers {
- if res, err = thisSkipper.Skip(min, inc); err != nil {
- result = nil
- self.curr = nil
- return
- }
- if index == 0 {
- if res == nil {
- result = nil
- self.curr = nil
- return
- }
- result = res.ShallowCopy()
- result.Values = self.merger(nil, result.Values, self.weights[0])
- newSkippers = append(newSkippers, thisSkipper)
- min = res.Key
- inc = true
- } else {
- if res != nil {
- newSkippers = append(newSkippers, thisSkipper)
- if bytes.Compare(min, res.Key) == 0 {
- result = nil
- break
- }
- }
- }
- }
-
- self.skippers = newSkippers
- newSkippers = newSkippers[:0]
- inc = false
-
- }
-
- self.curr = result
-
- return
-}
diff --git a/setop/parser_test.go b/setop/parser_test.go
deleted file mode 100644
index 7e8eacb..0000000
--- a/setop/parser_test.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package setop
-
-import (
- "reflect"
- "testing"
-)
-
-func TestSetOpParser(t *testing.T) {
- var x2 float64 = 2
- var x3 float64 = 3
- op, err := NewSetOpParser("(U (I ccc aa (D ffff*2 gg)*3) (I:ConCat c23 b_ff) (X dbla e&44))").Parse()
- if err != nil {
- t.Error(err)
- }
- cmp := &SetOp{
- Type: Union,
- Sources: []SetOpSource{
- SetOpSource{
- SetOp: &SetOp{
- Type: Intersection,
- Sources: []SetOpSource{
- SetOpSource{Key: []byte("ccc")},
- SetOpSource{Key: []byte("aa")},
- SetOpSource{
- SetOp: &SetOp{
- Type: Difference,
- Sources: []SetOpSource{
- SetOpSource{Key: []byte("ffff"), Weight: &x2},
- SetOpSource{Key: []byte("gg")},
- },
- },
- Weight: &x3,
- },
- },
- },
- },
- SetOpSource{
- SetOp: &SetOp{
- Type: Intersection,
- Merge: ConCat,
- Sources: []SetOpSource{
- SetOpSource{Key: []byte("c23")},
- SetOpSource{Key: []byte("b_ff")},
- },
- },
- },
- SetOpSource{
- SetOp: &SetOp{
- Type: Xor,
- Sources: []SetOpSource{
- SetOpSource{Key: []byte("dbla")},
- SetOpSource{Key: []byte("e&44")},
- },
- },
- },
- },
- }
- if !reflect.DeepEqual(op, cmp) {
- t.Errorf("%v and %v should be equal", op, cmp)
- }
-}
diff --git a/setop/set_op.go b/setop/set_op.go
deleted file mode 100644
index 70b5774..0000000
--- a/setop/set_op.go
+++ /dev/null
@@ -1,259 +0,0 @@
-package setop
-
-import (
- "bytes"
- "fmt"
- "strings"
-)
-
-// RawSourceCreator is a function that takes the name of a raw skippable sortable set, and returns a Skipper interface.
-type RawSourceCreator func(b []byte) Skipper
-
-// SetOpResultIterator is something that handles the results of a SetExpression.
-type SetOpResultIterator func(res *SetOpResult)
-
-const (
- // Append simply appends all elements in the input lists and builds an output list from them.
- Append = iota
- // ConCat appends all elements in the input lists into a single element, and builds an output list with only that element.
- ConCat
- // IntegerSum decodes all values as int64 using common.DecodeInt64 and sums them.
- IntegerSum
- // IntegerDiv decodes all values as int64 using common.DecodeInt64 and divides the first value in the input lists by all other values in turn.
- IntegerDiv
- // IntegerMul decodes all values as int64 using common.DecodeInt64 and multiplies them with each other.
- IntegerMul
- // FloatSum decodes all values as float64 using common.DecodeFloat64 and sums them.
- FloatSum
- // FloatDiv decodes all values as float64 using common.DecodeFloat64 and divides the first value in the input lists by all other values in turn.
- FloatDiv
- // FloatMul decodes all values as float64 using common.DecodeFloat64 and multiplies them with each other.
- FloatMul
- // BigIntAnd decodes all values as big.Ints using common.DecodeBigInt and logical ANDs them with each other.
- BigIntAnd
- // BigIntAdd decodes all values as big.Ints using common.DecodeBigInt and sums them.
- BigIntAdd
- // BigIntAndNot decodes all values as big.Ints using common.DecodeBigInt and logcal AND NOTs them with each other.
- BigIntAndNot
- // BigIntDiv decodes all values as big.Ints using common.DecodeBigInt and divides the first value in the input lists by all other values in them.
- BigIntDiv
- // BigIntMod decodes all values as big.Ints using common.DecodeBigInt and does a modulo operation on each one in turn, with the first one as source value.
- BigIntMod
- // BigIntMul decodes all values as big.Ints using common.DecodeBigInt and multiplies them with each other.
- BigIntMul
- // BigIntOr decodes all values as big.Ints using common.DecodeBigInt and logical ORs them with each other.
- BigIntOr
- // BigIntRem decodes all values as big.Ints using common.DecodeBigInt and does a remainder operation on each one in turn, with the first one as source value.
- BigIntRem
- // BigIntXor decodes all values as big.Ints using common.DecodeBigInt and logical XORs them with each other.
- BigIntXor
- // First will simply return the first slice from the inputs.
- First
- // Last will simply return the last slice from the inputs.
- Last
-)
-
-// SetOpMerge defines how a SetOp merges the values in the input sets.
-type SetOpMerge int
-
-func ParseSetOpMerge(s string) (result SetOpMerge, err error) {
- switch s {
- case "Append":
- result = Append
- case "ConCat":
- result = ConCat
- case "IntegerSum":
- result = IntegerSum
- case "IntegerDiv":
- result = IntegerDiv
- case "IntegerMul":
- result = IntegerMul
- case "FloatSum":
- result = FloatSum
- case "FloatDiv":
- result = FloatDiv
- case "FloatMul":
- result = FloatMul
- case "BigIntAnd":
- result = BigIntAnd
- case "BigIntAdd":
- result = BigIntAdd
- case "BigIntAndNot":
- result = BigIntAndNot
- case "BigIntDiv":
- result = BigIntDiv
- case "BigIntMod":
- result = BigIntMod
- case "BigIntMul":
- result = BigIntMul
- case "BigIntOr":
- result = BigIntOr
- case "BigIntRem":
- result = BigIntRem
- case "BigIntXor":
- result = BigIntXor
- case "First":
- result = First
- case "Last":
- result = Last
- default:
- err = fmt.Errorf("Unknown SetOpType %v. Legal values: Append, ConCat, IntegerSum, IntegerDiv, IntegerMul, FloatSum, FloatDiv, FloatMul, BigIntAdd, BigIntAnd, BigIntAndNot, BigIntDiv, BigIntMod, BigIntMul, BigIntOr, BigIntRem, BigIntXor, First, Last.", s)
- }
- return
-}
-
-func (self SetOpMerge) String() string {
- switch self {
- case Append:
- return "Append"
- case ConCat:
- return "ConCat"
- case IntegerSum:
- return "IntegerSum"
- case IntegerDiv:
- return "IntegerDiv"
- case IntegerMul:
- return "IntegerMul"
- case FloatSum:
- return "FloatSum"
- case FloatDiv:
- return "FloatDiv"
- case FloatMul:
- return "FloatMul"
- case BigIntAnd:
- return "BigIntAnd"
- case BigIntAdd:
- return "BigIntAdd"
- case BigIntAndNot:
- return "BigIntAndNot"
- case BigIntDiv:
- return "BigIntDiv"
- case BigIntMod:
- return "BigIntMod"
- case BigIntMul:
- return "BigIntMul"
- case BigIntOr:
- return "BigIntOr"
- case BigIntRem:
- return "BigIntRem"
- case BigIntXor:
- return "BigIntXor"
- case First:
- return "First"
- case Last:
- return "Last"
- }
- panic(fmt.Errorf("Unknown SetOpType %v", int(self)))
-}
-
-const (
- Union = iota
- Intersection
- Difference
- // Xor differs from the definition in http://en.wikipedia.org/wiki/Exclusive_or by only returning keys present in exactly ONE input set.
- Xor
-)
-
-// SetOpType is the set operation to perform in a SetExpression.
-type SetOpType int
-
-func (self SetOpType) String() string {
- switch self {
- case Union:
- return "U"
- case Intersection:
- return "I"
- case Difference:
- return "D"
- case Xor:
- return "X"
- }
- panic(fmt.Errorf("Unknown SetOpType %v", int(self)))
-}
-
-// SetOpSource is either a key to a raw source producing input data, or another SetOp that calculates input data.
-// Weight is the weight of this source in the chosen Merge for the parent SetOp, if any.
-type SetOpSource struct {
- Key []byte
- SetOp *SetOp
- Weight *float64
-}
-
-// SetOp is a set operation to perform on a slice of SetOpSources, using a SetOpMerge function to merge the calculated values.
-type SetOp struct {
- Sources []SetOpSource
- Type SetOpType
- Merge SetOpMerge
-}
-
-func (self *SetOp) String() string {
- sources := make([]string, len(self.Sources))
- for index, source := range self.Sources {
- if source.Key != nil {
- sources[index] = string(source.Key)
- } else {
- sources[index] = fmt.Sprint(source.SetOp)
- }
- if source.Weight != nil {
- sources[index] = fmt.Sprintf("%v*%v", sources[index], *source.Weight)
- }
- }
- return fmt.Sprintf("(%v %v)", self.Type, strings.Join(sources, " "))
-}
-
-// SetExpression is a set operation defined by the Op or Code fields, coupled with range parameters and a Dest key defining where to put the results.
-type SetExpression struct {
- Op *SetOp
- Code string
- Min []byte
- Max []byte
- MinInc bool
- MaxInc bool
- Len int
- Dest []byte
-}
-
-// Each will execute the set expression, using the provided RawSourceCreator, and iterate over the result using f.
-func (self *SetExpression) Each(r RawSourceCreator, f SetOpResultIterator) (err error) {
- if self.Op == nil {
- self.Op = MustParse(self.Code)
- }
- skipper := createSkipper(r, self.Op)
- min := self.Min
- mininc := self.MinInc
- count := 0
- gt := -1
- if self.MaxInc {
- gt = 0
- }
- var res *SetOpResult
- for res, err = skipper.Skip(min, mininc); res != nil && err == nil; res, err = skipper.Skip(min, mininc) {
- if (self.Len > 0 && count >= self.Len) || (self.Max != nil && bytes.Compare(res.Key, self.Max) > gt) {
- return
- }
- count++
- min = res.Key
- mininc = false
- f(res)
- }
- return
-}
-
-// SetOpResult is a key and any values the Merge returned.
-type SetOpResult struct {
- Key []byte
- Values [][]byte
-}
-
-// ShallowCopy returns another SetOpResult with the same Key and a copy of the Values.
-func (self *SetOpResult) ShallowCopy() (result *SetOpResult) {
- result = &SetOpResult{
- Key: self.Key,
- Values: make([][]byte, len(self.Values)),
- }
- copy(result.Values, self.Values)
- return
-}
-func (self *SetOpResult) String() string {
- return fmt.Sprintf("%+v", *self)
-}
diff --git a/setop/set_op_parser.go b/setop/set_op_parser.go
deleted file mode 100644
index 9f189b2..0000000
--- a/setop/set_op_parser.go
+++ /dev/null
@@ -1,215 +0,0 @@
-package setop
-
-import (
- "bytes"
- "fmt"
- "regexp"
- "strconv"
-)
-
-var operationPattern = regexp.MustCompile("^(\\w)(:(\\w+))?$")
-
-const (
- empty = iota
- lparen
- name
- params
- param
- weight
- finished
-)
-
-// SetOpParser is a simple s-expression parser to parse expressions
-// of set algebra.
-//
-// It seems simplest to provide a few examples:
-//
-// (U s1 s2 s3) will return the union of s1-3.
-//
-// (I (U s1 s2) s3 s4) will return the intersection of s3-4 with the union of s1-2.
-//
-// (D s1 s3 s3) will return the difference between s1 and s2-3, which is all elements in s1 not present in s2 or s3.
-//
-// (X s1 s2 s3) will return all element only present in one of s1, s2 and s3. Note that this does not follow the XOR set operation definition at http://en.wikipedia.org/wiki/Exclusive_or
-//
-// To use another merge function than Append (the default), append :MERGEFUNCNAME to the function name in the s-expression.
-//
-// (I:IntegerSum s1 s2) will return the integer sum of all elements present in both s1 and s2.
-type SetOpParser struct {
- in string
- nextName *bytes.Buffer
- nextWeight *bytes.Buffer
- start int
- pos int
-}
-
-func NewSetOpParser(in string) *SetOpParser {
- return &SetOpParser{
- in: in,
- nextName: new(bytes.Buffer),
- nextWeight: new(bytes.Buffer),
- }
-}
-
-func (self *SetOpParser) Parse() (result *SetOp, err error) {
- if result, err = self.parse(); err != nil {
- return
- }
- if self.pos < len([]byte(self.in)) {
- err = fmt.Errorf("Unexpected characters at %v in %v.", self.pos, self.in)
- }
- return
-}
-
-func MustParse(in string) *SetOp {
- res, err := NewSetOpParser(in).Parse()
- if err != nil {
- panic(err)
- }
- return res
-}
-
-func (self *SetOpParser) parse() (result *SetOp, err error) {
- state := empty
- result = &SetOp{}
- for state != finished {
- if self.pos >= len(self.in) {
- err = fmt.Errorf("Unexpected EOF at %v in %v.", self.pos, self.in)
- return
- }
- switch state {
- case empty:
- switch self.in[self.pos] {
- case '(':
- state = name
- case ' ':
- default:
- err = fmt.Errorf("Expected ( at %v in %v.", self.pos, self.in)
- return
- }
- case name:
- switch self.in[self.pos] {
- case ' ':
- if match := operationPattern.FindStringSubmatch(string(self.nextName.Bytes())); match != nil {
- switch match[1] {
- case "U":
- result.Type = Union
- case "I":
- result.Type = Intersection
- case "X":
- result.Type = Xor
- case "D":
- result.Type = Difference
- default:
- err = fmt.Errorf("Unknown operation type %c at %v in %v. Legal values: U,I,X,D.", self.in[self.pos], self.pos, self.in)
- return
- }
- if match[3] != "" {
- if result.Merge, err = ParseSetOpMerge(match[3]); err != nil {
- return
- }
- }
- state = params
- self.nextName = new(bytes.Buffer)
- } else {
- err = fmt.Errorf("Unknown operation type %c at %v in %v. Legal values: U,I,X,D.", self.in[self.pos], self.pos, self.in)
- return
- }
- case ')':
- err = fmt.Errorf("Empty operation not allowed at %v in %v.", self.pos, self.in)
- return
- default:
- self.nextName.WriteByte(self.in[self.pos])
- }
- case params:
- switch self.in[self.pos] {
- case ' ':
- case ')':
- if len(result.Sources) == 0 {
- err = fmt.Errorf("Operation without parameters not allowed at %v in %v.", self.pos, self.in)
- return
- }
- if self.nextName.Len() > 0 {
- result.Sources = append(result.Sources, SetOpSource{Key: self.nextName.Bytes()})
- self.nextName = new(bytes.Buffer)
- }
- state = finished
- case '(':
- if self.nextName.Len() > 0 {
- err = fmt.Errorf("Unexpected ( at %v in %v.", self.pos, self.in)
- return
- }
- var nested *SetOp
- if nested, err = self.parse(); err != nil {
- return
- }
- self.pos--
- result.Sources = append(result.Sources, SetOpSource{SetOp: nested})
- case '*':
- self.nextWeight = new(bytes.Buffer)
- state = weight
- default:
- state = param
- self.nextName.WriteByte(self.in[self.pos])
- }
- case weight:
- switch self.in[self.pos] {
- case '*':
- err = fmt.Errorf("Unexpected * at %v in %v.", self.pos, self.in)
- return
- case '(':
- err = fmt.Errorf("Unexpected ( at %v in %v.", self.pos, self.in)
- return
- case ')':
- var w float64
- if w, err = strconv.ParseFloat(string(self.nextWeight.Bytes()), 64); err != nil {
- err = fmt.Errorf("Unparseable float64 at %v in %v.", self.pos, self.in)
- return
- }
- result.Sources[len(result.Sources)-1].Weight = &w
- self.nextWeight = new(bytes.Buffer)
- state = finished
- case ' ':
- var w float64
- if w, err = strconv.ParseFloat(string(self.nextWeight.Bytes()), 64); err != nil {
- err = fmt.Errorf("Unparseable float64 at %v in %v.", self.pos, self.in)
- return
- }
- result.Sources[len(result.Sources)-1].Weight = &w
- self.nextWeight = new(bytes.Buffer)
- state = params
- default:
- self.nextWeight.WriteByte(self.in[self.pos])
- }
- case param:
- switch self.in[self.pos] {
- case '*':
- if self.nextName.Len() > 0 {
- result.Sources = append(result.Sources, SetOpSource{Key: self.nextName.Bytes()})
- self.nextName = new(bytes.Buffer)
- }
- self.nextWeight = new(bytes.Buffer)
- state = weight
- case ' ':
- if self.nextName.Len() > 0 {
- result.Sources = append(result.Sources, SetOpSource{Key: self.nextName.Bytes()})
- self.nextName = new(bytes.Buffer)
- }
- state = params
- case ')':
- if self.nextName.Len() > 0 {
- result.Sources = append(result.Sources, SetOpSource{Key: self.nextName.Bytes()})
- self.nextName = new(bytes.Buffer)
- }
- state = finished
- case '(':
- err = fmt.Errorf("Unexpected ( at %v in %v.", self.pos, self.in)
- return
- default:
- self.nextName.WriteByte(self.in[self.pos])
- }
- }
- self.pos++
- }
- return
-}
diff --git a/setop/set_op_test.go b/setop/set_op_test.go
deleted file mode 100644
index 5c07c2a..0000000
--- a/setop/set_op_test.go
+++ /dev/null
@@ -1,554 +0,0 @@
-package setop
-
-import (
- "bytes"
- "fmt"
- "github.com/zond/god/common"
- "math/big"
- "reflect"
- "sort"
- "testing"
-)
-
-type testSkipper struct {
- pairs []tP
- index int
-}
-type tP [2]string
-
-func (self *testSkipper) Skip(min []byte, inc bool) (result *SetOpResult, err error) {
- lt := 1
- if inc {
- lt = 0
- }
- for self.index < len(self.pairs) && bytes.Compare([]byte(self.pairs[self.index][0]), min) < lt {
- self.index++
- }
- if self.index < len(self.pairs) {
- return &SetOpResult{
- Key: []byte(self.pairs[self.index][0]),
- Values: [][]byte{[]byte(self.pairs[self.index][1])},
- }, nil
- }
- return nil, nil
-}
-
-var testSets = map[string]*testSkipper{
- "a": &testSkipper{
- pairs: []tP{
- tP{"a", "a"},
- tP{"b", "b"},
- tP{"c", "c"},
- },
- },
- "b": &testSkipper{
- pairs: []tP{
- tP{"a", "a"},
- tP{"c", "c"},
- tP{"d", "d"},
- },
- },
-}
-
-func resetSets() {
- for _, set := range testSets {
- set.index = 0
- }
-}
-
-func findTestSet(b []byte) Skipper {
- set, ok := testSets[string(b)]
- if !ok {
- panic(fmt.Errorf("couldn't find test set %s", string(b)))
- }
- return set
-}
-
-func collect(t *testing.T, expr string) []*SetOpResult {
- s, err := NewSetOpParser(expr).Parse()
- if err != nil {
- t.Fatal(err)
- }
- se := &SetExpression{
- Op: s,
- }
- var collector []*SetOpResult
- se.Each(findTestSet, func(res *SetOpResult) {
- collector = append(collector, res)
- })
- return collector
-}
-
-type testResults []*SetOpResult
-
-func (self testResults) Len() int {
- return len(self)
-}
-func (self testResults) Swap(i, j int) {
- self[i], self[j] = self[j], self[i]
-}
-func (self testResults) Less(i, j int) bool {
- return bytes.Compare(self[i].Key, self[j].Key) < 0
-}
-
-func diff(merger mergeFunc, sets [][]tP, weights []float64) (result []*SetOpResult) {
- hashes := make([]map[string][]byte, len(sets))
- for index, set := range sets {
- hashes[index] = make(map[string][]byte)
- for _, pair := range set {
- hashes[index][pair[0]] = []byte(pair[1])
- }
- }
- resultMap := make(map[string][][]byte)
- for k, v := range hashes[0] {
- resultMap[k] = merger(resultMap[k], [][]byte{v}, weights[0])
- }
- for _, m := range hashes[1:] {
- for k, _ := range m {
- delete(resultMap, k)
- }
- }
- for k, v := range resultMap {
- result = append(result, &SetOpResult{
- Key: []byte(k),
- Values: v,
- })
- }
- sort.Sort(testResults(result))
- return
-}
-
-func inter(merger mergeFunc, sets [][]tP, weights []float64) (result []*SetOpResult) {
- hashes := make([]map[string][]byte, len(sets))
- for index, set := range sets {
- hashes[index] = make(map[string][]byte)
- for _, pair := range set {
- hashes[index][pair[0]] = []byte(pair[1])
- }
- }
- resultMap := make(map[string][][]byte)
- for index, m := range hashes {
- for k, v := range m {
- isOk := true
- for _, m2 := range hashes {
- _, ex := m2[k]
- isOk = isOk && ex
- }
- if isOk {
- resultMap[k] = merger(resultMap[k], [][]byte{v}, weights[index])
- }
- }
- }
- for k, v := range resultMap {
- result = append(result, &SetOpResult{
- Key: []byte(k),
- Values: v,
- })
- }
- sort.Sort(testResults(result))
- return
-}
-
-func xor(merger mergeFunc, sets [][]tP, weights []float64) (result []*SetOpResult) {
- hashes := make([]map[string][]byte, len(sets))
- for index, set := range sets {
- hashes[index] = make(map[string][]byte)
- for _, pair := range set {
- hashes[index][pair[0]] = []byte(pair[1])
- }
- }
- matchMap := make(map[string]int)
- resultMap := make(map[string][][]byte)
- for index, m := range hashes {
- for k, v := range m {
- resultMap[k] = merger(resultMap[k], [][]byte{v}, weights[index])
- matchMap[k] += 1
- }
- }
- for k, v := range resultMap {
- if matchMap[k] == 1 {
- result = append(result, &SetOpResult{
- Key: []byte(k),
- Values: v,
- })
- }
- }
- sort.Sort(testResults(result))
- return
-}
-
-func union(merger mergeFunc, sets [][]tP, weights []float64) (result []*SetOpResult) {
- hashes := make([]map[string][]byte, len(sets))
- for index, set := range sets {
- hashes[index] = make(map[string][]byte)
- for _, pair := range set {
- hashes[index][pair[0]] = []byte(pair[1])
- }
- }
- resultMap := make(map[string][][]byte)
- for index, m := range hashes {
- for k, v := range m {
- resultMap[k] = merger(resultMap[k], [][]byte{v}, weights[index])
- }
- }
- for k, v := range resultMap {
- result = append(result, &SetOpResult{
- Key: []byte(k),
- Values: v,
- })
- }
- sort.Sort(testResults(result))
- return
-}
-
-func TestBigIntXor(t *testing.T) {
- found := bigIntXor([][]byte{common.EncodeBigInt(big.NewInt(15))}, [][]byte{common.EncodeBigInt(big.NewInt(1)), common.EncodeBigInt(big.NewInt(2)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected := [][]byte{common.EncodeBigInt(big.NewInt(8))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntXor(nil, [][]byte{common.EncodeBigInt(big.NewInt(15)), common.EncodeBigInt(big.NewInt(1)), common.EncodeBigInt(big.NewInt(2)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(8))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntXor([][]byte{common.EncodeBigInt(big.NewInt(15))}, [][]byte{common.EncodeBigInt(big.NewInt(3))}, 2)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(9))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
-}
-
-func TestBigIntRem(t *testing.T) {
- found := bigIntRem([][]byte{common.EncodeBigInt(big.NewInt(50))}, [][]byte{common.EncodeBigInt(big.NewInt(30)), common.EncodeBigInt(big.NewInt(11)), common.EncodeBigInt(big.NewInt(7))}, 1)
- expected := [][]byte{common.EncodeBigInt(big.NewInt(2))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntRem(nil, [][]byte{common.EncodeBigInt(big.NewInt(50)), common.EncodeBigInt(big.NewInt(30)), common.EncodeBigInt(big.NewInt(11)), common.EncodeBigInt(big.NewInt(7))}, 1)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(2))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntRem([][]byte{common.EncodeBigInt(big.NewInt(50))}, [][]byte{common.EncodeBigInt(big.NewInt(7))}, 2)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(8))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
-}
-
-func TestBigIntMul(t *testing.T) {
- found := bigIntMul([][]byte{common.EncodeBigInt(big.NewInt(1))}, [][]byte{common.EncodeBigInt(big.NewInt(2)), common.EncodeBigInt(big.NewInt(3)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected := [][]byte{common.EncodeBigInt(big.NewInt(24))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntMul(nil, [][]byte{common.EncodeBigInt(big.NewInt(1)), common.EncodeBigInt(big.NewInt(2)), common.EncodeBigInt(big.NewInt(3)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(24))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntMul([][]byte{common.EncodeBigInt(big.NewInt(1))}, [][]byte{common.EncodeBigInt(big.NewInt(2))}, 2)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(4))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
-}
-
-func TestBigIntOr(t *testing.T) {
- found := bigIntOr([][]byte{common.EncodeBigInt(big.NewInt(1))}, [][]byte{common.EncodeBigInt(big.NewInt(2)), common.EncodeBigInt(big.NewInt(3)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected := [][]byte{common.EncodeBigInt(big.NewInt(7))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntOr(nil, [][]byte{common.EncodeBigInt(big.NewInt(1)), common.EncodeBigInt(big.NewInt(2)), common.EncodeBigInt(big.NewInt(3)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(7))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntOr([][]byte{common.EncodeBigInt(big.NewInt(1))}, [][]byte{common.EncodeBigInt(big.NewInt(2))}, 2)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(5))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
-}
-
-func TestBigMod(t *testing.T) {
- found := bigIntMod([][]byte{common.EncodeBigInt(big.NewInt(50))}, [][]byte{common.EncodeBigInt(big.NewInt(30)), common.EncodeBigInt(big.NewInt(7)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected := [][]byte{common.EncodeBigInt(big.NewInt(2))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntMod(nil, [][]byte{common.EncodeBigInt(big.NewInt(50)), common.EncodeBigInt(big.NewInt(30)), common.EncodeBigInt(big.NewInt(7)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(2))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntMod([][]byte{common.EncodeBigInt(big.NewInt(50))}, [][]byte{common.EncodeBigInt(big.NewInt(15))}, 2)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(20))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
-}
-
-func TestBigIntDiv(t *testing.T) {
- found := bigIntDiv([][]byte{common.EncodeBigInt(big.NewInt(48))}, [][]byte{common.EncodeBigInt(big.NewInt(2)), common.EncodeBigInt(big.NewInt(3)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected := [][]byte{common.EncodeBigInt(big.NewInt(2))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntDiv(nil, [][]byte{common.EncodeBigInt(big.NewInt(48)), common.EncodeBigInt(big.NewInt(2)), common.EncodeBigInt(big.NewInt(3)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(2))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntDiv([][]byte{common.EncodeBigInt(big.NewInt(48))}, [][]byte{common.EncodeBigInt(big.NewInt(2))}, 2)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(12))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
-}
-
-func TestBigIntAndNot(t *testing.T) {
- found := bigIntAndNot([][]byte{common.EncodeBigInt(big.NewInt(15))}, [][]byte{common.EncodeBigInt(big.NewInt(1)), common.EncodeBigInt(big.NewInt(2)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected := [][]byte{common.EncodeBigInt(big.NewInt(8))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntAndNot(nil, [][]byte{common.EncodeBigInt(big.NewInt(15)), common.EncodeBigInt(big.NewInt(1)), common.EncodeBigInt(big.NewInt(2)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(8))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntAndNot([][]byte{common.EncodeBigInt(big.NewInt(15))}, [][]byte{common.EncodeBigInt(big.NewInt(2))}, 2)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(11))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
-}
-
-func TestBigIntAdd(t *testing.T) {
- found := bigIntAdd([][]byte{common.EncodeBigInt(big.NewInt(1))}, [][]byte{common.EncodeBigInt(big.NewInt(2)), common.EncodeBigInt(big.NewInt(3)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected := [][]byte{common.EncodeBigInt(big.NewInt(10))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntAdd(nil, [][]byte{common.EncodeBigInt(big.NewInt(1)), common.EncodeBigInt(big.NewInt(2)), common.EncodeBigInt(big.NewInt(3)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(10))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntAdd([][]byte{common.EncodeBigInt(big.NewInt(1))}, [][]byte{common.EncodeBigInt(big.NewInt(2))}, 2)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(5))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
-}
-
-func TestBigIntAnd(t *testing.T) {
- found := bigIntAnd([][]byte{common.EncodeBigInt(big.NewInt(1))}, [][]byte{common.EncodeBigInt(big.NewInt(2)), common.EncodeBigInt(big.NewInt(3)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected := [][]byte{common.EncodeBigInt(big.NewInt(0))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntAnd([][]byte{common.EncodeBigInt(big.NewInt(1)), common.EncodeBigInt(big.NewInt(3))}, [][]byte{common.EncodeBigInt(big.NewInt(3)), common.EncodeBigInt(big.NewInt(5))}, 1)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(1))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntAnd(nil, [][]byte{common.EncodeBigInt(big.NewInt(1)), common.EncodeBigInt(big.NewInt(2)), common.EncodeBigInt(big.NewInt(3)), common.EncodeBigInt(big.NewInt(4))}, 1)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(0))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntAnd(nil, [][]byte{common.EncodeBigInt(big.NewInt(1)), common.EncodeBigInt(big.NewInt(3)), common.EncodeBigInt(big.NewInt(3)), common.EncodeBigInt(big.NewInt(5))}, 1)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(1))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
- found = bigIntAnd([][]byte{common.EncodeBigInt(big.NewInt(15))}, [][]byte{common.EncodeBigInt(big.NewInt(3))}, 2)
- expected = [][]byte{common.EncodeBigInt(big.NewInt(6))}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeBigInt(found[0])), fmt.Sprint(common.DecodeBigInt(expected[0])))
- }
-}
-
-func TestFloatMul(t *testing.T) {
- found := floatMul([][]byte{common.EncodeFloat64(1)}, [][]byte{common.EncodeFloat64(2), common.EncodeFloat64(3), common.EncodeFloat64(4)}, 1)
- expected := [][]byte{common.EncodeFloat64(24)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeFloat64(found[0])), fmt.Sprint(common.DecodeFloat64(expected[0])))
- }
- found = floatMul(nil, [][]byte{common.EncodeFloat64(1), common.EncodeFloat64(2), common.EncodeFloat64(3), common.EncodeFloat64(4)}, 1)
- expected = [][]byte{common.EncodeFloat64(24)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeFloat64(found[0])), fmt.Sprint(common.DecodeFloat64(expected[0])))
- }
- found = floatMul([][]byte{common.EncodeFloat64(2)}, [][]byte{common.EncodeFloat64(2)}, 2)
- expected = [][]byte{common.EncodeFloat64(8)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeFloat64(found[0])), fmt.Sprint(common.DecodeFloat64(expected[0])))
- }
-}
-
-func TestFloatDiv(t *testing.T) {
- found := floatDiv([][]byte{common.EncodeFloat64(48)}, [][]byte{common.EncodeFloat64(2), common.EncodeFloat64(3), common.EncodeFloat64(4)}, 1)
- expected := [][]byte{common.EncodeFloat64(2)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeFloat64(found[0])), fmt.Sprint(common.DecodeFloat64(expected[0])))
- }
- found = floatDiv(nil, [][]byte{common.EncodeFloat64(48), common.EncodeFloat64(2), common.EncodeFloat64(3), common.EncodeFloat64(4)}, 1)
- expected = [][]byte{common.EncodeFloat64(2)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeFloat64(found[0])), fmt.Sprint(common.DecodeFloat64(expected[0])))
- }
- found = floatDiv([][]byte{common.EncodeFloat64(48)}, [][]byte{common.EncodeFloat64(2)}, 2)
- expected = [][]byte{common.EncodeFloat64(12)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", fmt.Sprint(common.DecodeFloat64(found[0])), fmt.Sprint(common.DecodeFloat64(expected[0])))
- }
-}
-
-func TestFloatSum(t *testing.T) {
- found := floatSum([][]byte{common.EncodeFloat64(1)}, [][]byte{common.EncodeFloat64(2), common.EncodeFloat64(3), common.EncodeFloat64(4)}, 1)
- expected := [][]byte{common.EncodeFloat64(10)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
- found = floatSum(nil, [][]byte{common.EncodeFloat64(1), common.EncodeFloat64(2), common.EncodeFloat64(3), common.EncodeFloat64(4)}, 1)
- expected = [][]byte{common.EncodeFloat64(10)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
- found = floatSum([][]byte{common.EncodeFloat64(1)}, [][]byte{common.EncodeFloat64(2)}, 2)
- expected = [][]byte{common.EncodeFloat64(5)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
-}
-
-func TestIntegerMul(t *testing.T) {
- found := integerMul([][]byte{common.EncodeInt64(1)}, [][]byte{common.EncodeInt64(2), common.EncodeInt64(3), common.EncodeInt64(4)}, 1)
- expected := [][]byte{common.EncodeInt64(24)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
- found = integerMul(nil, [][]byte{common.EncodeInt64(1), common.EncodeInt64(2), common.EncodeInt64(3), common.EncodeInt64(4)}, 1)
- expected = [][]byte{common.EncodeInt64(24)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
- found = integerMul([][]byte{common.EncodeInt64(2)}, [][]byte{common.EncodeInt64(2)}, 2)
- expected = [][]byte{common.EncodeInt64(8)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
-}
-
-func TestIntegerDiv(t *testing.T) {
- found := integerDiv([][]byte{common.EncodeInt64(48)}, [][]byte{common.EncodeInt64(2), common.EncodeInt64(3), common.EncodeInt64(4)}, 1)
- expected := [][]byte{common.EncodeInt64(2)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
- found = integerDiv(nil, [][]byte{common.EncodeInt64(48), common.EncodeInt64(2), common.EncodeInt64(3), common.EncodeInt64(4)}, 1)
- expected = [][]byte{common.EncodeInt64(2)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
- found = integerDiv([][]byte{common.EncodeInt64(48)}, [][]byte{common.EncodeInt64(2)}, 2)
- expected = [][]byte{common.EncodeInt64(12)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
-}
-
-func TestIntegerSum(t *testing.T) {
- found := integerSum([][]byte{common.EncodeInt64(1)}, [][]byte{common.EncodeInt64(2), common.EncodeInt64(3), common.EncodeInt64(4)}, 1)
- expected := [][]byte{common.EncodeInt64(10)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
- found = integerSum(nil, [][]byte{common.EncodeInt64(1), common.EncodeInt64(2), common.EncodeInt64(3), common.EncodeInt64(4)}, 1)
- expected = [][]byte{common.EncodeInt64(10)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
- found = integerSum([][]byte{common.EncodeInt64(1)}, [][]byte{common.EncodeInt64(2)}, 2)
- expected = [][]byte{common.EncodeInt64(5)}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
-}
-
-func TestConCat(t *testing.T) {
- found := conCat([][]byte{[]byte{1}}, [][]byte{[]byte{2}, []byte{3}, []byte{4}}, 1)
- expected := [][]byte{[]byte{1, 2, 3, 4}}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
- found = conCat(nil, [][]byte{[]byte{1}, []byte{2}, []byte{3}, []byte{4}}, 1)
- expected = [][]byte{[]byte{1, 2, 3, 4}}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
- found = conCat([][]byte{[]byte{1}}, [][]byte{[]byte{2}}, 2)
- expected = [][]byte{[]byte{1, 2, 2}}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
-}
-
-func TestAppend(t *testing.T) {
- found := _append([][]byte{[]byte{1}}, [][]byte{[]byte{2}, []byte{3}, []byte{4}}, 1)
- expected := [][]byte{[]byte{1}, []byte{2}, []byte{3}, []byte{4}}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
- found = _append(nil, [][]byte{[]byte{1}, []byte{2}, []byte{3}, []byte{4}}, 1)
- expected = [][]byte{[]byte{1}, []byte{2}, []byte{3}, []byte{4}}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
- found = _append([][]byte{[]byte{1}}, [][]byte{[]byte{2}}, 2)
- expected = [][]byte{[]byte{1}, []byte{2}, []byte{2}}
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
-}
-
-func TestUnion(t *testing.T) {
- resetSets()
- found := collect(t, "(U a b)")
- expected := union(_append, [][]tP{testSets["a"].pairs, testSets["b"].pairs}, []float64{1, 1})
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
-}
-
-func TestInter(t *testing.T) {
- resetSets()
- found := collect(t, "(I a b)")
- expected := inter(_append, [][]tP{testSets["a"].pairs, testSets["b"].pairs}, []float64{1, 1})
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
-}
-
-func TestDiff(t *testing.T) {
- resetSets()
- found := collect(t, "(D a b)")
- expected := diff(_append, [][]tP{testSets["a"].pairs, testSets["b"].pairs}, []float64{1, 1})
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
-}
-
-func TestXor(t *testing.T) {
- resetSets()
- found := collect(t, "(X a b)")
- expected := xor(_append, [][]tP{testSets["a"].pairs, testSets["b"].pairs}, []float64{1, 1})
- if !reflect.DeepEqual(found, expected) {
- t.Errorf("%v should be %v", found, expected)
- }
-}
diff --git a/templates/css.go b/templates/css.go
index 7a4a8c0..4380a5b 100644
--- a/templates/css.go
+++ b/templates/css.go
@@ -3,5 +3,5 @@ import "text/template"
var CSS = template.New("css")
func init() {
template.Must(CSS.New("bootstrap.min.css").Parse("/*!\n * Bootstrap v2.2.1\n *\n * Copyright 2012 Twitter, Inc\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Designed and built with all the love in the world @twitter by @mdo and @fat.\n */\n.clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:\"\";line-height:0;}\n.clearfix:after{clear:both;}\n.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;}\n.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}\narticle,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block;}\naudio,canvas,video{display:inline-block;*display:inline;*zoom:1;}\naudio:not([controls]){display:none;}\nhtml{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;}\na:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}\na:hover,a:active{outline:0;}\nsub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline;}\nsup{top:-0.5em;}\nsub{bottom:-0.25em;}\nimg{max-width:100%;width:auto\\9;height:auto;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic;}\n#map_canvas img,.google-maps img{max-width:none;}\nbutton,input,select,textarea{margin:0;font-size:100%;vertical-align:middle;}\nbutton,input{*overflow:visible;line-height:normal;}\nbutton::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0;}\nbutton,html input[type=\"button\"],input[type=\"reset\"],input[type=\"submit\"]{-webkit-appearance:button;cursor:pointer;}\ninput[type=\"search\"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield;}\ninput[type=\"search\"]::-webkit-search-decoration,input[type=\"search\"]::-webkit-search-cancel-button{-webkit-appearance:none;}\ntextarea{overflow:auto;vertical-align:top;}\nbody{margin:0;font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333333;background-color:#ffffff;}\na{color:#0088cc;text-decoration:none;}\na:hover{color:#005580;text-decoration:underline;}\n.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}\n.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);box-shadow:0 1px 3px rgba(0, 0, 0, 0.1);}\n.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px;}\n.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:\"\";line-height:0;}\n.row:after{clear:both;}\n[class*=\"span\"]{float:left;min-height:1px;margin-left:20px;}\n.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;}\n.span12{width:940px;}\n.span11{width:860px;}\n.span10{width:780px;}\n.span9{width:700px;}\n.span8{width:620px;}\n.span7{width:540px;}\n.span6{width:460px;}\n.span5{width:380px;}\n.span4{width:300px;}\n.span3{width:220px;}\n.span2{width:140px;}\n.span1{width:60px;}\n.offset12{margin-left:980px;}\n.offset11{margin-left:900px;}\n.offset10{margin-left:820px;}\n.offset9{margin-left:740px;}\n.offset8{margin-left:660px;}\n.offset7{margin-left:580px;}\n.offset6{margin-left:500px;}\n.offset5{margin-left:420px;}\n.offset4{margin-left:340px;}\n.offset3{margin-left:260px;}\n.offset2{margin-left:180px;}\n.offset1{margin-left:100px;}\n.row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:\"\";line-height:0;}\n.row-fluid:after{clear:both;}\n.row-fluid [class*=\"span\"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;}\n.row-fluid [class*=\"span\"]:first-child{margin-left:0;}\n.row-fluid .controls-row [class*=\"span\"]+[class*=\"span\"]{margin-left:2.127659574468085%;}\n.row-fluid .span12{width:100%;*width:99.94680851063829%;}\n.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%;}\n.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%;}\n.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%;}\n.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%;}\n.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%;}\n.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%;}\n.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%;}\n.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%;}\n.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%;}\n.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%;}\n.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%;}\n.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%;}\n.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%;}\n.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%;}\n.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%;}\n.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%;}\n.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%;}\n.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%;}\n.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%;}\n.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%;}\n.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%;}\n.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%;}\n.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%;}\n.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%;}\n.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%;}\n.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%;}\n.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%;}\n.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%;}\n.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%;}\n.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%;}\n.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%;}\n.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%;}\n.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%;}\n.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%;}\n.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%;}\n[class*=\"span\"].hide,.row-fluid [class*=\"span\"].hide{display:none;}\n[class*=\"span\"].pull-right,.row-fluid [class*=\"span\"].pull-right{float:right;}\n.container{margin-right:auto;margin-left:auto;*zoom:1;}.container:before,.container:after{display:table;content:\"\";line-height:0;}\n.container:after{clear:both;}\n.container-fluid{padding-right:20px;padding-left:20px;*zoom:1;}.container-fluid:before,.container-fluid:after{display:table;content:\"\";line-height:0;}\n.container-fluid:after{clear:both;}\np{margin:0 0 10px;}\n.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px;}\nsmall{font-size:85%;}\nstrong{font-weight:bold;}\nem{font-style:italic;}\ncite{font-style:normal;}\n.muted{color:#999999;}\n.text-warning{color:#c09853;}\na.text-warning:hover{color:#a47e3c;}\n.text-error{color:#b94a48;}\na.text-error:hover{color:#953b39;}\n.text-info{color:#3a87ad;}\na.text-info:hover{color:#2d6987;}\n.text-success{color:#468847;}\na.text-success:hover{color:#356635;}\nh1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility;}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999999;}\nh1,h2,h3{line-height:40px;}\nh1{font-size:38.5px;}\nh2{font-size:31.5px;}\nh3{font-size:24.5px;}\nh4{font-size:17.5px;}\nh5{font-size:14px;}\nh6{font-size:11.9px;}\nh1 small{font-size:24.5px;}\nh2 small{font-size:17.5px;}\nh3 small{font-size:14px;}\nh4 small{font-size:14px;}\n.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eeeeee;}\nul,ol{padding:0;margin:0 0 10px 25px;}\nul ul,ul ol,ol ol,ol ul{margin-bottom:0;}\nli{line-height:20px;}\nul.unstyled,ol.unstyled{margin-left:0;list-style:none;}\ndl{margin-bottom:20px;}\ndt,dd{line-height:20px;}\ndt{font-weight:bold;}\ndd{margin-left:10px;}\n.dl-horizontal{*zoom:1;}.dl-horizontal:before,.dl-horizontal:after{display:table;content:\"\";line-height:0;}\n.dl-horizontal:after{clear:both;}\n.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}\n.dl-horizontal dd{margin-left:180px;}\nhr{margin:20px 0;border:0;border-top:1px solid #eeeeee;border-bottom:1px solid #ffffff;}\nabbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999999;}\nabbr.initialism{font-size:90%;text-transform:uppercase;}\nblockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eeeeee;}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:25px;}\nblockquote small{display:block;line-height:20px;color:#999999;}blockquote small:before{content:'\\2014 \\00A0';}\nblockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eeeeee;border-left:0;}blockquote.pull-right p,blockquote.pull-right small{text-align:right;}\nblockquote.pull-right small:before{content:'';}\nblockquote.pull-right small:after{content:'\\00A0 \\2014';}\nq:before,q:after,blockquote:before,blockquote:after{content:\"\";}\naddress{display:block;margin-bottom:20px;font-style:normal;line-height:20px;}\ncode,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,\"Courier New\",monospace;font-size:12px;color:#333333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}\ncode{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;}\npre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}pre.prettyprint{margin-bottom:20px;}\npre code{padding:0;color:inherit;background-color:transparent;border:0;}\n.pre-scrollable{max-height:340px;overflow-y:scroll;}\n.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#ffffff;vertical-align:baseline;white-space:nowrap;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#999999;}\n.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}\n.badge{padding-left:9px;padding-right:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px;}\na.label:hover,a.badge:hover{color:#ffffff;text-decoration:none;cursor:pointer;}\n.label-important,.badge-important{background-color:#b94a48;}\n.label-important[href],.badge-important[href]{background-color:#953b39;}\n.label-warning,.badge-warning{background-color:#f89406;}\n.label-warning[href],.badge-warning[href]{background-color:#c67605;}\n.label-success,.badge-success{background-color:#468847;}\n.label-success[href],.badge-success[href]{background-color:#356635;}\n.label-info,.badge-info{background-color:#3a87ad;}\n.label-info[href],.badge-info[href]{background-color:#2d6987;}\n.label-inverse,.badge-inverse{background-color:#333333;}\n.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a;}\n.btn .label,.btn .badge{position:relative;top:-1px;}\n.btn-mini .label,.btn-mini .badge{top:0;}\ntable{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0;}\n.table{width:100%;margin-bottom:20px;}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #dddddd;}\n.table th{font-weight:bold;}\n.table thead th{vertical-align:bottom;}\n.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0;}\n.table tbody+tbody{border-top:2px solid #dddddd;}\n.table-condensed th,.table-condensed td{padding:4px 5px;}\n.table-bordered{border:1px solid #dddddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.table-bordered th,.table-bordered td{border-left:1px solid #dddddd;}\n.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0;}\n.table-bordered thead:first-child tr:first-child th:first-child,.table-bordered tbody:first-child tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px;}\n.table-bordered thead:first-child tr:first-child th:last-child,.table-bordered tbody:first-child tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px;}\n.table-bordered thead:last-child tr:last-child th:first-child,.table-bordered tbody:last-child tr:last-child td:first-child,.table-bordered tfoot:last-child tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;}\n.table-bordered thead:last-child tr:last-child th:last-child,.table-bordered tbody:last-child tr:last-child td:last-child,.table-bordered tfoot:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;}\n.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px;}\n.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px;}\n.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9;}\n.table-hover tbody tr:hover td,.table-hover tbody tr:hover th{background-color:#f5f5f5;}\ntable td[class*=\"span\"],table th[class*=\"span\"],.row-fluid table td[class*=\"span\"],.row-fluid table th[class*=\"span\"]{display:table-cell;float:none;margin-left:0;}\n.table td.span1,.table th.span1{float:none;width:44px;margin-left:0;}\n.table td.span2,.table th.span2{float:none;width:124px;margin-left:0;}\n.table td.span3,.table th.span3{float:none;width:204px;margin-left:0;}\n.table td.span4,.table th.span4{float:none;width:284px;margin-left:0;}\n.table td.span5,.table th.span5{float:none;width:364px;margin-left:0;}\n.table td.span6,.table th.span6{float:none;width:444px;margin-left:0;}\n.table td.span7,.table th.span7{float:none;width:524px;margin-left:0;}\n.table td.span8,.table th.span8{float:none;width:604px;margin-left:0;}\n.table td.span9,.table th.span9{float:none;width:684px;margin-left:0;}\n.table td.span10,.table th.span10{float:none;width:764px;margin-left:0;}\n.table td.span11,.table th.span11{float:none;width:844px;margin-left:0;}\n.table td.span12,.table th.span12{float:none;width:924px;margin-left:0;}\n.table tbody tr.success td{background-color:#dff0d8;}\n.table tbody tr.error td{background-color:#f2dede;}\n.table tbody tr.warning td{background-color:#fcf8e3;}\n.table tbody tr.info td{background-color:#d9edf7;}\n.table-hover tbody tr.success:hover td{background-color:#d0e9c6;}\n.table-hover tbody tr.error:hover td{background-color:#ebcccc;}\n.table-hover tbody tr.warning:hover td{background-color:#faf2cc;}\n.table-hover tbody tr.info:hover td{background-color:#c4e3f3;}\nform{margin:0 0 20px;}\nfieldset{padding:0;margin:0;border:0;}\nlegend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333333;border:0;border-bottom:1px solid #e5e5e5;}legend small{font-size:15px;color:#999999;}\nlabel,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px;}\ninput,button,select,textarea{font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;}\nlabel{display:block;margin-bottom:5px;}\nselect,textarea,input[type=\"text\"],input[type=\"password\"],input[type=\"datetime\"],input[type=\"datetime-local\"],input[type=\"date\"],input[type=\"month\"],input[type=\"time\"],input[type=\"week\"],input[type=\"number\"],input[type=\"email\"],input[type=\"url\"],input[type=\"search\"],input[type=\"tel\"],input[type=\"color\"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555555;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;vertical-align:middle;}\ninput,textarea,.uneditable-input{width:206px;}\ntextarea{height:auto;}\ntextarea,input[type=\"text\"],input[type=\"password\"],input[type=\"datetime\"],input[type=\"datetime-local\"],input[type=\"date\"],input[type=\"month\"],input[type=\"time\"],input[type=\"week\"],input[type=\"number\"],input[type=\"email\"],input[type=\"url\"],input[type=\"search\"],input[type=\"tel\"],input[type=\"color\"],.uneditable-input{background-color:#ffffff;border:1px solid #cccccc;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-webkit-transition:border linear .2s, box-shadow linear .2s;-moz-transition:border linear .2s, box-shadow linear .2s;-o-transition:border linear .2s, box-shadow linear .2s;transition:border linear .2s, box-shadow linear .2s;}textarea:focus,input[type=\"text\"]:focus,input[type=\"password\"]:focus,input[type=\"datetime\"]:focus,input[type=\"datetime-local\"]:focus,input[type=\"date\"]:focus,input[type=\"month\"]:focus,input[type=\"time\"]:focus,input[type=\"week\"]:focus,input[type=\"number\"]:focus,input[type=\"email\"]:focus,input[type=\"url\"]:focus,input[type=\"search\"]:focus,input[type=\"tel\"]:focus,input[type=\"color\"]:focus,.uneditable-input:focus{border-color:rgba(82, 168, 236, 0.8);outline:0;outline:thin dotted \\9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6);}\ninput[type=\"radio\"],input[type=\"checkbox\"]{margin:4px 0 0;*margin-top:0;margin-top:1px \\9;line-height:normal;cursor:pointer;}\ninput[type=\"file\"],input[type=\"image\"],input[type=\"submit\"],input[type=\"reset\"],input[type=\"button\"],input[type=\"radio\"],input[type=\"checkbox\"]{width:auto;}\nselect,input[type=\"file\"]{height:30px;*margin-top:4px;line-height:30px;}\nselect{width:220px;border:1px solid #cccccc;background-color:#ffffff;}\nselect[multiple],select[size]{height:auto;}\nselect:focus,input[type=\"file\"]:focus,input[type=\"radio\"]:focus,input[type=\"checkbox\"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}\n.uneditable-input,.uneditable-textarea{color:#999999;background-color:#fcfcfc;border-color:#cccccc;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);cursor:not-allowed;}\n.uneditable-input{overflow:hidden;white-space:nowrap;}\n.uneditable-textarea{width:auto;height:auto;}\ninput:-moz-placeholder,textarea:-moz-placeholder{color:#999999;}\ninput:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999999;}\ninput::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999999;}\n.radio,.checkbox{min-height:20px;padding-left:20px;}\n.radio input[type=\"radio\"],.checkbox input[type=\"checkbox\"]{float:left;margin-left:-20px;}\n.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px;}\n.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle;}\n.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px;}\n.input-mini{width:60px;}\n.input-small{width:90px;}\n.input-medium{width:150px;}\n.input-large{width:210px;}\n.input-xlarge{width:270px;}\n.input-xxlarge{width:530px;}\ninput[class*=\"span\"],select[class*=\"span\"],textarea[class*=\"span\"],.uneditable-input[class*=\"span\"],.row-fluid input[class*=\"span\"],.row-fluid select[class*=\"span\"],.row-fluid textarea[class*=\"span\"],.row-fluid .uneditable-input[class*=\"span\"]{float:none;margin-left:0;}\n.input-append input[class*=\"span\"],.input-append .uneditable-input[class*=\"span\"],.input-prepend input[class*=\"span\"],.input-prepend .uneditable-input[class*=\"span\"],.row-fluid input[class*=\"span\"],.row-fluid select[class*=\"span\"],.row-fluid textarea[class*=\"span\"],.row-fluid .uneditable-input[class*=\"span\"],.row-fluid .input-prepend [class*=\"span\"],.row-fluid .input-append [class*=\"span\"]{display:inline-block;}\ninput,textarea,.uneditable-input{margin-left:0;}\n.controls-row [class*=\"span\"]+[class*=\"span\"]{margin-left:20px;}\ninput.span12, textarea.span12, .uneditable-input.span12{width:926px;}\ninput.span11, textarea.span11, .uneditable-input.span11{width:846px;}\ninput.span10, textarea.span10, .uneditable-input.span10{width:766px;}\ninput.span9, textarea.span9, .uneditable-input.span9{width:686px;}\ninput.span8, textarea.span8, .uneditable-input.span8{width:606px;}\ninput.span7, textarea.span7, .uneditable-input.span7{width:526px;}\ninput.span6, textarea.span6, .uneditable-input.span6{width:446px;}\ninput.span5, textarea.span5, .uneditable-input.span5{width:366px;}\ninput.span4, textarea.span4, .uneditable-input.span4{width:286px;}\ninput.span3, textarea.span3, .uneditable-input.span3{width:206px;}\ninput.span2, textarea.span2, .uneditable-input.span2{width:126px;}\ninput.span1, textarea.span1, .uneditable-input.span1{width:46px;}\n.controls-row{*zoom:1;}.controls-row:before,.controls-row:after{display:table;content:\"\";line-height:0;}\n.controls-row:after{clear:both;}\n.controls-row [class*=\"span\"],.row-fluid .controls-row [class*=\"span\"]{float:left;}\n.controls-row .checkbox[class*=\"span\"],.controls-row .radio[class*=\"span\"]{padding-top:5px;}\ninput[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eeeeee;}\ninput[type=\"radio\"][disabled],input[type=\"checkbox\"][disabled],input[type=\"radio\"][readonly],input[type=\"checkbox\"][readonly]{background-color:transparent;}\n.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853;}\n.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;}\n.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;}\n.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;}\n.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;}\n.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;}\n.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;}\n.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;}\n.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;}\n.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;}\n.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;}\n.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;}\n.control-group.info>label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad;}\n.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad;}\n.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;}\n.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad;}\ninput:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b;}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;}\n.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1;}.form-actions:before,.form-actions:after{display:table;content:\"\";line-height:0;}\n.form-actions:after{clear:both;}\n.help-block,.help-inline{color:#595959;}\n.help-block{display:block;margin-bottom:10px;}\n.help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px;}\n.input-append,.input-prepend{margin-bottom:5px;font-size:0;white-space:nowrap;}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu{font-size:14px;}\n.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2;}\n.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #ffffff;background-color:#eeeeee;border:1px solid #ccc;}\n.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}\n.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546;}\n.input-prepend .add-on,.input-prepend .btn{margin-right:-1px;}\n.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}\n.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}.input-append input+.btn-group .btn,.input-append select+.btn-group .btn,.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}\n.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px;}\n.input-append .add-on:last-child,.input-append .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}\n.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}\n.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}\n.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}\n.input-prepend.input-append .btn-group:first-child{margin-left:0;}\ninput.search-query{padding-right:14px;padding-right:4px \\9;padding-left:14px;padding-left:4px \\9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;}\n.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}\n.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;}\n.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;}\n.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;}\n.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;}\n.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;*zoom:1;margin-bottom:0;vertical-align:middle;}\n.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none;}\n.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block;}\n.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0;}\n.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle;}\n.form-search .radio input[type=\"radio\"],.form-search .checkbox input[type=\"checkbox\"],.form-inline .radio input[type=\"radio\"],.form-inline .checkbox input[type=\"checkbox\"]{float:left;margin-right:3px;margin-left:0;}\n.control-group{margin-bottom:10px;}\nlegend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate;}\n.form-horizontal .control-group{margin-bottom:20px;*zoom:1;}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:\"\";line-height:0;}\n.form-horizontal .control-group:after{clear:both;}\n.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right;}\n.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0;}.form-horizontal .controls:first-child{*padding-left:180px;}\n.form-horizontal .help-block{margin-bottom:0;}\n.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block{margin-top:10px;}\n.form-horizontal .form-actions{padding-left:180px;}\n.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:14px;line-height:20px;*line-height:20px;text-align:center;vertical-align:middle;cursor:pointer;color:#333333;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);background-image:linear-gradient(to bottom, #ffffff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #bbbbbb;*border:0;border-bottom-color:#a2a2a2;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333333;background-color:#e6e6e6;*background-color:#d9d9d9;}\n.btn:active,.btn.active{background-color:#cccccc \\9;}\n.btn:first-child{*margin-left:0;}\n.btn:hover{color:#333333;text-decoration:none;background-color:#e6e6e6;*background-color:#d9d9d9;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear;}\n.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}\n.btn.active,.btn:active{background-color:#e6e6e6;background-color:#d9d9d9 \\9;background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);}\n.btn.disabled,.btn[disabled]{cursor:default;background-color:#e6e6e6;background-image:none;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}\n.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}\n.btn-large [class^=\"icon-\"],.btn-large [class*=\" icon-\"]{margin-top:2px;}\n.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}\n.btn-small [class^=\"icon-\"],.btn-small [class*=\" icon-\"]{margin-top:0;}\n.btn-mini{padding:1px 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}\n.btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}\n.btn-block+.btn-block{margin-top:5px;}\ninput[type=\"submit\"].btn-block,input[type=\"reset\"].btn-block,input[type=\"button\"].btn-block{width:100%;}\n.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255, 255, 255, 0.75);}\n.btn{border-color:#c5c5c5;border-color:rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);}\n.btn-primary{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #0088cc, #0044cc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));background-image:-webkit-linear-gradient(top, #0088cc, #0044cc);background-image:-o-linear-gradient(top, #0088cc, #0044cc);background-image:linear-gradient(to bottom, #0088cc, #0044cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);border-color:#0044cc #0044cc #002a80;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#0044cc;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#ffffff;background-color:#0044cc;*background-color:#003bb3;}\n.btn-primary:active,.btn-primary.active{background-color:#003399 \\9;}\n.btn-warning{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#ffffff;background-color:#f89406;*background-color:#df8505;}\n.btn-warning:active,.btn-warning.active{background-color:#c67605 \\9;}\n.btn-danger{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#da4f49;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(to bottom, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#ffffff;background-color:#bd362f;*background-color:#a9302a;}\n.btn-danger:active,.btn-danger.active{background-color:#942a25 \\9;}\n.btn-success{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(to bottom, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#ffffff;background-color:#51a351;*background-color:#499249;}\n.btn-success:active,.btn-success.active{background-color:#408140 \\9;}\n.btn-info{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(to bottom, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#ffffff;background-color:#2f96b4;*background-color:#2a85a0;}\n.btn-info:active,.btn-info.active{background-color:#24748c \\9;}\n.btn-inverse{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#363636;background-image:-moz-linear-gradient(top, #444444, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));background-image:-webkit-linear-gradient(top, #444444, #222222);background-image:-o-linear-gradient(top, #444444, #222222);background-image:linear-gradient(to bottom, #444444, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#222222;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#ffffff;background-color:#222222;*background-color:#151515;}\n.btn-inverse:active,.btn-inverse.active{background-color:#080808 \\9;}\nbutton.btn,input[type=\"submit\"].btn{*padding-top:3px;*padding-bottom:3px;}button.btn::-moz-focus-inner,input[type=\"submit\"].btn::-moz-focus-inner{padding:0;border:0;}\nbutton.btn.btn-large,input[type=\"submit\"].btn.btn-large{*padding-top:7px;*padding-bottom:7px;}\nbutton.btn.btn-small,input[type=\"submit\"].btn.btn-small{*padding-top:3px;*padding-bottom:3px;}\nbutton.btn.btn-mini,input[type=\"submit\"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px;}\n.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}\n.btn-link{border-color:transparent;cursor:pointer;color:#0088cc;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}\n.btn-link:hover{color:#005580;text-decoration:underline;background-color:transparent;}\n.btn-link[disabled]:hover{color:#333333;text-decoration:none;}\n[class^=\"icon-\"],[class*=\" icon-\"]{display:inline-block;width:14px;height:14px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url(http://github.com/%22../img/glyphicons-halflings.png/");background-position:14px 14px;background-repeat:no-repeat;margin-top:1px;}\n.icon-white,.nav-pills>.active>a>[class^=\"icon-\"],.nav-pills>.active>a>[class*=\" icon-\"],.nav-list>.active>a>[class^=\"icon-\"],.nav-list>.active>a>[class*=\" icon-\"],.navbar-inverse .nav>.active>a>[class^=\"icon-\"],.navbar-inverse .nav>.active>a>[class*=\" icon-\"],.dropdown-menu>li>a:hover>[class^=\"icon-\"],.dropdown-menu>li>a:hover>[class*=\" icon-\"],.dropdown-menu>.active>a>[class^=\"icon-\"],.dropdown-menu>.active>a>[class*=\" icon-\"],.dropdown-submenu:hover>a>[class^=\"icon-\"],.dropdown-submenu:hover>a>[class*=\" icon-\"]{background-image:url(http://github.com/%22../img/glyphicons-halflings-white.png/");}\n.icon-glass{background-position:0 0;}\n.icon-music{background-position:-24px 0;}\n.icon-search{background-position:-48px 0;}\n.icon-envelope{background-position:-72px 0;}\n.icon-heart{background-position:-96px 0;}\n.icon-star{background-position:-120px 0;}\n.icon-star-empty{background-position:-144px 0;}\n.icon-user{background-position:-168px 0;}\n.icon-film{background-position:-192px 0;}\n.icon-th-large{background-position:-216px 0;}\n.icon-th{background-position:-240px 0;}\n.icon-th-list{background-position:-264px 0;}\n.icon-ok{background-position:-288px 0;}\n.icon-remove{background-position:-312px 0;}\n.icon-zoom-in{background-position:-336px 0;}\n.icon-zoom-out{background-position:-360px 0;}\n.icon-off{background-position:-384px 0;}\n.icon-signal{background-position:-408px 0;}\n.icon-cog{background-position:-432px 0;}\n.icon-trash{background-position:-456px 0;}\n.icon-home{background-position:0 -24px;}\n.icon-file{background-position:-24px -24px;}\n.icon-time{background-position:-48px -24px;}\n.icon-road{background-position:-72px -24px;}\n.icon-download-alt{background-position:-96px -24px;}\n.icon-download{background-position:-120px -24px;}\n.icon-upload{background-position:-144px -24px;}\n.icon-inbox{background-position:-168px -24px;}\n.icon-play-circle{background-position:-192px -24px;}\n.icon-repeat{background-position:-216px -24px;}\n.icon-refresh{background-position:-240px -24px;}\n.icon-list-alt{background-position:-264px -24px;}\n.icon-lock{background-position:-287px -24px;}\n.icon-flag{background-position:-312px -24px;}\n.icon-headphones{background-position:-336px -24px;}\n.icon-volume-off{background-position:-360px -24px;}\n.icon-volume-down{background-position:-384px -24px;}\n.icon-volume-up{background-position:-408px -24px;}\n.icon-qrcode{background-position:-432px -24px;}\n.icon-barcode{background-position:-456px -24px;}\n.icon-tag{background-position:0 -48px;}\n.icon-tags{background-position:-25px -48px;}\n.icon-book{background-position:-48px -48px;}\n.icon-bookmark{background-position:-72px -48px;}\n.icon-print{background-position:-96px -48px;}\n.icon-camera{background-position:-120px -48px;}\n.icon-font{background-position:-144px -48px;}\n.icon-bold{background-position:-167px -48px;}\n.icon-italic{background-position:-192px -48px;}\n.icon-text-height{background-position:-216px -48px;}\n.icon-text-width{background-position:-240px -48px;}\n.icon-align-left{background-position:-264px -48px;}\n.icon-align-center{background-position:-288px -48px;}\n.icon-align-right{background-position:-312px -48px;}\n.icon-align-justify{background-position:-336px -48px;}\n.icon-list{background-position:-360px -48px;}\n.icon-indent-left{background-position:-384px -48px;}\n.icon-indent-right{background-position:-408px -48px;}\n.icon-facetime-video{background-position:-432px -48px;}\n.icon-picture{background-position:-456px -48px;}\n.icon-pencil{background-position:0 -72px;}\n.icon-map-marker{background-position:-24px -72px;}\n.icon-adjust{background-position:-48px -72px;}\n.icon-tint{background-position:-72px -72px;}\n.icon-edit{background-position:-96px -72px;}\n.icon-share{background-position:-120px -72px;}\n.icon-check{background-position:-144px -72px;}\n.icon-move{background-position:-168px -72px;}\n.icon-step-backward{background-position:-192px -72px;}\n.icon-fast-backward{background-position:-216px -72px;}\n.icon-backward{background-position:-240px -72px;}\n.icon-play{background-position:-264px -72px;}\n.icon-pause{background-position:-288px -72px;}\n.icon-stop{background-position:-312px -72px;}\n.icon-forward{background-position:-336px -72px;}\n.icon-fast-forward{background-position:-360px -72px;}\n.icon-step-forward{background-position:-384px -72px;}\n.icon-eject{background-position:-408px -72px;}\n.icon-chevron-left{background-position:-432px -72px;}\n.icon-chevron-right{background-position:-456px -72px;}\n.icon-plus-sign{background-position:0 -96px;}\n.icon-minus-sign{background-position:-24px -96px;}\n.icon-remove-sign{background-position:-48px -96px;}\n.icon-ok-sign{background-position:-72px -96px;}\n.icon-question-sign{background-position:-96px -96px;}\n.icon-info-sign{background-position:-120px -96px;}\n.icon-screenshot{background-position:-144px -96px;}\n.icon-remove-circle{background-position:-168px -96px;}\n.icon-ok-circle{background-position:-192px -96px;}\n.icon-ban-circle{background-position:-216px -96px;}\n.icon-arrow-left{background-position:-240px -96px;}\n.icon-arrow-right{background-position:-264px -96px;}\n.icon-arrow-up{background-position:-289px -96px;}\n.icon-arrow-down{background-position:-312px -96px;}\n.icon-share-alt{background-position:-336px -96px;}\n.icon-resize-full{background-position:-360px -96px;}\n.icon-resize-small{background-position:-384px -96px;}\n.icon-plus{background-position:-408px -96px;}\n.icon-minus{background-position:-433px -96px;}\n.icon-asterisk{background-position:-456px -96px;}\n.icon-exclamation-sign{background-position:0 -120px;}\n.icon-gift{background-position:-24px -120px;}\n.icon-leaf{background-position:-48px -120px;}\n.icon-fire{background-position:-72px -120px;}\n.icon-eye-open{background-position:-96px -120px;}\n.icon-eye-close{background-position:-120px -120px;}\n.icon-warning-sign{background-position:-144px -120px;}\n.icon-plane{background-position:-168px -120px;}\n.icon-calendar{background-position:-192px -120px;}\n.icon-random{background-position:-216px -120px;width:16px;}\n.icon-comment{background-position:-240px -120px;}\n.icon-magnet{background-position:-264px -120px;}\n.icon-chevron-up{background-position:-288px -120px;}\n.icon-chevron-down{background-position:-313px -119px;}\n.icon-retweet{background-position:-336px -120px;}\n.icon-shopping-cart{background-position:-360px -120px;}\n.icon-folder-close{background-position:-384px -120px;}\n.icon-folder-open{background-position:-408px -120px;width:16px;}\n.icon-resize-vertical{background-position:-432px -119px;}\n.icon-resize-horizontal{background-position:-456px -118px;}\n.icon-hdd{background-position:0 -144px;}\n.icon-bullhorn{background-position:-24px -144px;}\n.icon-bell{background-position:-48px -144px;}\n.icon-certificate{background-position:-72px -144px;}\n.icon-thumbs-up{background-position:-96px -144px;}\n.icon-thumbs-down{background-position:-120px -144px;}\n.icon-hand-right{background-position:-144px -144px;}\n.icon-hand-left{background-position:-168px -144px;}\n.icon-hand-up{background-position:-192px -144px;}\n.icon-hand-down{background-position:-216px -144px;}\n.icon-circle-arrow-right{background-position:-240px -144px;}\n.icon-circle-arrow-left{background-position:-264px -144px;}\n.icon-circle-arrow-up{background-position:-288px -144px;}\n.icon-circle-arrow-down{background-position:-312px -144px;}\n.icon-globe{background-position:-336px -144px;}\n.icon-wrench{background-position:-360px -144px;}\n.icon-tasks{background-position:-384px -144px;}\n.icon-filter{background-position:-408px -144px;}\n.icon-briefcase{background-position:-432px -144px;}\n.icon-fullscreen{background-position:-456px -144px;}\n.btn-group{position:relative;display:inline-block;*display:inline;*zoom:1;font-size:0;vertical-align:middle;white-space:nowrap;*margin-left:.3em;}.btn-group:first-child{*margin-left:0;}\n.btn-group+.btn-group{margin-left:5px;}\n.btn-toolbar{font-size:0;margin-top:10px;margin-bottom:10px;}.btn-toolbar .btn+.btn,.btn-toolbar .btn-group+.btn,.btn-toolbar .btn+.btn-group{margin-left:5px;}\n.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}\n.btn-group>.btn+.btn{margin-left:-1px;}\n.btn-group>.btn,.btn-group>.dropdown-menu{font-size:14px;}\n.btn-group>.btn-mini{font-size:11px;}\n.btn-group>.btn-small{font-size:12px;}\n.btn-group>.btn-large{font-size:16px;}\n.btn-group>.btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;}\n.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;}\n.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;}\n.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;}\n.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2;}\n.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0;}\n.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);*padding-top:5px;*padding-bottom:5px;}\n.btn-group>.btn-mini+.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:2px;*padding-bottom:2px;}\n.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px;}\n.btn-group>.btn-large+.dropdown-toggle{padding-left:12px;padding-right:12px;*padding-top:7px;*padding-bottom:7px;}\n.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);}\n.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6;}\n.btn-group.open .btn-primary.dropdown-toggle{background-color:#0044cc;}\n.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406;}\n.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f;}\n.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351;}\n.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4;}\n.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222222;}\n.btn .caret{margin-top:8px;margin-left:0;}\n.btn-mini .caret,.btn-small .caret,.btn-large .caret{margin-top:6px;}\n.btn-large .caret{border-left-width:5px;border-right-width:5px;border-top-width:5px;}\n.dropup .btn-large .caret{border-bottom-width:5px;}\n.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;}\n.btn-group-vertical{display:inline-block;*display:inline;*zoom:1;}\n.btn-group-vertical .btn{display:block;float:none;width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}\n.btn-group-vertical .btn+.btn{margin-left:0;margin-top:-1px;}\n.btn-group-vertical .btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}\n.btn-group-vertical .btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}\n.btn-group-vertical .btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0;}\n.btn-group-vertical .btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;}\n.nav{margin-left:0;margin-bottom:20px;list-style:none;}\n.nav>li>a{display:block;}\n.nav>li>a:hover{text-decoration:none;background-color:#eeeeee;}\n.nav>.pull-right{float:right;}\n.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999999;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);text-transform:uppercase;}\n.nav li+.nav-header{margin-top:9px;}\n.nav-list{padding-left:15px;padding-right:15px;margin-bottom:0;}\n.nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);}\n.nav-list>li>a{padding:3px 15px;}\n.nav-list>.active>a,.nav-list>.active>a:hover{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.2);background-color:#0088cc;}\n.nav-list [class^=\"icon-\"],.nav-list [class*=\" icon-\"]{margin-right:2px;}\n.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;}\n.nav-tabs,.nav-pills{*zoom:1;}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:\"\";line-height:0;}\n.nav-tabs:after,.nav-pills:after{clear:both;}\n.nav-tabs>li,.nav-pills>li{float:left;}\n.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px;}\n.nav-tabs{border-bottom:1px solid #ddd;}\n.nav-tabs>li{margin-bottom:-1px;}\n.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #dddddd;}\n.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555555;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;}\n.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}\n.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#ffffff;background-color:#0088cc;}\n.nav-stacked>li{float:none;}\n.nav-stacked>li>a{margin-right:0;}\n.nav-tabs.nav-stacked{border-bottom:0;}\n.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}\n.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;}\n.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;}\n.nav-tabs.nav-stacked>li>a:hover{border-color:#ddd;z-index:2;}\n.nav-pills.nav-stacked>li>a{margin-bottom:3px;}\n.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px;}\n.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;}\n.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}\n.nav .dropdown-toggle .caret{border-top-color:#0088cc;border-bottom-color:#0088cc;margin-top:6px;}\n.nav .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580;}\n.nav-tabs .dropdown-toggle .caret{margin-top:8px;}\n.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff;}\n.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;}\n.nav>.dropdown.active>a:hover{cursor:pointer;}\n.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover{color:#ffffff;background-color:#999999;border-color:#999999;}\n.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;opacity:1;filter:alpha(opacity=100);}\n.tabs-stacked .open>a:hover{border-color:#999999;}\n.tabbable{*zoom:1;}.tabbable:before,.tabbable:after{display:table;content:\"\";line-height:0;}\n.tabbable:after{clear:both;}\n.tab-content{overflow:auto;}\n.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0;}\n.tab-content>.tab-pane,.pill-content>.pill-pane{display:none;}\n.tab-content>.active,.pill-content>.active{display:block;}\n.tabs-below>.nav-tabs{border-top:1px solid #ddd;}\n.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0;}\n.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}.tabs-below>.nav-tabs>li>a:hover{border-bottom-color:transparent;border-top-color:#ddd;}\n.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd #ddd;}\n.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none;}\n.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px;}\n.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd;}\n.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}\n.tabs-left>.nav-tabs>li>a:hover{border-color:#eeeeee #dddddd #eeeeee #eeeeee;}\n.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#ffffff;}\n.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd;}\n.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}\n.tabs-right>.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #eeeeee #dddddd;}\n.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#ffffff;}\n.nav>.disabled>a{color:#999999;}\n.nav>.disabled>a:hover{text-decoration:none;background-color:transparent;cursor:default;}\n.navbar{overflow:visible;margin-bottom:20px;color:#777777;*position:relative;*z-index:2;}\n.navbar-inner{min-height:40px;padding-left:20px;padding-right:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top, #ffffff, #f2f2f2);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));background-image:-webkit-linear-gradient(top, #ffffff, #f2f2f2);background-image:-o-linear-gradient(top, #ffffff, #f2f2f2);background-image:linear-gradient(to bottom, #ffffff, #f2f2f2);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);-moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);*zoom:1;}.navbar-inner:before,.navbar-inner:after{display:table;content:\"\";line-height:0;}\n.navbar-inner:after{clear:both;}\n.navbar .container{width:auto;}\n.nav-collapse.collapse{height:auto;overflow:visible;}\n.navbar .brand{float:left;display:block;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777777;text-shadow:0 1px 0 #ffffff;}.navbar .brand:hover{text-decoration:none;}\n.navbar-text{margin-bottom:0;line-height:40px;}\n.navbar-link{color:#777777;}.navbar-link:hover{color:#333333;}\n.navbar .divider-vertical{height:40px;margin:0 9px;border-left:1px solid #f2f2f2;border-right:1px solid #ffffff;}\n.navbar .btn,.navbar .btn-group{margin-top:5px;}\n.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn{margin-top:0;}\n.navbar-form{margin-bottom:0;*zoom:1;}.navbar-form:before,.navbar-form:after{display:table;content:\"\";line-height:0;}\n.navbar-form:after{clear:both;}\n.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px;}\n.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0;}\n.navbar-form input[type=\"image\"],.navbar-form input[type=\"checkbox\"],.navbar-form input[type=\"radio\"]{margin-top:3px;}\n.navbar-form .input-append,.navbar-form .input-prepend{margin-top:6px;white-space:nowrap;}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0;}\n.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0;}.navbar-search .search-query{margin-bottom:0;padding:4px 14px;font-family:\"Helvetica Neue\",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;}\n.navbar-static-top{position:static;margin-bottom:0;}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}\n.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0;}\n.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px;}\n.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0;}\n.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}\n.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;}\n.navbar-fixed-top{top:0;}\n.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,.1);box-shadow:0 1px 10px rgba(0,0,0,.1);}\n.navbar-fixed-bottom{bottom:0;}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,.1);box-shadow:0 -1px 10px rgba(0,0,0,.1);}\n.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0;}\n.navbar .nav.pull-right{float:right;margin-right:0;}\n.navbar .nav>li{float:left;}\n.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777777;text-decoration:none;text-shadow:0 1px 0 #ffffff;}\n.navbar .nav .dropdown-toggle .caret{margin-top:8px;}\n.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{background-color:transparent;color:#333333;text-decoration:none;}\n.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);-moz-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);}\n.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#ededed;background-image:-moz-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5));background-image:-webkit-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-o-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:linear-gradient(to bottom, #f2f2f2, #e5e5e5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0);border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e5e5e5;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#ffffff;background-color:#e5e5e5;*background-color:#d9d9d9;}\n.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#cccccc \\9;}\n.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);-moz-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);}\n.btn-navbar .icon-bar+.icon-bar{margin-top:3px;}\n.navbar .nav>li>.dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0, 0, 0, 0.2);position:absolute;top:-7px;left:9px;}\n.navbar .nav>li>.dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #ffffff;position:absolute;top:-6px;left:10px;}\n.navbar-fixed-bottom .nav>li>.dropdown-menu:before{border-top:7px solid #ccc;border-top-color:rgba(0, 0, 0, 0.2);border-bottom:0;bottom:-7px;top:auto;}\n.navbar-fixed-bottom .nav>li>.dropdown-menu:after{border-top:6px solid #ffffff;border-bottom:0;bottom:-6px;top:auto;}\n.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:#e5e5e5;color:#555555;}\n.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777777;border-bottom-color:#777777;}\n.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;}\n.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{left:auto;right:0;}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{left:auto;right:12px;}\n.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{left:auto;right:13px;}\n.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{left:auto;right:100%;margin-left:0;margin-right:-1px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;}\n.navbar-inverse{color:#999999;}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top, #222222, #111111);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111));background-image:-webkit-linear-gradient(top, #222222, #111111);background-image:-o-linear-gradient(top, #222222, #111111);background-image:linear-gradient(to bottom, #222222, #111111);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0);border-color:#252525;}\n.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999999;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover{color:#ffffff;}\n.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{background-color:transparent;color:#ffffff;}\n.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#ffffff;background-color:#111111;}\n.navbar-inverse .navbar-link{color:#999999;}.navbar-inverse .navbar-link:hover{color:#ffffff;}\n.navbar-inverse .divider-vertical{border-left-color:#111111;border-right-color:#222222;}\n.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{background-color:#111111;color:#ffffff;}\n.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999999;border-bottom-color:#999999;}\n.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;}\n.navbar-inverse .navbar-search .search-query{color:#ffffff;background-color:#515151;border-color:#111111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none;}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#cccccc;}\n.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#cccccc;}\n.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#cccccc;}\n.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333333;text-shadow:0 1px 0 #ffffff;background-color:#ffffff;border:0;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);outline:0;}\n.navbar-inverse .btn-navbar{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e0e0e;background-image:-moz-linear-gradient(top, #151515, #040404);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));background-image:-webkit-linear-gradient(top, #151515, #040404);background-image:-o-linear-gradient(top, #151515, #040404);background-image:linear-gradient(to bottom, #151515, #040404);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0);border-color:#040404 #040404 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#040404;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#ffffff;background-color:#040404;*background-color:#000000;}\n.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000000 \\9;}\n.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.breadcrumb li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #ffffff;}\n.breadcrumb .divider{padding:0 5px;color:#ccc;}\n.breadcrumb .active{color:#999999;}\n.pagination{margin:20px 0;}\n.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);}\n.pagination ul>li{display:inline;}\n.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#ffffff;border:1px solid #dddddd;border-left-width:0;}\n.pagination ul>li>a:hover,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5;}\n.pagination ul>.active>a,.pagination ul>.active>span{color:#999999;cursor:default;}\n.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover{color:#999999;background-color:transparent;cursor:default;}\n.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;}\n.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;}\n.pagination-centered{text-align:center;}\n.pagination-right{text-align:right;}\n.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px;}\n.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;}\n.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;}\n.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-top-left-radius:3px;-moz-border-radius-topleft:3px;border-top-left-radius:3px;-webkit-border-bottom-left-radius:3px;-moz-border-radius-bottomleft:3px;border-bottom-left-radius:3px;}\n.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;-moz-border-radius-topright:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;-moz-border-radius-bottomright:3px;border-bottom-right-radius:3px;}\n.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px;}\n.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:1px 6px;font-size:10.5px;}\n.pager{margin:20px 0;list-style:none;text-align:center;*zoom:1;}.pager:before,.pager:after{display:table;content:\"\";line-height:0;}\n.pager:after{clear:both;}\n.pager li{display:inline;}\n.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;}\n.pager li>a:hover{text-decoration:none;background-color:#f5f5f5;}\n.pager .next>a,.pager .next>span{float:right;}\n.pager .previous>a,.pager .previous>span{float:left;}\n.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>span{color:#999999;background-color:#fff;cursor:default;}\n.thumbnails{margin-left:-20px;list-style:none;*zoom:1;}.thumbnails:before,.thumbnails:after{display:table;content:\"\";line-height:0;}\n.thumbnails:after{clear:both;}\n.row-fluid .thumbnails{margin-left:0;}\n.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px;}\n.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;-o-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out;}\na.thumbnail:hover{border-color:#0088cc;-webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);-moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);}\n.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto;}\n.thumbnail .caption{padding:9px;color:#555555;}\n.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;color:#c09853;}\n.alert h4{margin:0;}\n.alert .close{position:relative;top:-2px;right:-21px;line-height:20px;}\n.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847;}\n.alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48;}\n.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad;}\n.alert-block{padding-top:14px;padding-bottom:14px;}\n.alert-block>p,.alert-block>ul{margin-bottom:0;}\n.alert-block p+p{margin-top:5px;}\n@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-o-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f7f7f7;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(to bottom, #f5f5f5, #f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}\n.progress .bar{width:0%;height:100%;color:#ffffff;float:left;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(to bottom, #149bdf, #0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;}\n.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);}\n.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px;}\n.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite;}\n.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(to bottom, #ee5f5b, #c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0);}\n.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}\n.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(to bottom, #62c462, #57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0);}\n.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}\n.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(to bottom, #5bc0de, #339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0);}\n.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}\n.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);}\n.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}\n.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eeeeee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;color:inherit;letter-spacing:-1px;}\n.hero-unit li{line-height:30px;}\n.media,.media-body{overflow:hidden;*overflow:visible;zoom:1;}\n.media,.media .media{margin-top:15px;}\n.media:first-child{margin-top:0;}\n.media-object{display:block;}\n.media-heading{margin:0 0 5px;}\n.media .pull-left{margin-right:10px;}\n.media .pull-right{margin-left:10px;}\n.media-list{margin-left:0;list-style:none;}\n.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);}.tooltip.in{opacity:0.8;filter:alpha(opacity=80);}\n.tooltip.top{margin-top:-3px;}\n.tooltip.right{margin-left:3px;}\n.tooltip.bottom{margin-top:3px;}\n.tooltip.left{margin-left:-3px;}\n.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#000000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}\n.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid;}\n.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000000;}\n.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000000;}\n.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000000;}\n.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000000;}\n.popover{position:absolute;top:0;left:0;z-index:1010;display:none;width:236px;padding:1px;background-color:#ffffff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);}.popover.top{margin-top:-10px;}\n.popover.right{margin-left:10px;}\n.popover.bottom{margin-top:10px;}\n.popover.left{margin-left:-10px;}\n.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0;}\n.popover-content{padding:9px 14px;}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0;}\n.popover .arrow,.popover .arrow:after{position:absolute;display:inline-block;width:0;height:0;border-color:transparent;border-style:solid;}\n.popover .arrow:after{content:\"\";z-index:-1;}\n.popover.top .arrow{bottom:-10px;left:50%;margin-left:-10px;border-width:10px 10px 0;border-top-color:#ffffff;}.popover.top .arrow:after{border-width:11px 11px 0;border-top-color:rgba(0, 0, 0, 0.25);bottom:-1px;left:-11px;}\n.popover.right .arrow{top:50%;left:-10px;margin-top:-10px;border-width:10px 10px 10px 0;border-right-color:#ffffff;}.popover.right .arrow:after{border-width:11px 11px 11px 0;border-right-color:rgba(0, 0, 0, 0.25);bottom:-11px;left:-1px;}\n.popover.bottom .arrow{top:-10px;left:50%;margin-left:-10px;border-width:0 10px 10px;border-bottom-color:#ffffff;}.popover.bottom .arrow:after{border-width:0 11px 11px;border-bottom-color:rgba(0, 0, 0, 0.25);top:-1px;left:-11px;}\n.popover.left .arrow{top:50%;right:-10px;margin-top:-10px;border-width:10px 0 10px 10px;border-left-color:#ffffff;}.popover.left .arrow:after{border-width:11px 0 11px 11px;border-left-color:rgba(0, 0, 0, 0.25);bottom:-11px;right:-1px;}\n.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000;}.modal-backdrop.fade{opacity:0;}\n.modal-backdrop,.modal-backdrop.fade.in{opacity:0.8;filter:alpha(opacity=80);}\n.modal{position:fixed;top:50%;left:50%;z-index:1050;width:560px;margin:-250px 0 0 -280px;background-color:#ffffff;border:1px solid #999;border:1px solid rgba(0, 0, 0, 0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;outline:none;}.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%;}\n.modal.fade.in{top:50%;}\n.modal-header{padding:9px 15px;border-bottom:1px solid #eee;}.modal-header .close{margin-top:2px;}\n.modal-header h3{margin:0;line-height:30px;}\n.modal-body{overflow-y:auto;max-height:400px;padding:15px;}\n.modal-form{margin-bottom:0;}\n.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;*zoom:1;}.modal-footer:before,.modal-footer:after{display:table;content:\"\";line-height:0;}\n.modal-footer:after{clear:both;}\n.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0;}\n.modal-footer .btn-group .btn+.btn{margin-left:-1px;}\n.modal-footer .btn-block+.btn-block{margin-left:0;}\n.dropup,.dropdown{position:relative;}\n.dropdown-toggle{*margin-bottom:-3px;}\n.dropdown-toggle:active,.open .dropdown-toggle{outline:0;}\n.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000000;border-right:4px solid transparent;border-left:4px solid transparent;content:\"\";}\n.dropdown .caret{margin-top:8px;margin-left:2px;}\n.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#ffffff;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;}.dropdown-menu.pull-right{right:0;left:auto;}\n.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;}\n.dropdown-menu li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333333;white-space:nowrap;}\n.dropdown-menu li>a:hover,.dropdown-menu li>a:focus,.dropdown-submenu:hover>a{text-decoration:none;color:#ffffff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #0088cc, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));background-image:-webkit-linear-gradient(top, #0088cc, #0077b3);background-image:-o-linear-gradient(top, #0088cc, #0077b3);background-image:linear-gradient(to bottom, #0088cc, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);}\n.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#333333;text-decoration:none;outline:0;background-color:#0081c2;background-image:-moz-linear-gradient(top, #0088cc, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));background-image:-webkit-linear-gradient(top, #0088cc, #0077b3);background-image:-o-linear-gradient(top, #0088cc, #0077b3);background-image:linear-gradient(to bottom, #0088cc, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);}\n.dropdown-menu .disabled>a,.dropdown-menu .disabled>a:hover{color:#999999;}\n.dropdown-menu .disabled>a:hover{text-decoration:none;background-color:transparent;background-image:none;cursor:default;}\n.open{*z-index:1000;}.open >.dropdown-menu{display:block;}\n.pull-right>.dropdown-menu{right:0;left:auto;}\n.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000000;content:\"\";}\n.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px;}\n.dropdown-submenu{position:relative;}\n.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px;}\n.dropdown-submenu:hover>.dropdown-menu{display:block;}\n.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0;}\n.dropdown-submenu>a:after{display:block;content:\" \";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#cccccc;margin-top:5px;margin-right:-10px;}\n.dropdown-submenu:hover>a:after{border-left-color:#ffffff;}\n.dropdown-submenu.pull-left{float:none;}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;}\n.dropdown .dropdown-menu .nav-header{padding-left:20px;padding-right:20px;}\n.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}\n.accordion{margin-bottom:20px;}\n.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}\n.accordion-heading{border-bottom:0;}\n.accordion-heading .accordion-toggle{display:block;padding:8px 15px;}\n.accordion-toggle{cursor:pointer;}\n.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5;}\n.carousel{position:relative;margin-bottom:20px;line-height:1;}\n.carousel-inner{overflow:hidden;width:100%;position:relative;}\n.carousel .item{display:none;position:relative;-webkit-transition:0.6s ease-in-out left;-moz-transition:0.6s ease-in-out left;-o-transition:0.6s ease-in-out left;transition:0.6s ease-in-out left;}\n.carousel .item>img{display:block;line-height:1;}\n.carousel .active,.carousel .next,.carousel .prev{display:block;}\n.carousel .active{left:0;}\n.carousel .next,.carousel .prev{position:absolute;top:0;width:100%;}\n.carousel .next{left:100%;}\n.carousel .prev{left:-100%;}\n.carousel .next.left,.carousel .prev.right{left:0;}\n.carousel .active.left{left:-100%;}\n.carousel .active.right{left:100%;}\n.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#ffffff;text-align:center;background:#222222;border:3px solid #ffffff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:0.5;filter:alpha(opacity=50);}.carousel-control.right{left:auto;right:15px;}\n.carousel-control:hover{color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90);}\n.carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:15px;background:#333333;background:rgba(0, 0, 0, 0.75);}\n.carousel-caption h4,.carousel-caption p{color:#ffffff;line-height:20px;}\n.carousel-caption h4{margin:0 0 5px;}\n.carousel-caption p{margin-bottom:0;}\n.media,.media-body{overflow:hidden;*overflow:visible;zoom:1;}\n.media,.media .media{margin-top:15px;}\n.media:first-child{margin-top:0;}\n.media-object{display:block;}\n.media-heading{margin:0 0 5px;}\n.media .pull-left{margin-right:10px;}\n.media .pull-right{margin-left:10px;}\n.media-list{margin-left:0;list-style:none;}\n.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);}\n.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}\n.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}\n.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.close:hover{color:#000000;text-decoration:none;cursor:pointer;opacity:0.4;filter:alpha(opacity=40);}\nbutton.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;}\n.pull-right{float:right;}\n.pull-left{float:left;}\n.hide{display:none;}\n.show{display:block;}\n.invisible{visibility:hidden;}\n.affix{position:fixed;}\n.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear;}.fade.in{opacity:1;}\n.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height 0.35s ease;-moz-transition:height 0.35s ease;-o-transition:height 0.35s ease;transition:height 0.35s ease;}.collapse.in{height:auto;}\n.hidden{display:none;visibility:hidden;}\n.visible-phone{display:none !important;}\n.visible-tablet{display:none !important;}\n.hidden-desktop{display:none !important;}\n.visible-desktop{display:inherit !important;}\n@media (min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important ;} .visible-tablet{display:inherit !important;} .hidden-tablet{display:none !important;}}@media (max-width:767px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important;} .visible-phone{display:inherit !important;} .hidden-phone{display:none !important;}}@media (max-width:767px){body{padding-left:20px;padding-right:20px;} .navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-left:-20px;margin-right:-20px;} .container-fluid{padding:0;} .dl-horizontal dt{float:none;clear:none;width:auto;text-align:left;} .dl-horizontal dd{margin-left:0;} .container{width:auto;} .row-fluid{width:100%;} .row,.thumbnails{margin-left:0;} .thumbnails>li{float:none;margin-left:0;} [class*=\"span\"],.uneditable-input[class*=\"span\"],.row-fluid [class*=\"span\"]{float:none;display:block;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .row-fluid [class*=\"offset\"]:first-child{margin-left:0;} .input-large,.input-xlarge,.input-xxlarge,input[class*=\"span\"],select[class*=\"span\"],textarea[class*=\"span\"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .input-prepend input,.input-append input,.input-prepend input[class*=\"span\"],.input-append input[class*=\"span\"]{display:inline-block;width:auto;} .controls-row [class*=\"span\"]+[class*=\"span\"]{margin-left:0;} .modal{position:fixed;top:20px;left:20px;right:20px;width:auto;margin:0;}.modal.fade{top:-100px;} .modal.fade.in{top:20px;}}@media (max-width:480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0);} .page-header h1 small{display:block;line-height:20px;} input[type=\"checkbox\"],input[type=\"radio\"]{border:1px solid #ccc;} .form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left;} .form-horizontal .controls{margin-left:0;} .form-horizontal .control-list{padding-top:0;} .form-horizontal .form-actions{padding-left:10px;padding-right:10px;} .media .pull-left,.media .pull-right{float:none;display:block;margin-bottom:10px;} .media-object{margin-right:0;margin-left:0;} .modal{top:10px;left:10px;right:10px;} .modal-header .close{padding:10px;margin:-10px;} .carousel-caption{position:static;}}@media (min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:\"\";line-height:0;} .row:after{clear:both;} [class*=\"span\"]{float:left;min-height:1px;margin-left:20px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px;} .span12{width:724px;} .span11{width:662px;} .span10{width:600px;} .span9{width:538px;} .span8{width:476px;} .span7{width:414px;} .span6{width:352px;} .span5{width:290px;} .span4{width:228px;} .span3{width:166px;} .span2{width:104px;} .span1{width:42px;} .offset12{margin-left:764px;} .offset11{margin-left:702px;} .offset10{margin-left:640px;} .offset9{margin-left:578px;} .offset8{margin-left:516px;} .offset7{margin-left:454px;} .offset6{margin-left:392px;} .offset5{margin-left:330px;} .offset4{margin-left:268px;} .offset3{margin-left:206px;} .offset2{margin-left:144px;} .offset1{margin-left:82px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:\"\";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*=\"span\"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;} .row-fluid [class*=\"span\"]:first-child{margin-left:0;} .row-fluid .controls-row [class*=\"span\"]+[class*=\"span\"]{margin-left:2.7624309392265194%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%;} .row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%;} .row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%;} .row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%;} .row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%;} .row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%;} .row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%;} .row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%;} .row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%;} .row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%;} .row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%;} .row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%;} .row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%;} .row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%;} .row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%;} .row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%;} .row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%;} .row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%;} .row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%;} .row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%;} .row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%;} .row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%;} .row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%;} .row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%;} .row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%;} .row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%;} .row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%;} .row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%;} .row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%;} .row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%;} .row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%;} .row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%;} .row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%;} .row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%;} .row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*=\"span\"]+[class*=\"span\"]{margin-left:20px;} input.span12, textarea.span12, .uneditable-input.span12{width:710px;} input.span11, textarea.span11, .uneditable-input.span11{width:648px;} input.span10, textarea.span10, .uneditable-input.span10{width:586px;} input.span9, textarea.span9, .uneditable-input.span9{width:524px;} input.span8, textarea.span8, .uneditable-input.span8{width:462px;} input.span7, textarea.span7, .uneditable-input.span7{width:400px;} input.span6, textarea.span6, .uneditable-input.span6{width:338px;} input.span5, textarea.span5, .uneditable-input.span5{width:276px;} input.span4, textarea.span4, .uneditable-input.span4{width:214px;} input.span3, textarea.span3, .uneditable-input.span3{width:152px;} input.span2, textarea.span2, .uneditable-input.span2{width:90px;} input.span1, textarea.span1, .uneditable-input.span1{width:28px;}}@media (min-width:1200px){.row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:\"\";line-height:0;} .row:after{clear:both;} [class*=\"span\"]{float:left;min-height:1px;margin-left:30px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px;} .span12{width:1170px;} .span11{width:1070px;} .span10{width:970px;} .span9{width:870px;} .span8{width:770px;} .span7{width:670px;} .span6{width:570px;} .span5{width:470px;} .span4{width:370px;} .span3{width:270px;} .span2{width:170px;} .span1{width:70px;} .offset12{margin-left:1230px;} .offset11{margin-left:1130px;} .offset10{margin-left:1030px;} .offset9{margin-left:930px;} .offset8{margin-left:830px;} .offset7{margin-left:730px;} .offset6{margin-left:630px;} .offset5{margin-left:530px;} .offset4{margin-left:430px;} .offset3{margin-left:330px;} .offset2{margin-left:230px;} .offset1{margin-left:130px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:\"\";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*=\"span\"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;} .row-fluid [class*=\"span\"]:first-child{margin-left:0;} .row-fluid .controls-row [class*=\"span\"]+[class*=\"span\"]{margin-left:2.564102564102564%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%;} .row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%;} .row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%;} .row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%;} .row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%;} .row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%;} .row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%;} .row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%;} .row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%;} .row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%;} .row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%;} .row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%;} .row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%;} .row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%;} .row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%;} .row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%;} .row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%;} .row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%;} .row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%;} .row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%;} .row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%;} .row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%;} .row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%;} .row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%;} .row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%;} .row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%;} .row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%;} .row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%;} .row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%;} .row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%;} .row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%;} .row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%;} .row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%;} .row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%;} .row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*=\"span\"]+[class*=\"span\"]{margin-left:30px;} input.span12, textarea.span12, .uneditable-input.span12{width:1156px;} input.span11, textarea.span11, .uneditable-input.span11{width:1056px;} input.span10, textarea.span10, .uneditable-input.span10{width:956px;} input.span9, textarea.span9, .uneditable-input.span9{width:856px;} input.span8, textarea.span8, .uneditable-input.span8{width:756px;} input.span7, textarea.span7, .uneditable-input.span7{width:656px;} input.span6, textarea.span6, .uneditable-input.span6{width:556px;} input.span5, textarea.span5, .uneditable-input.span5{width:456px;} input.span4, textarea.span4, .uneditable-input.span4{width:356px;} input.span3, textarea.span3, .uneditable-input.span3{width:256px;} input.span2, textarea.span2, .uneditable-input.span2{width:156px;} input.span1, textarea.span1, .uneditable-input.span1{width:56px;} .thumbnails{margin-left:-30px;} .thumbnails>li{margin-left:30px;} .row-fluid .thumbnails{margin-left:0;}}@media (max-width:979px){body{padding-top:0;} .navbar-fixed-top,.navbar-fixed-bottom{position:static;} .navbar-fixed-top{margin-bottom:20px;} .navbar-fixed-bottom{margin-top:20px;} .navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px;} .navbar .container{width:auto;padding:0;} .navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px;} .nav-collapse{clear:both;} .nav-collapse .nav{float:none;margin:0 0 10px;} .nav-collapse .nav>li{float:none;} .nav-collapse .nav>li>a{margin-bottom:2px;} .nav-collapse .nav>.divider-vertical{display:none;} .nav-collapse .nav .nav-header{color:#777777;text-shadow:none;} .nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} .nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} .nav-collapse .dropdown-menu li+li a{margin-bottom:2px;} .nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#f2f2f2;} .navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999999;} .navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:hover{background-color:#111111;} .nav-collapse.in .btn-group{margin-top:5px;padding:0;} .nav-collapse .dropdown-menu{position:static;top:auto;left:auto;float:none;display:none;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} .nav-collapse .open>.dropdown-menu{display:block;} .nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none;} .nav-collapse .dropdown-menu .divider{display:none;} .nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none;} .nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);} .navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111111;border-bottom-color:#111111;} .navbar .nav-collapse .nav.pull-right{float:none;margin-left:0;} .nav-collapse,.nav-collapse.collapse{overflow:hidden;height:0;} .navbar .btn-navbar{display:block;} .navbar-static .navbar-inner{padding-left:10px;padding-right:10px;}}@media (min-width:980px){.nav-collapse.collapse{height:auto !important;overflow:visible !important;}}\n"))
- template.Must(CSS.New("common.css").Parse("#chord_container {\n width: 100%;\n text-align: center;\n position: absolute;\n z-index: -10;\n}\n#chord {\n margin: auto;\n width: 1200px;\n height: 800px;\n}\n#nodes_container {\n float: right;\n font-family: \"Courier\";\n}\n#node_container {\n display: none;\n float: left;\n font-family: \"Courier\";\n}\n.node {\n cursor: pointer;\n}\n#code {\n width: 30em;\n height: 20em;\n}\n#execute {\n display: block;\n}\n"))
+ template.Must(CSS.New("common.css").Parse("#chord_container {\n width: 100%;\n text-align: center;\n position: absolute;\n z-index: -10;\n}\n#chord {\n margin: auto;\n width: 1200px;\n height: 800px;\n}\n#nodes_container {\n float: right;\n font-family: \"Courier\";\n}\n#nodes {\n background-color: rgba(255,255,255,0.9);\n border: 1px solid black;\n}\n#node_container {\n display: none;\n float: left;\n font-family: \"Courier\";\n}\n.node {\n cursor: pointer;\n}\n#code {\n width: 30em;\n height: 20em;\n}\n#execute {\n display: block;\n}\n"))
}
diff --git a/templates/css/common.css b/templates/css/common.css
index 3ee853c..db798e0 100644
--- a/templates/css/common.css
+++ b/templates/css/common.css
@@ -1,30 +1,34 @@
#chord_container {
- width: 100%;
- text-align: center;
- position: absolute;
- z-index: -10;
+ width: 100%;
+ text-align: center;
+ position: absolute;
+ z-index: -10;
}
#chord {
- margin: auto;
- width: 1200px;
- height: 800px;
+ margin: auto;
+ width: 1200px;
+ height: 800px;
}
#nodes_container {
float: right;
- font-family: "Courier";
+ font-family: "Courier";
+}
+#nodes {
+ background-color: rgba(255,255,255,0.9);
+ border: 1px solid black;
}
#node_container {
- display: none;
- float: left;
- font-family: "Courier";
+ display: none;
+ float: left;
+ font-family: "Courier";
}
.node {
- cursor: pointer;
+ cursor: pointer;
}
#code {
- width: 30em;
- height: 20em;
+ width: 30em;
+ height: 20em;
}
#execute {
- display: block;
+ display: block;
}
diff --git a/templates/html.go b/templates/html.go
index f807384..c937367 100644
--- a/templates/html.go
+++ b/templates/html.go
@@ -2,5 +2,5 @@ package templates
import "html/template"
var HTML = template.New("html")
func init() {
- template.Must(HTML.New("index.html").Parse("\n \n \n Go Database! Manager\n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n
×\n
\n node\n \n | gob rpc address | \n | \n
\n \n | JSON/HTTP rpc address | \n | \n
\n \n | position | \n | \n
\n \n | owned keys | \n | \n
\n \n | held keys | \n | \n
\n \n | load | \n | \n
\n
\n
\n \n\n"))
+ template.Must(HTML.New("index.html").Parse("\n \n \n Go Database! Manager\n \n \n \n \n \n \n \n\n \n \n \n
\n \n \n
×\n
\n node\n \n | gob rpc address | \n | \n
\n \n | JSON/HTTP rpc address | \n | \n
\n \n | position | \n | \n
\n \n | owned keys | \n | \n
\n \n | held keys | \n | \n
\n \n | load | \n | \n
\n
\n
\n\n\n"))
}
diff --git a/templates/html/index.html b/templates/html/index.html
index 3297096..95b0369 100644
--- a/templates/html/index.html
+++ b/templates/html/index.html
@@ -1,86 +1,86 @@
-
-
- Go Database! Manager
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
×
-
- node
-
- | gob rpc address |
- |
-
-
- | JSON/HTTP rpc address |
- |
-
-
- | position |
- |
-
-
- | owned keys |
- |
-
-
- | held keys |
- |
-
-
- | load |
- |
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
×
+
+ node
+
+ | gob rpc address |
+ |
+
+
+ | JSON/HTTP rpc address |
+ |
+
+
+ | position |
+ |
+
+
+ | owned keys |
+ |
+
+
+ | held keys |
+ |
+
+
+ | load |
+ |
+
+
+
+