diff --git a/2023/icons/ngSkinTools2.ico b/2023/icons/ngSkinTools2.ico
new file mode 100644
index 0000000..caf8aef
Binary files /dev/null and b/2023/icons/ngSkinTools2.ico differ
diff --git a/2023/icons/ngSkinTools2ShelfIcon.png b/2023/icons/ngSkinTools2ShelfIcon.png
new file mode 100644
index 0000000..08b27e1
Binary files /dev/null and b/2023/icons/ngSkinTools2ShelfIcon.png differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/README.md b/2023/scripts/rigging_tools/ngskintools2/README.md
new file mode 100644
index 0000000..3dbc940
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/README.md
@@ -0,0 +1,51 @@
+# ngSkinTools2 模块
+
+ngSkinTools2 是一个强大的 Maya 蒙皮权重编辑工具。
+
+## 📁 文件夹结构
+
+```
+ngskintools2/ # ngSkinTools2 核心模块
+├── __init__.py # 模块初始化(原始)
+├── launcher.py # 启动器脚本(新增)
+├── api/ # API 接口
+├── ui/ # 用户界面
+├── operations/ # 操作功能
+└── README.md # 本文档
+```
+
+## 🚀 使用方法
+
+### 从工具架启动
+
+1. 打开 Maya
+2. 切换到 **Nexus_Rigging** 工具架
+3. 点击 **ngSkin** 按钮
+
+### 从 Python 启动
+
+```python
+from rigging_tools.ngskintools2 import launcher
+launcher.LaunchNgSkinTools()
+```
+
+### 直接使用 ngSkinTools2 API
+
+```python
+from rigging_tools.ngskintools2 import open_ui
+open_ui()
+```
+
+## ✨ 主要功能
+
+- 高级权重绘制和编辑
+- 权重镜像和传递
+- 多层权重管理
+- 权重导入/导出
+- 影响对象管理
+
+## 📝 注意事项
+
+- 确保 Maya 版本兼容
+- 需要加载对应的插件
+- 建议在绑定工作流程中使用
diff --git a/2023/scripts/rigging_tools/ngskintools2/__init__.py b/2023/scripts/rigging_tools/ngskintools2/__init__.py
new file mode 100644
index 0000000..6798d37
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/__init__.py
@@ -0,0 +1,33 @@
+import os
+
+DEBUG_MODE = os.getenv("NGSKINTOOLS_DEBUG", 'false') == 'true'
+
+try:
+ from maya import cmds
+
+ BATCH_MODE = cmds.about(batch=True) == 1
+except:
+ BATCH_MODE = True
+
+
+def open_ui():
+ """
+ opens ngSkinTools2 main UI window. if the window is already open, brings that workspace
+ window to front.
+ """
+
+ from ngSkinTools2.ui import mainwindow
+
+ mainwindow.open()
+
+
+def workspace_control_main_window():
+ """
+ this function is used permanently by Maya's "workspace control", and acts as an alternative top-level entry point to open UI
+ """
+ from ngSkinTools2.ui import mainwindow
+ from ngSkinTools2.ui.paintContextCallbacks import definePaintContextCallbacks
+
+ definePaintContextCallbacks()
+
+ mainwindow.resume_in_workspace_control()
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/__init__.py b/2023/scripts/rigging_tools/ngskintools2/api/__init__.py
new file mode 100644
index 0000000..b3d854e
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/__init__.py
@@ -0,0 +1,40 @@
+from . import import_v1
+from .copy_paste_weights import PasteOperation, copy_weights, cut_weights, paste_weights
+from .import_export import FileFormat, export_json, import_json
+from .influenceMapping import InfluenceInfo, InfluenceMapping, InfluenceMappingConfig
+from .layers import (
+ Layer,
+ LayerEffects,
+ Layers,
+ NamedPaintTarget,
+ get_layers_enabled,
+ init_layers,
+)
+from .mirror import Mirror, MirrorOptions
+from .paint import (
+ BrushProjectionMode,
+ BrushShape,
+ PaintMode,
+ PaintModeSettings,
+ PaintTool,
+ TabletMode,
+ WeightsDisplayMode,
+)
+from .suspend_updates import suspend_updates
+from .target_info import (
+ add_influences,
+ get_related_skin_cluster,
+ is_slow_mode_skin_cluster,
+ list_influences,
+)
+from .tools import (
+ assign_from_closest_joint,
+ copy_component_weights,
+ duplicate_layer,
+ fill_transparency,
+ flood_weights,
+ merge_layers,
+ paste_average_component_weights,
+ unify_weights,
+)
+from .transfer import VertexTransferMode, transfer_layers
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/cmd_wrappers.py b/2023/scripts/rigging_tools/ngskintools2/api/cmd_wrappers.py
new file mode 100644
index 0000000..f4cb511
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/cmd_wrappers.py
@@ -0,0 +1,19 @@
+from maya import cmds
+
+
+def as_comma_separated_list(l):
+ return ",".join((str(i) for i in l))
+
+
+def get_source(plug, **kwargs):
+ for i in cmds.listConnections(plug, source=True, **kwargs) or []:
+ return i
+ return None
+
+
+def get_source_node(plug):
+ return get_source(plug, plugs=False)
+
+
+def get_source_plug(plug):
+ return get_source(plug, plugs=True)
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/config.py b/2023/scripts/rigging_tools/ngskintools2/api/config.py
new file mode 100644
index 0000000..d43f455
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/config.py
@@ -0,0 +1,47 @@
+import json
+
+from maya import cmds
+
+from ngSkinTools2.api.log import getLogger
+from ngSkinTools2.api.python_compatibility import Object
+
+log = getLogger("api/layers")
+
+
+def __define_property__(name, conversion, doc, refresh_on_write=True):
+ return property(
+ lambda self: conversion(self.__load__(name)), lambda self, val: self.__save__(name, conversion(val), refresh=refresh_on_write), doc=doc
+ )
+
+
+# noinspection PyBroadException
+class Config(Object):
+ """
+ per-skin-cluster configuration
+ """
+
+ influence_colors = __define_property__(
+ "influence_colors",
+ lambda v: {int(k): tuple(float(v[i]) for i in range(3)) for k, v in v.items()},
+ doc="Influence color map [logical index]->(r,g,b)",
+ refresh_on_write=True,
+ )
+
+ def __init__(self, data_node):
+ self.data_node = data_node
+
+ def __load__(self, attr):
+ try:
+ return json.loads(cmds.getAttr(self.data_node + ".config_" + attr))
+ except:
+ return None
+
+ def __save__(self, attr, value, refresh=False):
+ if not cmds.attributeQuery("config_" + attr, node=self.data_node, exists=True):
+ cmds.addAttr(self.data_node, dt="string", longName="config_" + attr)
+ cmds.setAttr(self.data_node + ".config_" + attr, json.dumps(value), type='string')
+
+ if refresh:
+ from ngSkinTools2.api.tools import refresh_screen
+
+ refresh_screen(self.data_node)
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/copy_paste_weights.py b/2023/scripts/rigging_tools/ngskintools2/api/copy_paste_weights.py
new file mode 100644
index 0000000..c9cdb34
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/copy_paste_weights.py
@@ -0,0 +1,37 @@
+from ngSkinTools2.api import plugin
+
+
+def __clipboard_operation__(layer, influences, operation):
+ influences = "" if influences is None else ','.join([str(i) for i in influences])
+ plugin.ngst2Layers(layer.mesh, e=True, id=layer.id, clipboard=operation, paintTarget=influences)
+
+
+def copy_weights(layer, influences):
+ """
+ :type layer: ngSkinTools2.api.layers.Layer
+ :type influences: list
+ """
+ __clipboard_operation__(layer, influences, 'copy')
+
+
+def cut_weights(layer, influences):
+ """
+ :type layer: ngSkinTools2.api.layers.Layer
+ :type influences: list
+ """
+ __clipboard_operation__(layer, influences, 'cut')
+
+
+class PasteOperation:
+ replace = 'pasteReplace'
+ add = 'pasteAdd'
+ subtract = 'pasteSubtract'
+
+
+def paste_weights(layer, operation=PasteOperation.replace, influences=None):
+ """
+ :type layer: ngSkinTools2.api.layers.Layer
+ :param operation: one of paste_* constants
+ :param influences: list of target influences
+ """
+ __clipboard_operation__(layer, influences, operation)
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/events.py b/2023/scripts/rigging_tools/ngskintools2/api/events.py
new file mode 100644
index 0000000..38efcee
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/events.py
@@ -0,0 +1,190 @@
+"""
+
+## Event handling brainstorm
+
+# Usecase: when selection changes, handlers need to update to this.
+
+Handlers are interested in same data (what's the selected mesh, are layers available, etc). When even is received
+by handler, all data to handle the even is there. Data is mostly pre-fetched (assuming that someone will eventually
+need it anyway), but for some events lazy-loading might be needed.
+
+# Usecase: event handlers need to respond only when data actually changes (state goes from "layers available"
+to "layers unavailable")
+
+Even handlers store that information on heir side. Signal has no way of knowing prevous state of the handler.
+
+# Usecase: event can be fired as a source of multiple other events (layer availability changed: could come from
+data transformation or undo/redo event)
+
+Events have their own hierarchy, "layers availability changed" signal stores information about it's previous state
+and emits if state changes.
+
+
+
+
+## Events hierarchy complexity
+
+Whenever possible, keep event tree localized in single place for easier refactoring.
+"""
+from maya import cmds
+
+from ngSkinTools2 import api, cleanup, signal
+from ngSkinTools2.api import target_info
+from ngSkinTools2.api.log import getLogger
+from ngSkinTools2.api.python_compatibility import Object
+from ngSkinTools2.signal import Signal
+
+log = getLogger("events")
+
+
+class ConditionalEmit(Object):
+ def __init__(self, name, check):
+ self.signal = Signal(name)
+ self.check = check
+
+ def emitIfChanged(self):
+ if self.check():
+ self.signal.emit()
+
+ def addHandler(self, handler, **kwargs):
+ self.signal.addHandler(handler, **kwargs)
+
+ def removeHandler(self, handler):
+ self.signal.removeHandler(handler)
+
+
+def script_job(*args, **kwargs):
+ """
+ a proxy on top of cmds.scriptJob for scriptJob creation;
+ will register an automatic cleanup procedure to kill the job
+ """
+ job = cmds.scriptJob(*args, **kwargs)
+
+ def kill():
+ # noinspection PyBroadException
+ try:
+ cmds.scriptJob(kill=job)
+ except:
+ # should be no issue if we cannot kill the job anymore (e.g., killing from the
+ # import traceback; traceback.print_exc()
+ pass
+
+ cleanup.registerCleanupHandler(kill)
+
+ return job
+
+
+class Events(Object):
+ """
+ root tree of events signaling each other
+ """
+
+ def __init__(self, state):
+ """
+
+ :type state: ngSkinTools2.api.session.State
+ """
+
+ def script_job_signal(name):
+ result = Signal(name + "_scriptJob")
+ script_job(e=[name, result.emit])
+ return result
+
+ self.mayaDeleteAll = script_job_signal('deleteAll')
+
+ self.nodeSelectionChanged = script_job_signal('SelectionChanged')
+
+ self.undoExecuted = script_job_signal('Undo')
+ self.redoExecuted = script_job_signal('Redo')
+ self.undoRedoExecuted = Signal('undoRedoExecuted')
+ self.undoExecuted.addHandler(self.undoRedoExecuted.emit)
+ self.redoExecuted.addHandler(self.undoRedoExecuted.emit)
+
+ self.toolChanged = script_job_signal('ToolChanged')
+ self.quitApplication = script_job_signal('quitApplication')
+
+ def check_target_changed():
+ """
+ verify that currently selected mesh is changed, and this means a change in LayersManager.
+ """
+ selection = cmds.ls(selection=True, objectsOnly=True) or []
+ selected_skin_cluster = None if not selection else target_info.get_related_skin_cluster(selection[-1])
+
+ if selected_skin_cluster is not None:
+ layers_available = api.get_layers_enabled(selected_skin_cluster)
+ else:
+ layers_available = False
+
+ if state.selectedSkinCluster == selected_skin_cluster and state.layersAvailable == layers_available:
+ return False
+
+ state.selection = selection
+ state.set_skin_cluster(selected_skin_cluster)
+ state.skin_cluster_dq_channel_used = (
+ False if selected_skin_cluster is None else cmds.getAttr(selected_skin_cluster + ".skinningMethod") == 2
+ )
+ state.layersAvailable = layers_available
+ state.all_layers = [] # reset when target has actually changed
+ log.info("target changed, layers available: %s", state.layersAvailable)
+
+ return True
+
+ self.targetChanged = event = ConditionalEmit("targetChanged", check_target_changed)
+
+ for source in [self.mayaDeleteAll, self.undoRedoExecuted, self.nodeSelectionChanged]:
+ source.addHandler(event.emitIfChanged)
+
+ def check_layers_list_changed():
+ state.all_layers = [] if not state.layersAvailable else api.Layers(state.selectedSkinCluster).list()
+ return True
+
+ self.layerListChanged = ConditionalEmit("layerListChanged", check_layers_list_changed)
+ signal.on(self.targetChanged, self.undoRedoExecuted)(self.layerListChanged.emitIfChanged)
+
+ def check_current_layer_changed():
+ # current layer changed if current mesh changed,
+ # or id within the mesh changed
+ current_layer = None
+ if state.selectedSkinCluster is not None and state.layersAvailable:
+ current_layer = api.Layers(state.selectedSkinCluster).current_layer()
+
+ if state.selectedSkinCluster == state.currentLayer.selectedSkinCluster and state.currentLayer.layer == current_layer:
+ return False
+
+ state.currentLayer.selectedSkinCluster = state.selectedSkinCluster
+ state.currentLayer.layer = current_layer
+ return True
+
+ self.currentLayerChanged = event = ConditionalEmit("currentLayerChanged", check_current_layer_changed)
+ self.targetChanged.addHandler(event.emitIfChanged)
+ self.undoRedoExecuted.addHandler(event.emitIfChanged)
+
+ def check_current_paint_target_changed():
+ skin_cluster = state.selectedSkinCluster
+ new_layer = state.currentLayer.layer
+ new_targets = None
+ if new_layer is not None:
+ new_targets = new_layer.paint_targets
+
+ log.info("[%s] checking current influence changed to %s %r", skin_cluster, new_layer, new_targets)
+ if (
+ skin_cluster == state.currentInfluence.skinCluster
+ and new_layer == state.currentInfluence.layer
+ and new_targets == state.currentInfluence.targets
+ ):
+ return False
+
+ log.info("[%s] current influence changed to %s %r", skin_cluster, new_layer, new_targets)
+
+ state.currentInfluence.skinCluster = skin_cluster
+ state.currentInfluence.layer = new_layer
+ state.currentInfluence.targets = new_targets
+ return True
+
+ self.currentInfluenceChanged = event = ConditionalEmit("currentInfluenceChanged", check_current_paint_target_changed)
+ self.currentLayerChanged.addHandler(event.emitIfChanged)
+
+ self.influencesListUpdated = Signal("influencesListUpdated")
+
+ # now get initial state
+ self.targetChanged.emitIfChanged()
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/eventtypes.py b/2023/scripts/rigging_tools/ngskintools2/api/eventtypes.py
new file mode 100644
index 0000000..09ce2c1
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/eventtypes.py
@@ -0,0 +1,3 @@
+from ngSkinTools2.signal import Event
+
+tool_settings_changed = Event('tool_settings_changed')
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/feedback.py b/2023/scripts/rigging_tools/ngskintools2/api/feedback.py
new file mode 100644
index 0000000..5b32c14
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/feedback.py
@@ -0,0 +1,11 @@
+def display_error(message):
+ from ngSkinTools2 import BATCH_MODE
+
+ if BATCH_MODE:
+ import sys
+
+ sys.stdout.write(message + "\n")
+ else:
+ from ngSkinTools2.ui import dialogs
+
+ dialogs.displayError(message)
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/http_client.py b/2023/scripts/rigging_tools/ngskintools2/api/http_client.py
new file mode 100644
index 0000000..cb7237d
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/http_client.py
@@ -0,0 +1,46 @@
+import json
+import threading
+
+import maya.utils
+
+from .python_compatibility import PY2
+
+# HTTP library might not be available in batch mode
+available = True
+
+try:
+ # different ways to import urlopen
+ if PY2:
+ from urllib import urlencode
+
+ # noinspection PyUnresolvedReferences
+ from urllib2 import HTTPError, Request, urlopen
+ else:
+ from urllib.error import HTTPError
+ from urllib.parse import urlencode
+ from urllib.request import Request, urlopen
+
+ _ = urlencode
+ _ = urlopen
+ _ = Request
+ _ = HTTPError
+except:
+ available = False
+
+
+def encode_url(base_url, args):
+ return base_url + "?" + urlencode(args)
+
+
+def get_async(url, success_callback, failure_callback):
+ def runnerFunc():
+ defer_func = maya.utils.executeDeferred
+ try:
+ result = urlopen(url).read()
+ defer_func(success_callback, json.loads(result))
+ except Exception as err:
+ defer_func(failure_callback, str(err))
+
+ t = threading.Thread(target=runnerFunc)
+ t.start()
+ return t
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/import_export.py b/2023/scripts/rigging_tools/ngskintools2/api/import_export.py
new file mode 100644
index 0000000..8e36320
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/import_export.py
@@ -0,0 +1,110 @@
+from os import unlink
+
+from ngSkinTools2.api import plugin
+
+from . import transfer
+from .influenceMapping import InfluenceMappingConfig
+
+
+# noinspection PyClassHasNoInit
+class FileFormat:
+ JSON = "json"
+ CompressedJSON = "compressed json"
+
+
+# noinspection PyShadowingBuiltins
+def import_json(
+ target,
+ file,
+ vertex_transfer_mode=transfer.VertexTransferMode.closestPoint,
+ influences_mapping_config=InfluenceMappingConfig.transfer_defaults(),
+ format=FileFormat.JSON,
+):
+ """
+ Transfer layers from file into provided target mesh. Existing layers, if any, will be preserved
+
+ :param str target: destination mesh or skin cluster node name
+ :param str file: file path to load json from
+ :param vertex_transfer_mode: vertex mapping mode when matching imported file's vertices to the target mesh
+ :param InfluenceMappingConfig influences_mapping_config:
+ :param str format: expected file format, one of `FileFormat` values
+ """
+
+ importer = transfer.LayersTransfer()
+ importer.vertex_transfer_mode = vertex_transfer_mode
+ importer.influences_mapping.config = influences_mapping_config
+ importer.load_source_from_file(file, format=format)
+ importer.target = target
+ importer.execute()
+
+
+# noinspection PyShadowingBuiltins
+def export_json(target, file, format=FileFormat.JSON):
+ """
+ Save skinning layers to file in json format, to be later used in `import_json`
+
+ :param str target: source mesh or skin cluster node name
+ :param str file: file path to save json to
+ :param str format: exported file format, one of `FileFormat` values
+ """
+
+ with FileFormatWrapper(file, format=format, read_mode=False) as f:
+ plugin.ngst2tools(
+ tool="exportJsonFile",
+ target=target,
+ file=f.plain_file,
+ )
+
+
+def compress_gzip(source, dest):
+ import gzip
+ import shutil
+
+ with open(source, 'rb') as f_in, gzip.open(dest, 'wb') as f_out:
+ shutil.copyfileobj(f_in, f_out)
+
+
+def decompress_gzip(source, dest):
+ import gzip
+ import shutil
+
+ with gzip.open(source, 'rb') as f_in, open(dest, 'wb') as f_out:
+ shutil.copyfileobj(f_in, f_out)
+
+
+class FileFormatWrapper:
+ def __init__(self, target_file, format, read_mode=False):
+ self.target_file = target_file
+ self.format = format
+ self.plain_file = target_file
+ if self.using_temp_file():
+ self.plain_file = target_file + "_temp"
+ self.read_mode = read_mode
+
+ def using_temp_file(self):
+ return self.format != FileFormat.JSON
+
+ def __compress__(self):
+ if self.format == FileFormat.CompressedJSON:
+ compress_gzip(self.plain_file, self.target_file)
+
+ def __decompress__(self):
+ if self.format == FileFormat.CompressedJSON:
+ decompress_gzip(self.target_file, self.plain_file)
+
+ def __enter__(self):
+ if not self.using_temp_file():
+ return self
+ if self.read_mode:
+ self.__decompress__()
+ return self
+
+ def __exit__(self, _, value, traceback):
+ if not self.using_temp_file():
+ return self
+
+ try:
+ if not self.read_mode:
+ self.__compress__()
+ finally:
+ unlink(self.plain_file)
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/import_v1.py b/2023/scripts/rigging_tools/ngskintools2/api/import_v1.py
new file mode 100644
index 0000000..1082bcc
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/import_v1.py
@@ -0,0 +1,103 @@
+# for same mesh, convert from v1 layers to v2
+from maya import cmds, mel
+
+from ngSkinTools2.api.log import getLogger
+from ngSkinTools2.decorators import undoable
+
+logger = getLogger("import v1")
+
+__has_v1 = None
+
+
+def has_v1():
+ global __has_v1
+ if __has_v1 is not None:
+ return __has_v1
+
+ __has_v1 = False
+ try:
+ cmds.loadPlugin('ngSkinTools')
+ __has_v1 = True
+ except:
+ pass
+
+
+def can_import(target):
+ if not has_v1():
+ return False
+ try:
+ result = cmds.ngSkinLayer(target, q=True, lda=True)
+ return result == 1
+ except Exception as err:
+ logger.error(err)
+ return False
+
+
+def cleanup(selection):
+ """
+ Delete V1 data from provided list of nodes. Must be a v1 compatible target
+
+
+ :type selection: list[string]
+ """
+ for s in selection:
+ hist = cmds.listHistory(s) or []
+ skinClusters = [i for i in hist if cmds.nodeType(i) in ('skinCluster')]
+ cmds.delete(
+ [
+ i
+ for skinCluster in skinClusters
+ for i in cmds.listHistory(skinCluster, future=True, levels=1)
+ if cmds.nodeType(i) in ('ngSkinLayerDisplay', 'ngSkinLayerData')
+ ]
+ )
+
+
+@undoable
+def import_layers(target):
+ if not has_v1():
+ return False
+
+ import ngSkinTools2.api as ngst_api
+
+ layers = ngst_api.init_layers(target)
+
+ layerList = cmds.ngSkinLayer(target, q=True, listLayers=True)
+ layerList = [layerList[i : i + 3] for i in range(0, len(layerList), 3)]
+
+ layerIdMap = {0: None}
+
+ def get_layer_influences(layerId):
+ influences = mel.eval("ngSkinLayer -id {0} -q -listLayerInfluences -activeInfluences {1}".format(layerId, target)) or []
+ return zip(influences[0::2], map(int, influences[1::2]))
+
+ def get_layer_weights(layerId, infl):
+ return mel.eval("ngSkinLayer -id {0:d} -paintTarget {1} -q -w {2:s}".format(layerId, infl, target))
+
+ def copy_layer(oldLayerId, newLayer):
+ """
+
+ :type oldLayerId: int
+ :type newLayer: ngSkinTools2.api.layers.Layer
+ """
+
+ newLayer.opacity = mel.eval("ngSkinLayer -id {0:d} -q -opacity {1:s}".format(oldLayerId, target))
+ newLayer.enabled = mel.eval("ngSkinLayer -id {0:d} -q -enabled {1:s}".format(oldLayerId, target))
+
+ newLayer.set_weights(ngst_api.NamedPaintTarget.MASK, get_layer_weights(oldLayerId, "mask"))
+ newLayer.set_weights(ngst_api.NamedPaintTarget.DUAL_QUATERNION, get_layer_weights(oldLayerId, "dq"))
+
+ for inflPath, inflId in get_layer_influences(oldLayerId):
+ logger.info("importing influence %s for layer %s", inflPath, oldLayerId)
+ weights = get_layer_weights(oldLayerId, inflId)
+ newLayer.set_weights(inflId, weights)
+
+ with ngst_api.suspend_updates(target):
+ for layerId, layerName, layerParent in layerList:
+ layerId = int(layerId)
+ layerParent = int(layerParent)
+ newLayer = layers.add(name=layerName, force_empty=True, parent=layerIdMap[layerParent])
+ newLayer.index = 0
+ layerIdMap[layerId] = newLayer.id
+
+ copy_layer(layerId, newLayer)
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/influenceMapping.py b/2023/scripts/rigging_tools/ngskintools2/api/influenceMapping.py
new file mode 100644
index 0000000..40d1cb4
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/influenceMapping.py
@@ -0,0 +1,545 @@
+"""
+Influence mapping process creates a "source->destination" list for two influence lists,
+describing how based on influence metadata (name, position) and mapping requirements
+(mirror mode, left/right side name prefixes, etc) a mapping is created,
+where "source->destination" in, say, weight transfer/mirror situation, describes that weights
+currently associated with source influence, should be transfered to destination influence.
+
+for mirror mode, same influence can map to itself, which would generally mean "copy influence weights
+on one side to be the same on the other side".
+
+mapping is returned as "logical index"->"logical index" map.
+
+For usage details, see unit test examples.
+"""
+from __future__ import division
+
+import itertools
+import json
+import re
+
+from ngSkinTools2.api.log import getLogger
+from ngSkinTools2.api.python_compatibility import Object, is_string
+
+log = getLogger("influenceMapping")
+
+
+def regexpMatchAny(fragments):
+ return '(' + '|'.join(fragments) + ')'
+
+
+illegalCharactersRegexp = re.compile(r"[^\w_\*]")
+
+
+def validate_glob(glob):
+ match = illegalCharactersRegexp.search(glob)
+ if match is not None:
+ raise Exception("invalid pattern '{}': character {} not allowed".format(glob, match.group(0)))
+
+
+def convertGlobToRegexp(glob):
+ """
+ :type glob: str
+ """
+ glob = illegalCharactersRegexp.sub("", glob)
+ if "*" not in glob: # if no stars added, just add them on both sides, e.g. "_L_" is the same as "*_L_*"
+ glob = "*" + glob + "*"
+ return "^" + glob.replace("*", "(.*)") + "$"
+
+
+class InfluenceInfo(Object):
+ """
+ Metadata about an influence in a skin cluster
+ """
+
+ SIDE_LEFT = "left"
+ SIDE_RIGHT = "right"
+ SIDE_CENTER = "center"
+ SIDE_MAP = {
+ 0: SIDE_CENTER,
+ 1: SIDE_LEFT,
+ 2: SIDE_RIGHT,
+ }
+
+ oppositeSides = {SIDE_LEFT: SIDE_RIGHT, SIDE_RIGHT: SIDE_LEFT}
+
+ def __init__(self, pivot=None, path=None, name=None, logicalIndex=None, labelSide=None, labelText=None):
+ self.pivot = pivot #: influence pivot in world-space coordinates
+ self.path = path #: influence node path
+ self.name = name #: influence node name (if influence is not a DAG node, like )
+ self.logicalIndex = logicalIndex #: influence logical index in the skin cluster.
+ self.labelSide = labelSide #: joint label "side" attribute
+ self.labelText = labelText #: joint label text
+
+ def path_name(self):
+ """
+ returns path if it's not None, otherwise returns name
+ :return:
+ """
+ if self.path is not None:
+ return self.path
+ if self.name is None:
+ raise Exception("both path and name is empty for InfluenceInfo")
+ return self.name
+
+ def __repr__(self):
+ return "[InflInfo %r %r %r]" % (self.logicalIndex, self.path, self.pivot)
+
+ def as_json(self):
+ return {
+ "pivot": self.pivot,
+ "path": self.path,
+ "name": self.name,
+ "logicalIndex": self.logicalIndex,
+ "labelSide": self.labelSide,
+ "labelText": self.labelText,
+ }
+
+ def from_json(self, json):
+ self.pivot = json["pivot"]
+ self.path = json.get("path", "")
+ self.name = json.get("name", "")
+ self.logicalIndex = json["logicalIndex"]
+ self.labelSide = json["labelSide"]
+ self.labelText = json["labelText"]
+ return self
+
+
+def calcShortestUniqueName(influences):
+ """
+ calculates "uniquePath" for each influence - in a similar manner as Maya does, only in the context of single
+ skincluster instead of the whole scene.
+ :type influences: list[InfluenceInfo]
+ """
+
+ def commonOffset(original, sibling):
+ i = 0
+ for o, s in zip(original, sibling):
+ if o != s:
+ break
+ i += 1
+
+ # extend to full name
+ while i < len(original) and original[i] != '|':
+ i += 1
+
+ return i
+
+ for infl in influences:
+ if infl.path is None:
+ infl.shortestPath = infl.name
+
+ reversedPaths = [{"path": infl.path[::-1], "infl": infl} for infl in influences if infl.path]
+
+ # sort by line ending
+ reversedPaths = sorted(reversedPaths, key=lambda item: item["path"])
+
+ # compare path to siblings, find a shortest subpath that is different from nearest similar names
+ for prev, curr, next in zip([None] + reversedPaths[:-1], reversedPaths, reversedPaths[1:] + [None]):
+ minLength = curr['path'].find("|")
+ if minLength < 0:
+ minLength = len(curr['path'])
+
+ prevOffset = minLength if prev is None else commonOffset(curr['path'], prev['path'])
+ nextOffset = minLength if next is None else commonOffset(curr['path'], next['path'])
+
+ curr['infl'].shortestPath = curr['path'][: max(prevOffset, nextOffset)][::-1]
+
+
+def nameMatches(globs, influences, destination_influences=None, mirror_mode=False):
+ """
+ for each name pair, calculates a match score, and keeps matches that have highest score.
+
+ score calculation rules:
+ * each name is broken down into sections, e.g. |root|L_shoulder|L_elbow -> root, L_shoulder, L_elbow
+ * for each section, find glob match, e.g. L_elbow becomes : {withoutGlob: elbow, matchedRule=L_*, oppositeRule=R_*}
+ * two names are matched from the end, section by section:
+ * it is assumed that a section matches if "withoutGlob" part is identical, and section1.matchedRule==section2.oppositeRule
+
+
+ matching of the name happens by finding highest score
+
+ returns map of source->destination matches
+ :type globs: list[(string, string)]
+ :type influences: list[InfluenceInfo]
+ """
+
+ if destination_influences is None:
+ destination_influences = influences
+
+ # 1 each path element is calculated as glob value
+
+ globRegexps = [[re.compile(convertGlobToRegexp(i)) for i in g] for g in globs]
+
+ # join with reversed logic
+ globRegexps = globRegexps + [tuple(reversed(ge)) for ge in globRegexps]
+
+ class GlobInfo(Object):
+ def __init__(self):
+ self.withoutGlob = ""
+ self.matchedRule = None
+ self.oppositeRule = None
+
+ def convertPathElementToGlobInfo(pathElement):
+ result = GlobInfo()
+ result.withoutGlob = pathElement
+
+ for expr, opposite in globRegexps:
+ match = expr.match(pathElement)
+ if match is not None:
+ result.matchedRule = expr
+ result.oppositeRule = opposite
+ result.withoutGlob = "".join(match.groups())
+ break
+
+ return result
+
+ def calcMatchScore(info1, info2):
+ """
+
+ :type info1: list[GlobInfo]
+ :type info2: list[GlobInfo]
+ """
+
+ # optimization - if there's no chance these two paths match,
+ # cut away loop logic
+ if info1[0].withoutGlob != info2[0].withoutGlob:
+ return 0
+
+ score = 0
+
+ rules_matched = False
+
+ for e1, e2 in zip(info1, info2):
+ if e1.withoutGlob != e2.withoutGlob or e1.matchedRule != e2.oppositeRule:
+ break
+
+ if e1.matchedRule is not None:
+ score += 10
+ rules_matched = True
+
+ score += 1
+
+ # in mirror mode, it's important that at least rule is matched (e.g. L->R or similar)
+ if mirror_mode and not rules_matched:
+ score = 0
+
+ return score
+
+ class MatchData(Object):
+ path_split = re.compile("[\\|\\:]")
+
+ def __init__(self, infl):
+ """
+ :type infl: InfluenceInfo
+ """
+ reversedPath = list(reversed(self.path_split.split(infl.path))) if infl.path else [infl.name]
+ self.infl = infl
+ self.score = 0
+ self.match = None
+ self.globInfo = [convertPathElementToGlobInfo(e) for e in reversedPath]
+
+ destination_matches = [MatchData(infl) for infl in destination_influences]
+ if destination_influences == influences:
+ source_data = destination_matches
+ else:
+ source_data = [MatchData(infl) for infl in influences]
+
+ # encapsulating for profiler
+ def findBestMatches():
+ for source in source_data:
+ for destination in destination_matches:
+ if source == destination:
+ continue
+
+ score = calcMatchScore(source.globInfo, destination.globInfo)
+
+ if (not mirror_mode or score > source.score) and score > destination.score:
+ destination.match = source
+ destination.score = score
+ if mirror_mode:
+ source.match = destination
+ source.score = score
+
+ findBestMatches()
+
+ return {md.match.infl: md.infl for md in destination_matches if md.match is not None}
+
+
+def exactNameMatches(influences, destination_influences=None):
+ """
+ match influences by exact name
+ :type influences: list[InfluenceInfo]
+ """
+
+ pass
+
+
+def labelMatches(source_influences, destination_influences, mirror_mode=False):
+ """
+ :type source_influences: list[InfluenceInfo]
+ """
+
+ def infl_key(i):
+ if i.labelText is None:
+ return ("", "")
+
+ return (i.labelText, i.labelSide)
+
+ def group_by_label_and_side(infl_list):
+ return {k: list(v) for k, v in itertools.groupby(list(sorted(infl_list, key=infl_key)), key=infl_key)}
+
+ def as_unique_entries(l):
+ return {k: v[0] for k, v in l.items() if len(v) == 1}
+
+ result = {}
+
+ # group by labelText+labelSide keys
+ # it is essential that only unique keys are used; skip repeats of text+side on either list, as they are ambiguous
+ grouped_sources = group_by_label_and_side(source_influences)
+ unique_sources = as_unique_entries(grouped_sources)
+ unique_destinations = unique_sources if mirror_mode else as_unique_entries(group_by_label_and_side(destination_influences))
+
+ # "center" treatment in mirror mode: sometimes users might not set left/right sides, and "center" is actually just an untouched default;
+ # in that case, just favour other influences if there are multiple "center" with the same label
+ if mirror_mode:
+ for (label, side), src in grouped_sources.items():
+ if label == "" or side != InfluenceInfo.SIDE_CENTER:
+ continue
+
+ # only the cases of len==1 and len==2 are supported
+ if len(src) == 1:
+ result[src[0]] = src[0]
+ else:
+ result[src[0]] = src[1]
+ result[src[1]] = src[0]
+
+ # find matching label+side pairs for all destinations; flip side for mirror mode
+ for (label, side), src in unique_sources.items():
+ if label == "":
+ continue
+ if mirror_mode:
+ if side == InfluenceInfo.SIDE_CENTER:
+ continue
+ side = InfluenceInfo.oppositeSides[side]
+
+ dest = unique_destinations.get((label, side), None)
+ if dest is not None:
+ result[src] = dest
+
+ return result
+
+
+def distanceMatches(source_influences, destination_influences, threshold, mirror_axis):
+ """
+ :type source_influences: list[InfluenceInfo]
+ :type destination_influences: list[InfluenceInfo]
+ :type threshold: float
+ :type mirror_axis: union(int, None)
+ """
+
+ def distance_squared(p1, p2):
+ return (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2 + (p1[2] - p2[2]) ** 2
+
+ threshold_squared = threshold * threshold
+
+ mirror_mode = mirror_axis is not None
+
+ result = {}
+ for source in source_influences:
+ # if we're in mirror mode and near mirror axis, match self instead of other influence
+ if mirror_mode and abs(source.pivot[mirror_axis]) < (threshold / 2.0):
+ result[source] = source
+ continue
+
+ source_pivot = list(source.pivot[:])
+ if mirror_mode:
+ source_pivot[mirror_axis] = -source_pivot[mirror_axis]
+
+ best_distance = None
+ for destination in destination_influences:
+ d = distance_squared(source_pivot, destination.pivot)
+ if threshold_squared < d:
+ continue
+
+ if best_distance is None or d < best_distance:
+ best_distance = d
+ result[source] = destination
+ if mirror_mode:
+ result[destination] = source
+
+ return result
+
+
+def dg_matches(source_influences, destination_influences, link_resolver):
+ """
+ :type source_influences: list[InfluenceInfo]
+ :type destination_influences: list[InfluenceInfo]
+ :type link_resolver:
+ """
+
+ result = {}
+
+ dest_by_path = {i.path: i for i in destination_influences}
+ for i in source_influences:
+ dest = link_resolver(i.path)
+ dest = None if dest is None else dest_by_path.get(dest, None)
+ if dest is not None:
+ result[i] = dest
+
+ return result
+
+
+class InfluenceMappingConfig(Object):
+ """
+ This class represents a configuration for how influences are matched for weights mirroring or transfering
+ between meshes.
+ """
+
+ globs = [
+ ("L_*", "R_*"),
+ ("l_*", "r_*"),
+ ("lf_*", "rt_*"),
+ ("*_lf", "*_rt"),
+ ] #: For mirrored influences matching, this specifies the globs that will be used for name substitution
+
+ use_dg_link_matching = True #: turn on to use dependency graph links
+ use_name_matching = True #: should matching by name be used?
+ use_label_matching = True #: should matching by label be used?
+ use_distance_matching = True #: should matching by influence X,Y,Z coordinates be used?
+ distance_threshold = 0.001 #: When matching by distance, if distance between two positions is greater than this threshold, that pair of influences is not considered as potential match.
+
+ __mirror_axis = None
+ dg_destination_attribute = "oppositeInfluence" #: default attribute name
+
+ @property
+ def mirror_axis(self):
+ """
+ int: Mirror axis (0 - X, 1 - Y, 2 - Z)
+
+ When mirror axis is not None, matching is done in "mirror" mode:
+
+ * left/right side .globs are used;
+ * matching by position uses mirrorAxis to invert positions first;
+
+ """
+ return self.__mirror_axis
+
+ @mirror_axis.setter
+ def mirror_axis(self, axis):
+ if is_string(axis):
+ self.__mirror_axis = ['x', 'y', 'z'].index(axis)
+ return
+
+ if axis is not None and not isinstance(axis, int):
+ raise Exception("invalid axis type, need int")
+
+ self.__mirror_axis = axis
+
+ @classmethod
+ def transfer_defaults(cls):
+ """
+ Builds a mapping configuration that is suitable as default for transferring between meshes (or importing)
+
+ Returns:
+ InfluenceMappingConfig: default transfer configuration
+ """
+ result = InfluenceMappingConfig()
+ result.mirror_axis = None
+ result.globs = []
+ return result
+
+ def as_json(self):
+ """
+ serializes config as JSON string
+ """
+ return json.dumps(self.__dict__)
+
+ def load_json(self, json_string):
+ """
+ loads configuration from previously saved `as_json` output
+ """
+ try:
+ self.__dict__ = json.loads(json_string)
+ except:
+ pass
+
+
+def default_dg_resolver(dg_attribute):
+ from maya import cmds
+
+ def resolver(input_path):
+ try:
+ sources = cmds.listConnections(input_path + "." + dg_attribute, source=True)
+ if sources:
+ return cmds.ls(sources[0], long=True)[0]
+ except:
+ pass
+ return None
+
+ return resolver
+
+
+class InfluenceMapping(Object):
+ """
+ this class serves as a hub to calculate influences mapping, given a mapping config and source/destination influences
+ """
+
+ def __init__(self):
+ self.config = InfluenceMappingConfig() # type:InfluenceMappingConfig
+ "assigned config"
+
+ self.influences = [] # type: list[InfluenceInfo]
+ "Source influences list. Can be assigned to result of :py:meth:`Layers.list_influences`"
+
+ self.destinationInfluences = None
+ self.calculatedMapping = None
+ self.dg_resolver = lambda: default_dg_resolver(self.config.dg_destination_attribute)
+
+ def calculate(self):
+ mirror_mode = self.config.mirror_axis is not None
+ log.info("calculate influence mapping, mirror mode: %s", mirror_mode)
+ if self.destinationInfluences is None:
+ self.destinationInfluences = self.influences
+
+ results = []
+
+ if mirror_mode:
+ results.append(({infl: infl for infl in self.destinationInfluences}, "fallback to self"))
+
+ if self.config.use_distance_matching:
+ matches = distanceMatches(
+ self.influences, self.destinationInfluences, self.config.distance_threshold, mirror_axis=self.config.mirror_axis
+ )
+ results.append((matches, "distance"))
+
+ if self.config.use_name_matching:
+ results.append((nameMatches(self.config.globs, self.influences, self.destinationInfluences, mirror_mode=mirror_mode), "name"))
+
+ if self.config.use_label_matching:
+ results.append((labelMatches(self.influences, self.destinationInfluences, mirror_mode=mirror_mode), "label"))
+
+ if self.config.use_dg_link_matching:
+ matches = dg_matches(self.influences, self.destinationInfluences, self.dg_resolver())
+ results.append((matches, "DG link"))
+
+ result = {}
+ for mapping, matchedRule in results:
+ for k, v in mapping.items():
+ result[k] = {
+ "matchedRule": matchedRule,
+ "infl": v,
+ }
+
+ self.calculatedMapping = result
+
+ return result
+
+ @staticmethod
+ def asIntIntMapping(mapping):
+ """
+
+
+ :meta private:
+ """
+ return {k.logicalIndex: v['infl'].logicalIndex for k, v in mapping.items()}
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/influence_names.py b/2023/scripts/rigging_tools/ngskintools2/api/influence_names.py
new file mode 100644
index 0000000..6a2b404
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/influence_names.py
@@ -0,0 +1,117 @@
+import re
+
+from ngSkinTools2.api.python_compatibility import Object
+from ngSkinTools2.signal import Signal
+
+
+class InfluenceNameFilter(Object):
+ """
+ simple helper object to match against filter strings;
+ accepts filter as a string, breaks it down into lowercase tokens, and
+ matches values in non-case sensitive way
+
+ e.g. filter "leg arm spines" matches "leg", "left_leg",
+ "R_arm", but does not match "spine"
+
+ in a special case of empty filter, returns true for isMatch
+ """
+
+ def __init__(self):
+ self.matchers = []
+ self.changed = Signal("filter changed")
+ self.currentFilterString = ""
+
+ def set_filter_string(self, filter_string):
+ if self.currentFilterString == filter_string:
+ # avoid emitting change events if there's no change
+ return
+ self.currentFilterString = filter_string
+
+ def create_pattern(expression):
+ expression = "".join([char for char in expression if char.lower() in "abcdefghijklmnopqrstuvwxyz0123456789_*"])
+ expression = expression.replace("*", ".*")
+ return re.compile(expression, re.I)
+
+ self.matchers = [create_pattern(i.strip()) for i in filter_string.split() if i.strip() != '']
+ self.changed.emit()
+ return self
+
+ def short_name(self, name):
+ try:
+ return name[name.rindex("|") + 1 :]
+ except Exception as err:
+ return name
+
+ def is_match(self, value):
+ if len(self.matchers) == 0:
+ return True
+
+ value = self.short_name(str(value).lower())
+ for pattern in self.matchers:
+ if pattern.search(value) is not None:
+ return True
+
+ return False
+
+
+def short_name(name, min_len=0):
+ """
+
+ :param str name:
+ :param int min_len:
+ """
+ idx = name.rfind("|", None, len(name) - min_len - 1)
+ if idx < 0:
+ return name
+ return name[idx + 1 :]
+
+
+class IndexedName(object):
+ def __init__(self, path):
+ self.path = path
+ self.name = short_name(path)
+
+ def extend_short_name(self):
+ self.name = short_name(self.path, len(self.name))
+
+
+def extend_unique_names(items, from_item):
+ """
+
+ :param int from_item:
+ :param list[IndexedName] items:
+ """
+
+ if from_item >= len(items) - 1:
+ return
+
+ curr = items[from_item]
+ needs_more_iterations = True
+ while needs_more_iterations:
+ needs_more_iterations = False
+ curr_name = curr.name
+
+ for item in items[from_item + 1 :]:
+ if item.name == curr_name:
+ if not needs_more_iterations:
+ curr.extend_short_name()
+ item.extend_short_name()
+ needs_more_iterations = True
+
+
+def unique_names(name_list):
+ """
+ returns a list of shortened names without duplicates. e.g ["|a|b", "|a|b|c", "b|b"] will become ["a|b", "c", "b|b"]
+ :param name_list:
+ :return:
+ """
+
+ # assign index to each name to later restore the original order
+ indexed_names = [IndexedName(i) for i in name_list]
+
+ sorted_by_reveresed_name = sorted(indexed_names, key=lambda x: x.path[::-1])
+
+ for i, _ in enumerate(sorted_by_reveresed_name):
+ extend_unique_names(sorted_by_reveresed_name, i)
+
+ return [i.name for i in indexed_names]
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/internals.py b/2023/scripts/rigging_tools/ngskintools2/api/internals.py
new file mode 100644
index 0000000..61153d5
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/internals.py
@@ -0,0 +1,17 @@
+def make_editable_property(propertyName):
+ return property(lambda self: self.__query__(**{propertyName: True}), lambda self, val: self.__edit__(**{propertyName: val}))
+
+
+def influences_map_to_list(influencesMapping):
+ return ','.join(str(k) + "," + str(v) for (k, v) in list(influencesMapping.items()))
+
+
+def float_list_as_string(floatList):
+ """
+ returns empty string for None and []
+ otherwise, returns a list of floats, comma delimited
+ """
+ if not floatList:
+ return ""
+
+ return ",".join([str(i) for i in floatList])
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/layers.py b/2023/scripts/rigging_tools/ngskintools2/api/layers.py
new file mode 100644
index 0000000..9f4dc4e
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/layers.py
@@ -0,0 +1,416 @@
+import json
+
+from maya import mel
+
+from ngSkinTools2.api import internals, plugin, target_info
+from ngSkinTools2.api.config import Config
+from ngSkinTools2.api.log import getLogger
+from ngSkinTools2.api.python_compatibility import Object, is_string
+from ngSkinTools2.api.suspend_updates import suspend_updates
+from ngSkinTools2.decorators import undoable
+
+logger = getLogger("api/layers")
+
+
+class NamedPaintTarget(Object):
+ MASK = "mask"
+ DUAL_QUATERNION = "dq"
+
+
+class LayerEffects(Object):
+ def __init__(self, layer, state=None):
+ self.__layer = layer # type: Layer
+ if state is not None:
+ self.__set_state__(state)
+
+ def __set_state__(self, state):
+ from ngSkinTools2.api import MirrorOptions
+
+ self.mirror_mask = state.get("mirrorMask", False)
+ self.mirror_weights = state.get("mirrorWeights", False)
+ self.mirror_dq = state.get("mirrorDq", False)
+ self.mirror_direction = state.get("mirrorDirection", MirrorOptions.directionPositiveToNegative)
+
+ def configure_mirror(self, everything=None, mirror_mask=None, mirror_weights=None, mirror_dq=None, mirror_direction=None):
+ """
+ Enable/disable components for mirror effect:
+
+ >>> layer.effects.configure_mirror(mirror_mask=True)
+ >>> layer.effects.configure_mirror(mirror_dq=False)
+ >>> # equivalent of setting all flags to False
+ >>> layer.effects.configure_mirror(everything=False)
+
+ Mirroring direction must be set explicitly.
+
+ >>> from ngSkinTools2.api import MirrorOptions
+ >>> layer.effects.configure_mirror(mirror_mask=True,mirror_direction=MirrorOptions.directionPositiveToNegative)
+
+
+ :arg bool mirror_mask: should mask be mirrored with this effect?
+ :arg bool mirror_weights: should influence weights be mirrored with this effect?
+ :arg bool mirror_dq: should dq weights be mirrored with this effect?
+ :arg int mirror_direction: mirroring direction. Use `MirrorOptions.directionPositiveToNegative`, `MirrorOptions.directionNegativeToPositive`
+ or `MirrorOptions.directionFlip`
+ """
+ if everything is not None:
+ mirror_mask = mirror_dq = mirror_weights = everything
+
+ logger.info(
+ "configure mirror: layer %s mask %r weights %r dq %r direction %r",
+ self.__layer.name,
+ mirror_mask,
+ mirror_weights,
+ mirror_dq,
+ mirror_direction,
+ )
+
+ args = {'mirrorLayerDq': mirror_dq, 'mirrorLayerMask': mirror_mask, 'mirrorLayerWeights': mirror_weights, "mirrorDirection": mirror_direction}
+
+ self.__layer.__edit__(configureMirrorEffect=True, **{k: v for k, v in list(args.items()) if v is not None})
+
+
+def _build_layer_property(name, doc, edit_name=None, default_value=None):
+ if edit_name is None:
+ edit_name = name
+
+ def getter(self):
+ return self.__get_state__(name, default_value=default_value)
+
+ def setter(self, val):
+ if isinstance(val, (list, tuple)):
+ val = ",".join([str(i) for i in val])
+ self.__edit__(**{edit_name: val})
+
+ return property(getter, setter, doc=doc)
+
+
+class Layer(Object):
+ """ """
+
+ name = _build_layer_property('name', "str: Layer name") # type: str
+ enabled = _build_layer_property('enabled', "bool: is layer enabled or disabled") # type: bool
+ opacity = _build_layer_property('opacity', "float: value between 1.0 and 0") # type: float
+ paint_target = _build_layer_property(
+ 'paintTarget', "str or int: currently active paint target for this layer (either an influence or one of named targets)"
+ ) # type: Union(str, int)
+ index = _build_layer_property('index', edit_name='layerIndex', doc="int: layer index in parent's child list; set to reorder") # type: int
+ locked_influences = _build_layer_property(
+ 'lockedInfluences',
+ doc="list[int]: list of locked influence indexes",
+ default_value=[],
+ ) # type: list[int]
+
+ @classmethod
+ def load(cls, mesh, layer_id):
+ if layer_id < 0:
+ raise Exception("invalid layer ID: %s" % layer_id)
+ result = Layer(mesh, layer_id)
+ result.reload()
+ return result
+
+ def __init__(self, mesh, id, state=None):
+ self.mesh = mesh
+ self.id = id
+ self.effects = LayerEffects(self) # type: LayerEffects
+ "configure effects for this layer"
+
+ self.__state = None
+ if state is not None:
+ self.__set_state(state)
+
+ def __get_state__(self, k, default_value=None):
+ return self.__state.get(k, default_value)
+
+ def __query__(self, arg, **kwargs):
+ keys = " ".join(["-{k} {v}".format(k=k, v=v) for k, v in list(kwargs.items())])
+ return mel.eval("ngst2Layers -id {id} {keys} -q -{arg} {mesh}".format(id=self.id, mesh=self.mesh, keys=keys, arg=arg))
+
+ def __edit__(self, **kwargs):
+ self.__set_state(plugin.ngst2Layers(self.mesh, e=True, id=as_layer_id(self), **kwargs))
+
+ def __set_state(self, state):
+ if state is None:
+ # some plugin functions still return empty result after edits - nevermind those
+ return
+ if is_string(state):
+ try:
+ state = json.loads(state)
+ except Exception as err:
+ raise Exception(str(err) + "; input body was: " + repr(state))
+
+ self.__state = state
+
+ # logger.info("setting layer state %r: %r", self.id, state)
+
+ self.parent_id = state['parentId']
+ self.__parent = None
+ self.children_ids = state['children']
+ self.__children = []
+
+ self.effects.__set_state__(state['effects'])
+
+ def reload(self):
+ """
+ Refresh layer data from plugin.
+ """
+ self.__set_state(self.__query__('layerAttributesJson'))
+
+ def __eq__(self, other):
+ if not isinstance(other, Layer):
+ return False
+
+ return self.mesh == other.mesh and self.id == other.id and self.__state == other.__state
+
+ def __repr__(self):
+ return "[Layer #{id} '#{name}']".format(id=self.id, name=self.name)
+
+ @property
+ def paint_targets(self):
+ """
+ list[str or int]: list of paint targets to be set as current for this layer
+ """
+ return self.__get_state__("paintTargets")
+
+ @paint_targets.setter
+ def paint_targets(self, targets):
+ self.__edit__(**{"paintTarget": ",".join([str(target) for target in targets])})
+
+ @property
+ def parent(self):
+ """
+ Layer: layer parent, or None, if layer is at root level.
+ """
+ if self.__parent is None:
+ if self.parent_id is not None:
+ self.__parent = Layer.load(self.mesh, self.parent_id)
+
+ return self.__parent
+
+ @parent.setter
+ def parent(self, parent):
+ if parent is None:
+ parent = 0
+
+ self.__edit__(parent=as_layer_id(parent))
+
+ @property
+ def num_children(self):
+ """
+ int: a bit more lightweight method to count number of child layers than len(children()), as it does not
+ prefetch children data.
+ """
+ return len(self.children_ids)
+
+ @property
+ def children(self):
+ """
+ list[Layer]: lazily load children if needed, and return as Layer objects
+ """
+ if len(self.children_ids) != 0:
+ if len(self.__children) == 0:
+ self.__children = [Layer.load(self.mesh, i) for i in self.children_ids]
+
+ return self.__children
+
+ def set_current(self):
+ """
+
+ Set as "default" layer for other operations.
+
+
+ .. warning::
+ Scheduled for removal. API calls should specify target layer explicitly
+
+
+
+ """
+ plugin.ngst2Layers(self.mesh, currentLayer=self.id)
+
+ def set_weights(self, influence, weights_list, undo_enabled=True):
+ """
+ Modify weights in the layer.
+
+ :arg int/str influence: either index of an influence, or named paint target (one of :py:class:`NamedPaintTarget` values)
+ :arg list[int] weights_list: weights for each vertex (must match number of vertices in skin cluster)
+ :arg bool undo_enabled: set to False if you don't need undo, for slight performance boost
+ """
+ self.__edit__(paintTarget=influence, vertexWeights=internals.float_list_as_string(weights_list), undoEnabled=undo_enabled)
+
+ def get_weights(self, influence):
+ """
+ get influence (or named paint target) weights for all vertices
+ """
+ result = self.__query__('vertexWeights', paintTarget=influence)
+ if result is None:
+ return []
+ return [float(i) for i in result]
+
+ def get_used_influences(self):
+ """
+
+ :rtype: list[int]
+ """
+ result = self.__query__('usedInfluences')
+ return result or []
+
+
+def as_layer_id(layer):
+ """
+ converts given input to layer ID. If input is a Layer object, returns it's ID, otherwise assumes that input is already a layer ID
+
+ Returns:
+ int: layer ID
+ """
+ if isinstance(layer, Layer):
+ return layer.id
+
+ return int(layer)
+
+
+def as_layer_id_list(layers):
+ """
+ maps a given layer list with `as_layer_id`
+
+ Args:
+ layers (list[Any]): objects representing a list of layers
+
+ :rtype: list[int]
+ """
+ return (as_layer_id(i) for i in layers)
+
+
+def generate_layer_name(existing_layers, base_name):
+ """
+ A little utility to generate a unique layer name. For example, if base_name="test", it will try to use values in sequence "test", "test (1)",
+ "test (2)" and will return first value that is not a name for any layer in the given layers list.
+
+ :arg existing_layers Layer: whatever
+ """
+ name = base_name
+ currentLayerNames = [i.name for i in existing_layers]
+ index = 1
+ while name in currentLayerNames:
+ index += 1
+ name = base_name + " ({0})".format(index)
+
+ return name
+
+
+class Layers(Object):
+ """
+ Layers manages skinning layers on provided target (skinCluster or a mesh)
+ """
+
+ prune_weights_filter_threshold = internals.make_editable_property('pruneWeightsFilterThreshold')
+ influence_limit_per_vertex = internals.make_editable_property('influenceLimitPerVertex')
+
+ def __init__(self, target):
+ """
+
+ :param str target: name of skin cluster node or skinned mesh.
+ """
+ if not target:
+ raise Exception("target must be specified")
+
+ self.__target = target
+ self.__cached_data_node = None
+
+ def add(self, name, force_empty=False, parent=None):
+ """
+ creates new layer with given name and returns its ID; when force_empty flag is set to true,
+ layer weights will not be populated from skin cluster.
+ """
+ layer_id = plugin.ngst2Layers(self.mesh, name=name, add=True, forceEmpty=force_empty)
+ result = Layer.load(self.mesh, layer_id)
+ result.parent = parent
+ return result
+
+ def delete(self, layer):
+ plugin.ngst2Layers(self.mesh, removeLayer=True, id=as_layer_id(layer))
+
+ def list(self):
+ """
+
+ returns all layers as Layer objects.
+ :rtype list[Layer]
+ """
+ data = json.loads(plugin.ngst2Layers(self.mesh, q=True, listLayers=True))
+ return [Layer(self.mesh, id=l['id'], state=l) for l in data]
+
+ @undoable
+ def clear(self):
+ """
+ delete all layers
+ """
+ with suspend_updates(self.data_node):
+ for i in self.list():
+ if i.parent_id is None:
+ self.delete(i)
+
+ def list_influences(self):
+ """
+ Wraps :py:meth:`target_info.list_influences`
+ """
+ return target_info.list_influences(self.mesh)
+
+ def current_layer(self):
+ """
+ get current layer that was previously marked as current with :py:meth:`Layer.set_current`.
+
+ .. warning::
+ Scheduled for removal. API calls should specify target layer explicitly
+
+ """
+ layer_id = plugin.ngst2Layers(self.mesh, q=True, currentLayer=True)
+ if layer_id < 0:
+ return None
+ return Layer.load(self.mesh, layer_id)
+
+ def __edit__(self, **kwargs):
+ plugin.ngst2Layers(self.mesh, e=True, **kwargs)
+
+ def __query__(self, **kwargs):
+ return plugin.ngst2Layers(self.mesh, q=True, **kwargs)
+
+ def set_influences_mirror_mapping(self, influencesMapping):
+ plugin.ngst2Layers(self.mesh, configureMirrorMapping=True, influencesMapping=internals.influences_map_to_list(influencesMapping))
+
+ @property
+ def mesh(self):
+ return self.__target
+
+ def is_enabled(self):
+ """
+ returns true if skinning layers are enabled for the given mesh
+ :return:
+ """
+ return get_layers_enabled(self.mesh)
+
+ @property
+ def data_node(self):
+ if not self.__cached_data_node:
+ self.__cached_data_node = target_info.get_related_data_node(self.mesh)
+ return self.__cached_data_node
+
+ @property
+ def config(self):
+ return Config(self.data_node)
+
+
+def init_layers(target):
+ """Attach ngSkinTools data node to given target. Does nothing if layers are already attached.
+
+
+ :arg str target: skin cluster or mesh node to attach layers to
+ :rtype: Layers
+ """
+ plugin.ngst2Layers(target, layerDataAttach=True)
+
+ return Layers(target)
+
+
+def get_layers_enabled(selection):
+ """
+ return true if layers are enabled on this selection
+ """
+ return plugin.ngst2Layers(selection, q=True, lda=True)
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/log.py b/2023/scripts/rigging_tools/ngskintools2/api/log.py
new file mode 100644
index 0000000..c8b147c
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/log.py
@@ -0,0 +1,76 @@
+import logging
+import sys
+
+from ngSkinTools2.api.python_compatibility import Object
+
+
+class DummyLogger(Object):
+ def __getattr__(self, name):
+ return self.doNothing
+
+ def doNothing(self, *args, **kwargs):
+ pass
+
+ def isEnabledFor(self, *args):
+ return False
+
+ def getLogger(self, name):
+ return self
+
+
+class LogLineCountFilter(logging.Filter):
+ def __init__(self):
+ self.count = 1
+
+ def filter(self, record):
+ record.count = self.count
+ self.count = (self.count + 1) % 1000
+ return True
+
+
+class SimpleLoggerFactory(Object):
+ ROOT_LOGGER_NAME = "ngSkinTools2"
+
+ def __init__(self, level=logging.DEBUG):
+ self.level = level
+ self.log = self.configureRootLogger()
+
+ def configureRootLogger(self):
+ logger = logging.getLogger(self.ROOT_LOGGER_NAME)
+ logger.setLevel(self.level)
+ logger.addFilter(LogLineCountFilter())
+ # logger.handlers = []
+
+ formatter = logging.Formatter("%(count)3d: [UI %(levelname)s %(filename)s:%(lineno)d] %(message)s")
+ formatter.datefmt = '%H:%M:%S'
+
+ for i in logger.handlers[:]:
+ logger.removeHandler(i)
+
+ ch = logging.StreamHandler(sys.__stdout__)
+ ch.setLevel(self.level)
+ ch.setFormatter(formatter)
+ logger.addHandler(ch)
+ logger.propagate = False
+
+ return logger
+
+ def getLogger(self, name):
+ return self.log
+
+ self.log.debug("creating logger '%s'" % name)
+
+ result = logging.getLogger(self.ROOT_LOGGER_NAME + "." + name)
+ result.setLevel(self.level)
+
+ result.info("alive check")
+ return result
+
+
+import ngSkinTools2
+
+currentLoggerFactory = DummyLogger() if not ngSkinTools2.DEBUG_MODE else SimpleLoggerFactory(level=logging.DEBUG)
+
+
+def getLogger(name):
+ return currentLoggerFactory.getLogger(name)
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/mirror.py b/2023/scripts/rigging_tools/ngskintools2/api/mirror.py
new file mode 100644
index 0000000..e9f0e37
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/mirror.py
@@ -0,0 +1,184 @@
+import itertools
+
+from maya import cmds
+
+from ngSkinTools2.api import influenceMapping, internals, plugin, target_info
+from ngSkinTools2.api.cmd_wrappers import get_source_node
+from ngSkinTools2.api.layers import Layers
+from ngSkinTools2.api.log import getLogger
+from ngSkinTools2.api.python_compatibility import Object
+
+log = getLogger("mirror")
+
+
+class Mirror(Object):
+ """
+ query and configure mirror options for provided target
+ """
+
+ axis = internals.make_editable_property('mirrorAxis')
+ seam_width = internals.make_editable_property('mirrorWidth')
+ vertex_transfer_mode = internals.make_editable_property('vertexTransferMode')
+
+ def __init__(self, target):
+ """
+ :type target: skin target (skinCluster or mesh)
+ """
+ self.target = target
+ self.__skin_cluster__ = None
+ self.__data_node__ = None
+
+ # noinspection PyMethodMayBeStatic
+ def __query__(self, **kwargs):
+ return plugin.ngst2Layers(self.target, q=True, **kwargs)
+
+ # noinspection PyMethodMayBeStatic
+ def __edit__(self, **kwargs):
+ plugin.ngst2Layers(self.target, configureMirrorMapping=True, **kwargs)
+ self.recalculate_influences_mapping()
+
+ def __mapper_config_attr(self):
+ return self.__get_data_node__() + ".influenceMappingOptions"
+
+ def build_influences_mapper(self, defaults=None):
+ mapper = influenceMapping.InfluenceMapping()
+ layers = Layers(self.target)
+ mapper.influences = layers.list_influences()
+
+ mapper.config.load_json(cmds.getAttr(self.__mapper_config_attr()))
+ mapper.config.mirror_axis = self.axis
+
+ return mapper
+
+ def save_influences_mapper(self, mapper):
+ """
+ :type mapper: influenceMapping.InfluenceMapping
+ """
+ self.set_mirror_config(mapper.config.as_json())
+
+ def set_mirror_config(self, config_as_json):
+ cmds.setAttr(self.__mapper_config_attr(), config_as_json, type='string')
+
+ def set_influences_mapping(self, mapping):
+ """
+ :type mapping: map[int] -> int
+ """
+ log.info("mapping updated: %r", mapping)
+
+ mapping_as_string = ','.join(str(k) + "," + str(v) for (k, v) in list(mapping.items()))
+ plugin.ngst2Layers(self.target, configureMirrorMapping=True, influencesMapping=mapping_as_string)
+
+ def recalculate_influences_mapping(self):
+ """
+ loads current influence mapping settings, and update influences mapping with these values
+ """
+ m = self.build_influences_mapper().calculate()
+ self.set_influences_mapping(influenceMapping.InfluenceMapping.asIntIntMapping(m))
+
+ def mirror(self, options):
+ """
+ :type options: MirrorOptions
+ """
+ plugin.ngst2Layers(
+ self.target,
+ mirrorLayerWeights=options.mirrorWeights,
+ mirrorLayerMask=options.mirrorMask,
+ mirrorLayerDq=options.mirrorDq,
+ mirrorDirection=options.direction,
+ )
+
+ def set_reference_mesh(self, mesh_shape):
+ dest = self.__get_data_node__() + ".mirrorMesh"
+ if mesh_shape:
+ cmds.connectAttr(mesh_shape + ".outMesh", dest)
+ else:
+ for i in cmds.listConnections(dest, source=True, plugs=True):
+ cmds.disconnectAttr(i, dest)
+
+ def get_reference_mesh(self):
+ return get_source_node(self.__get_data_node__() + '.mirrorMesh')
+
+ def __get_skin_cluster__(self):
+ if self.__skin_cluster__ is None:
+ self.__skin_cluster__ = target_info.get_related_skin_cluster(self.target)
+ return self.__skin_cluster__
+
+ def __get_data_node__(self):
+ if self.__data_node__ is None:
+ self.__data_node__ = target_info.get_related_data_node(self.target)
+ return self.__data_node__
+
+ # noinspection PyStatementEffect
+ def build_reference_mesh(self):
+ sc = self.__get_skin_cluster__()
+ dn = self.__get_data_node__()
+
+ if sc is None or dn is None:
+ return
+
+ existing_ref_mesh = self.get_reference_mesh()
+ if existing_ref_mesh:
+ cmds.select(existing_ref_mesh)
+ raise Exception("symmetry mesh already configured for %s: %s" % (str(sc), existing_ref_mesh))
+
+ def get_shape(node):
+ return cmds.listRelatives(node, shapes=True)[0]
+
+ result, _ = cmds.polyCube()
+ g = cmds.group(empty=True, name="ngskintools_mirror_mesh_setup")
+ cmds.parent(result, g)
+ result = cmds.rename(g + "|" + result, "mirror_reference_mesh")
+
+ cmds.delete(result, ch=True)
+ cmds.connectAttr(sc + ".input[0].inputGeometry", get_shape(result) + ".inMesh")
+ cmds.delete(result, ch=True)
+
+ (mirrored,) = cmds.duplicate(result)
+ mirrored = cmds.rename(g + "|" + mirrored, 'flipped_preview')
+ mirrored_shape = get_shape(mirrored)
+
+ cmds.setAttr(mirrored + ".sx", -1)
+ cmds.setAttr(mirrored + ".overrideEnabled", 1)
+ cmds.setAttr(mirrored + ".overrideDisplayType", 2)
+ cmds.setAttr(mirrored + ".overrideShading", 0)
+ cmds.setAttr(mirrored + ".overrideTexturing", 1)
+
+ (blend,) = cmds.blendShape(result, mirrored_shape)
+ cmds.setAttr(blend + ".weight[0]", 1.0)
+
+ # lock accidental transformations
+ for c, t, m in itertools.product('xyz', 'trs', (result, mirrored)):
+ cmds.setAttr(m + "." + t + c, lock=True)
+
+ # shift setup to the right by slightly more than bounding box width
+
+ bb = cmds.exactWorldBoundingBox(g)
+ cmds.move((bb[3] - bb[0]) * 1.2, 0, 0, g, r=True)
+
+ self.set_reference_mesh(str(result))
+ cmds.select(result)
+ return result
+
+
+class MirrorOptions(Object):
+ directionNegativeToPositive = 0
+ directionPositiveToNegative = 1
+ directionGuess = 2
+ directionFlip = 3
+
+ def __init__(self):
+ self.mirrorWeights = True
+ self.mirrorMask = True
+ self.mirrorDq = True
+ self.direction = MirrorOptions.directionPositiveToNegative
+
+
+def set_reference_mesh_from_selection():
+ selection = cmds.ls(sl=True, long=True)
+
+ if len(selection) != 2:
+ log.debug("wrong selection size")
+ return
+
+ m = Mirror(selection[1])
+ m.set_reference_mesh(selection[0])
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/paint.py b/2023/scripts/rigging_tools/ngskintools2/api/paint.py
new file mode 100644
index 0000000..2b06842
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/paint.py
@@ -0,0 +1,466 @@
+import copy
+import json
+
+from maya import cmds
+
+from ngSkinTools2.api import internals, plugin
+from ngSkinTools2.api.log import getLogger
+from ngSkinTools2.api.pyside import QtCore
+from ngSkinTools2.api.python_compatibility import Object
+
+log = getLogger("api/paint")
+
+
+# noinspection PyClassHasNoInit
+class BrushProjectionMode(Object):
+ surface = 0
+ screen = 1
+
+
+# noinspection PyClassHasNoInit
+class PaintMode(Object):
+ """
+ Constants for paint mode
+ """
+
+ replace = 1
+ add = 2
+ scale = 3
+ smooth = 4
+ sharpen = 5
+
+ @classmethod
+ def all(cls):
+ return cls.replace, cls.smooth, cls.add, cls.scale, cls.sharpen
+
+
+# noinspection PyClassHasNoInit
+class TabletMode(Object):
+ unused = 0
+ multiplyIntensity = 1
+ multiplyOpacity = 2
+ multiplyRadius = 3
+
+
+# noinspection PyClassHasNoInit
+class WeightsDisplayMode(Object):
+ allInfluences = 0
+ currentInfluence = 1
+ currentInfluenceColored = 2
+
+
+# noinspection PyClassHasNoInit
+class MaskDisplayMode(Object):
+ default_ = 0
+ color_ramp = 1
+
+
+# noinspection PyClassHasNoInit
+class BrushShape(Object):
+ solid = 0 # 1.0 for whole brush size
+ smooth = 1 # feathered edges
+ gaus = 2 # very smooth from center
+
+
+# noinspection PyClassHasNoInit
+class PaintModeSettings(Object):
+ """
+ Brush/Flood settings
+ """
+
+ __property_map = {
+ "brush_projection_mode": 'brushProjectionMode',
+ "mode": 'paintMode',
+ "brush_radius": 'brushRadius',
+ "brush_shape": 'brushShape',
+ "intensity": 'brushIntensity',
+ "iterations": 'brushIterations',
+ "tablet_mode": 'tabletMode',
+ "mirror": 'interactiveMirror',
+ "influences_limit": 'influencesLimit',
+ "fixed_influences_per_vertex": 'fixedInfluencesPerVertex',
+ "limit_to_component_selection": 'limitToComponentSelection',
+ "use_volume_neighbours": 'useVolumeNeighbours',
+ "distribute_to_other_influences": 'redistributeRemovedWeight',
+ "sample_joint_on_stroke_start": 'sampleJointOnStrokeStart',
+ }
+
+ mode = PaintMode.replace #: Tool mode. One of the :py:class:`PaintMode` values.
+
+ # varies by mode
+ intensity = 1.0 #: tool intensity;
+ iterations = 1
+ """
+ iterations; repeats the same smooth operation given number of times -
+ using this parameter instead of calling `flood_weights` multiple times.
+ """
+
+ brush_shape = BrushShape.solid
+
+ # varies by screen mode
+ # can be modified inside the plugin
+ brush_radius = 10
+
+ mirror = False #: is automatic mirroring on or off
+ distribute_to_other_influences = False
+ influences_limit = 0 #: influences limit per vertex to ensure while smoothing
+ brush_projection_mode = BrushProjectionMode.surface #: brush projection mode, one of :py:class:`BrushProjectionMode` values.
+ sample_joint_on_stroke_start = False
+ tablet_mode = TabletMode.unused
+ use_volume_neighbours = False
+ limit_to_component_selection = False
+ fixed_influences_per_vertex = False
+ """
+ only applicable for smooth mode; when set to True, smoothing will not add additional influences to a vertex.
+ """
+
+ def apply_primary_brush(self):
+ self.__apply(1)
+
+ def apply_alternative_brush(self):
+ self.__apply(2)
+
+ def apply_inverted_brush(self):
+ self.__apply(3)
+
+ def __apply(self, settings_type):
+ """
+ apply settings to C++ plugin side.
+ :param settings_type:
+ """
+
+ kwargs = {v: getattr(self, k) for k, v in self.__property_map.items()}
+ kwargs['paintType'] = settings_type
+ plugin.ngst2PaintSettingsCmd(**kwargs)
+
+ def from_dict(self, values):
+ # type: (dict) -> PaintModeSettings
+
+ for k in self.__property_map.keys():
+ if k in values:
+ setattr(self, k, values[k])
+
+ return self
+
+ def to_dict(self):
+ # type: () -> dict
+ return {k: getattr(self, k) for k in self.__property_map.keys()}
+
+
+def __make_common_property__(property_name):
+ def setval(self, val):
+ setattr(self.primary_settings, property_name, val)
+ self.apply_settings()
+
+ return property(lambda self: getattr(self.primary_settings, property_name), setval)
+
+
+def __make_mode_property__(property_name):
+ return __make_dimensional_property__(lambda self: self.mode, lambda self: self.mode_settings[self.mode], property_name)
+
+
+def __make_projection_property__(property_name):
+ return __make_dimensional_property__(
+ lambda self: self.brush_projection_mode, lambda self: self.projection_settings[self.brush_projection_mode], property_name
+ )
+
+
+def __make_dimensional_property__(name, get_dimension_func, property_name):
+ def setval(self, val):
+ log.debug("setting dimensional property %s/%s: %r", name(self), property_name, val)
+ dimension = get_dimension_func(self)
+ dimension[property_name] = val
+ setattr(self.primary_settings, property_name, val)
+ self.apply_settings()
+
+ def getval(self):
+ return get_dimension_func(self).get(property_name, getattr(self.primary_settings, property_name))
+
+ return property(getval, setval)
+
+
+class PaintSettingsModel(Object):
+ """
+ Paint settings model manages paint settings persistence and storage on CPP side;
+ in CPP side three states need to be maintained:
+ * primary settings
+ * alternative settings (used when shift is pressed)
+ * inverse settings (used when ctrl is pressed)
+ """
+
+ projection_settings = None # type: dict
+ mode_settings = None # type: dict
+ primary_settings = None # type: PaintModeSettings
+
+ paint_mode = __make_common_property__("mode")
+ mode = __make_common_property__("mode")
+
+ intensity = __make_mode_property__("intensity")
+ iterations = __make_mode_property__("iterations")
+ brush_shape = __make_mode_property__("brush_shape")
+
+ brush_radius = __make_projection_property__("brush_radius")
+
+ mirror = __make_common_property__("mirror")
+ distribute_to_other_influences = __make_common_property__("distribute_to_other_influences")
+ influences_limit = __make_common_property__("influences_limit")
+ brush_projection_mode = __make_common_property__("brush_projection_mode")
+ sample_joint_on_stroke_start = __make_common_property__("sample_joint_on_stroke_start")
+ tablet_mode = __make_common_property__("tablet_mode")
+ use_volume_neighbours = __make_common_property__("use_volume_neighbours")
+ limit_to_component_selection = __make_common_property__("limit_to_component_selection")
+ fixed_influences_per_vertex = __make_common_property__("fixed_influences_per_vertex")
+
+ def __init__(self):
+ self.projection_settings = None
+ self.mode_settings = None
+ self.primary_settings = None
+ self.storage_func_save = lambda data: None
+ self.storage_func_load = lambda: ""
+ self.apply_settings_func = self.apply_plugin_settings
+
+ self.setup_maya_option_var_persistence()
+
+ def __save_settings(self):
+ data = {
+ "common": self.primary_settings.to_dict(),
+ "mode_settings": self.mode_settings,
+ "projection_settings": self.projection_settings,
+ }
+ serialized_data = json.dumps(data)
+ log.info("saving brush settings: %s", serialized_data)
+ self.storage_func_save(serialized_data)
+
+ def load_settings(self):
+ def to_int_keys(d):
+ return {int(k): v for k, v in d.items()}
+
+ try:
+ saved_data = self.storage_func_load()
+ log.info("loading brush settings from %s", saved_data)
+ if saved_data is None:
+ self.initialize_defaults()
+ return
+ data = json.loads(saved_data)
+ self.primary_settings = PaintModeSettings().from_dict(data['common'])
+ self.mode_settings = to_int_keys(data['mode_settings'])
+ self.projection_settings = to_int_keys(data['projection_settings'])
+ self.apply_settings()
+ except Exception as err:
+ log.info(err)
+
+ def setup_maya_option_var_persistence(self):
+ from ngSkinTools2.ui import options
+
+ val = options.PersistentValue(options.VAR_OPTION_PREFIX + "_brush_settings")
+
+ self.storage_func_load = val.get
+ self.storage_func_save = val.set
+ self.load_settings()
+
+ def __bake_settings(self, mode):
+ result = copy.copy(self.primary_settings)
+ result.mode = mode
+
+ for k, v in self.mode_settings[mode].items():
+ setattr(result, k, v)
+
+ for k, v in self.projection_settings[self.brush_projection_mode].items():
+ setattr(result, k, v)
+
+ return result
+
+ def apply_settings(self):
+ # TODO: very inelegant here; we should not have to re-bake and re-set all settings at once
+ # if we're switching any of dimensional settings, we need to reflect this
+ self.primary_settings = self.__bake_settings(self.mode)
+ primary = self.primary_settings
+
+ inverted_modes = {
+ PaintMode.replace: PaintMode.replace,
+ PaintMode.add: PaintMode.scale,
+ PaintMode.scale: PaintMode.add,
+ PaintMode.smooth: PaintMode.sharpen,
+ PaintMode.sharpen: PaintMode.smooth,
+ }
+
+ alternative = self.__bake_settings(PaintMode.smooth)
+ inverted = self.__bake_settings(inverted_modes.get(self.mode, PaintMode.replace))
+
+ if self.mode == PaintMode.replace:
+ inverted.intensity = 0
+
+ log.debug("normal mode intensity: %r", primary.intensity)
+ self.apply_settings_func(primary, alternative, inverted)
+ self.__save_settings()
+
+ def initialize_defaults(self):
+ self.primary_settings = PaintModeSettings()
+ self.primary_settings.mode = PaintMode.replace
+ self.primary_settings.brush_radius = 2
+ self.primary_settings.intensity = 1.0
+ self.primary_settings.tablet_mode = TabletMode.unused
+ self.primary_settings.brush_shape = BrushShape.solid
+ self.primary_settings.distribute_to_other_influences = False
+ self.mode_settings = {
+ PaintMode.replace: {
+ "intensity": 1.0,
+ "brush_shape": BrushShape.solid,
+ },
+ PaintMode.add: {
+ "intensity": 0.1,
+ "brush_shape": BrushShape.solid,
+ },
+ PaintMode.scale: {
+ "intensity": 0.95,
+ "brush_shape": BrushShape.solid,
+ },
+ PaintMode.smooth: {
+ "intensity": 0.2,
+ "iterations": 5,
+ "brush_shape": BrushShape.smooth,
+ },
+ PaintMode.sharpen: {
+ "intensity": 0.2,
+ "iterations": 5,
+ "brush_shape": BrushShape.smooth,
+ },
+ }
+ self.projection_settings = {
+ BrushProjectionMode.surface: {
+ "brush_radius": 2,
+ },
+ BrushProjectionMode.screen: {
+ "brush_radius": 100,
+ },
+ }
+ self.apply_settings()
+
+ # noinspection PyMethodMayBeStatic
+ def apply_plugin_settings(self, primary, alternative, inverted):
+ # type: (PaintModeSettings, PaintModeSettings, PaintModeSettings) -> None
+ primary.apply_primary_brush()
+ alternative.apply_alternative_brush()
+ inverted.apply_inverted_brush()
+
+
+class DisplaySettings(Object):
+ def __init__(self):
+ from ngSkinTools2.ui import options
+
+ self.persistence = options.PersistentDict("paint_display_settings")
+
+ weights_display_mode = internals.make_editable_property('weightsDisplayMode')
+ mask_display_mode = internals.make_editable_property('maskDisplayMode')
+ layer_effects_display = internals.make_editable_property('layerEffectsDisplay')
+ display_masked = internals.make_editable_property('displayMasked')
+ show_selected_verts_only = internals.make_editable_property('showSelectedVertsOnly')
+ wireframe_color = internals.make_editable_property('wireframeColor')
+ wireframe_color_single_influence = internals.make_editable_property('wireframeColorSingleInfluence')
+
+ # noinspection PyMethodMayBeStatic
+ def __edit__(self, **kwargs):
+ plugin.ngst2PaintSettingsCmd(**kwargs)
+ for k, v in kwargs.items():
+ self.persistence[k] = v
+
+ @property
+ def display_node_visible(self):
+ """
+ gets/sets visibility of temporary node that displays weight colors. when set to false, displays original mesh instead.
+ """
+ return plugin.ngst2PaintSettingsCmd(q=True, displayNodeVisible=True)
+
+ @display_node_visible.setter
+ def display_node_visible(self, value):
+ plugin.ngst2PaintSettingsCmd(displayNodeVisible=value)
+
+ # noinspection PyMethodMayBeStatic
+ def __query__(self, **kwargs):
+ for k in kwargs:
+ persisted = self.persistence[k]
+ if persisted is not None:
+ return persisted
+ return plugin.ngst2PaintSettingsCmd(q=True, **kwargs)
+
+
+class PaintTool(PaintSettingsModel):
+ __paint_context = None
+
+ def __init__(self):
+ PaintSettingsModel.__init__(self)
+ self.display_settings = DisplaySettings()
+
+ def update_plugin_brush_radius(self):
+ new_value = plugin.ngst2PaintSettingsCmd(q=True, brushRadius=True)
+ if self.brush_radius != new_value:
+ self.brush_radius = new_value
+
+ def update_plugin_brush_intensity(self):
+ new_value = plugin.ngst2PaintSettingsCmd(q=True, brushIntensity=True)
+ if self.intensity != new_value:
+ self.intensity = new_value
+
+ @classmethod
+ def start(cls):
+ if cls.__paint_context is None:
+ cls.__paint_context = plugin.ngst2PaintContext()
+ cmds.setToolTo(cls.__paint_context)
+
+ def flood(self, layer, influence=None, influences=None):
+ from ngSkinTools2.api import tools
+
+ tools.flood_weights(target=layer, influence=influence, influences=influences, settings=self.primary_settings)
+
+ @classmethod
+ def is_painting(cls):
+ return cmds.contextInfo(cmds.currentCtx(), c=True) == 'ngst2PaintContext'
+
+
+class Popups(Object):
+ def __init__(self):
+ self.windows = []
+
+ def add(self, w):
+ self.windows.append(w)
+ w.destroyed.connect(lambda *args: self.remove(w))
+
+ def remove(self, w):
+ self.windows = [i for i in self.windows if i != w]
+
+ def close_all(self):
+ for i in self.windows:
+ i.close()
+ self.windows = []
+
+
+popups = Popups()
+
+
+class TabletEventFilter(QtCore.QObject):
+ def __init__(self):
+ QtCore.QObject.__init__(self)
+ self.pressure = 1.0
+
+ def eventFilter(self, obj, event):
+ if event.type() in [QtCore.QEvent.TabletPress, QtCore.QEvent.TabletMove]:
+ self.pressure = event.pressure()
+ # log.info("tablet pressure: %r", self.pressure)
+
+ return QtCore.QObject.eventFilter(self, obj, event)
+
+ def install(self):
+ from ngSkinTools2.ui import qt
+
+ log.info("installing event filter...")
+ qt.mainWindow.installEventFilter(self)
+ log.info("...done")
+
+ def uninstall(self):
+ from ngSkinTools2.ui import qt
+
+ qt.mainWindow.removeEventFilter(self)
+ log.info("event filter uninstalled")
+
+
+tabletEventFilter = TabletEventFilter()
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/plugin.py b/2023/scripts/rigging_tools/ngskintools2/api/plugin.py
new file mode 100644
index 0000000..1e21f8b
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/plugin.py
@@ -0,0 +1,70 @@
+import json
+
+from maya import cmds, mel
+
+from ngSkinTools2.api import feedback
+from ngSkinTools2.api.log import getLogger
+
+log = getLogger("plugin")
+
+
+def ngst2Layers(*args, **kwargs):
+ log.debug("ngst2layers [%r] [%r]", args, kwargs)
+ return cmds.ngst2Layers(*args, **kwargs)
+
+
+def ngst2LayersMel(cmd):
+ cmd = "ngst2Layers " + cmd
+ log.debug(cmd)
+ return mel.eval(cmd)
+
+
+def ngst2tools(**kwargs):
+ log.debug("ngst2tools [%r]", kwargs)
+ result = cmds.ngst2Tools(json.dumps(kwargs))
+ if result is not None:
+ result = json.loads(result)
+ return result
+
+
+def ngst2PaintContext():
+ log.debug("ngst2PaintContext()")
+ return cmds.ngst2PaintContext()
+
+
+def ngst2PaintSettingsCmd(**kwargs):
+ log.debug("ngst2PaintSettingsCmd [%r]", kwargs)
+ return cmds.ngst2PaintSettingsCmd(**kwargs)
+
+
+def ngst2_hotkey(**kwargs):
+ log.debug("ngst2Hotkey [%r]", kwargs)
+ return cmds.ngst2Hotkey(**kwargs)
+
+
+pluginBinary = 'ngSkinTools2'
+
+
+def is_plugin_loaded():
+ return cmds.pluginInfo(pluginBinary, q=True, loaded=True)
+
+
+def load_plugin():
+ from maya import cmds
+
+ if not is_plugin_loaded():
+ cmds.loadPlugin(pluginBinary, quiet=True)
+
+ if not is_plugin_loaded():
+ feedback.display_error("Failed to load the plugin. This is often a case-by-case issue - contact support.")
+ return
+
+ from ngSkinTools2 import version
+
+ expected_version = version.pluginVersion()
+ actual_version = cmds.pluginInfo(pluginBinary, q=True, version=True)
+ if actual_version != expected_version:
+ feedback.display_error(
+ "Invalid plugin version detected: required '{expectedVersion}', "
+ "but was '{actualVersion}'. Clean reinstall recommended.".format(expectedVersion=expected_version, actualVersion=actual_version)
+ )
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/pyside.py b/2023/scripts/rigging_tools/ngskintools2/api/pyside.py
new file mode 100644
index 0000000..bf8c00e
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/pyside.py
@@ -0,0 +1,29 @@
+pyside6 = False
+try:
+ from PySide6 import QtCore, QtGui, QtSvg, QtWidgets
+ from PySide6.QtCore import Qt
+ from PySide6.QtGui import QAction, QActionGroup
+ from PySide6.QtSvgWidgets import QSvgWidget
+ from PySide6.QtWidgets import QWidget
+
+ pyside6 = True
+except:
+ from PySide2 import QtCore, QtGui, QtSvg, QtWidgets
+ from PySide2.QtCore import Qt
+ from PySide2.QtSvg import QSvgWidget
+ from PySide2.QtWidgets import QAction, QActionGroup, QWidget
+
+
+def get_main_window():
+ from maya import OpenMayaUI as omui
+
+ return wrap_instance(omui.MQtUtil.mainWindow(), QWidget)
+
+
+def wrap_instance(ptr, widget):
+ if pyside6:
+ from shiboken6 import wrapInstance
+ else:
+ from shiboken2 import wrapInstance
+
+ return wrapInstance(int(ptr), widget)
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/python_compatibility.py b/2023/scripts/rigging_tools/ngskintools2/api/python_compatibility.py
new file mode 100644
index 0000000..f84003a
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/python_compatibility.py
@@ -0,0 +1,24 @@
+import sys
+
+PY2 = sys.version_info[0] == 2
+PY3 = not PY2
+
+
+def is_string(obj):
+ if PY2:
+ # noinspection PyUnresolvedReferences
+ return isinstance(obj, basestring)
+
+ return isinstance(obj, str)
+
+
+# need to use a new-style class in case of python2, or "normal" class otherwise
+if PY2:
+
+ class Object(object):
+ pass
+
+else:
+
+ class Object:
+ pass
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/session.py b/2023/scripts/rigging_tools/ngskintools2/api/session.py
new file mode 100644
index 0000000..4423c92
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/session.py
@@ -0,0 +1,162 @@
+"""
+UI session is running as long as any of the ngSkinTools UI windows are open.
+
+"""
+import functools
+
+from ngSkinTools2 import cleanup, signal
+from ngSkinTools2.api import Layers, PaintTool, events, mirror, plugin
+from ngSkinTools2.api.log import getLogger
+from ngSkinTools2.api.python_compatibility import Object
+from ngSkinTools2.observableValue import ObservableValue
+from ngSkinTools2.signal import SignalHub
+
+log = getLogger("events")
+
+
+class CurrentLayerState(Object):
+ def __init__(self):
+ self.selectedSkinCluster = None
+
+ # will be None, when no current layer is available
+ self.layer = None # type: ngSkinTools2.api.Layer
+
+
+class CurrentPaintTargetState(Object):
+ def __init__(self):
+ self.skinCluster = None
+ self.layerId = None
+ self.targets = None
+
+
+class State(Object):
+ def __init__(self):
+ self.layersAvailable = False
+ self.selection = []
+ self.selectedSkinCluster = None
+ self.skin_cluster_dq_channel_used = False
+
+ self.all_layers = [] # type: List[ngSkinTools2.api.Layer]
+ self.currentLayer = CurrentLayerState()
+ self.currentInfluence = CurrentPaintTargetState()
+
+ def set_skin_cluster(self, cluster):
+ self.selectedSkinCluster = cluster
+ self.layers = None if cluster is None else Layers(cluster)
+
+ def mirror(self):
+ # type: () -> mirror.Mirror
+ return mirror.Mirror(self.selectedSkinCluster)
+
+
+class Context(Object):
+ def __init__(self):
+ self.selected_layers = ObservableValue() # [] layerId
+
+
+class Session(Object):
+ def __init__(self):
+ # reference objects that are keeping the session
+ self.references = set()
+ self.state = None # type: State
+ self.events = None # type: events.Events
+ self.signal_hub = None # type: SignalHub
+ self.context = None # type: Context
+
+ self.referenceId = 0
+
+ def active(self):
+ return len(self.references) > 0
+
+ def start(self):
+ log.info("STARTING SESSION")
+ plugin.load_plugin()
+
+ self.paint_tool = PaintTool()
+
+ self.state = State()
+ self.events = events.Events(self.state)
+ self.signal_hub = SignalHub()
+ self.signal_hub.activate()
+ cleanup.registerCleanupHandler(self.signal_hub.deactivate)
+ self.context = Context()
+
+ @signal.on(self.events.targetChanged)
+ def on_target_change():
+ log.info("target changed: clearing target context")
+ self.context.selected_layers.set([])
+
+ self.events.nodeSelectionChanged.emit()
+
+ def end(self):
+ log.info("ENDING SESSION")
+ cleanup.cleanup()
+ self.state = None
+ self.events = None
+ self.context = None
+ self.signal_hub = None
+ pass
+
+ def addReference(self):
+ """
+ returns unique ID for this added reference; this value needs to be passed into removeReference();
+ this ensures that reference holder does not remove other references rather than his own.
+ :return:
+ """
+ self.referenceId += 1
+ if not self.active():
+ self.start()
+
+ self.references.add(self.referenceId)
+ return self.referenceId
+
+ def removeReference(self, referenceId):
+ try:
+ self.references.remove(referenceId)
+ except KeyError:
+ pass
+
+ if not self.active():
+ self.end()
+
+ def addQtWidgetReference(self, widget):
+ ref = self.addReference()
+
+ widget.destroyed.connect(lambda: self.removeReference(ref))
+
+ def reference(self):
+ class Context(Object):
+ def __init__(self, session):
+ """
+ :type session: Session
+ :type refObj: object
+ """
+
+ self.session = session
+
+ def __enter__(self):
+ self.ref = self.session.addReference()
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.session.removeReference(self.ref)
+
+ return Context(self)
+
+
+session = Session()
+
+
+def withSession(func):
+ """
+ decorator makes sure that single session is running throughout function's lifetime
+ """
+
+ @functools.wraps(func)
+ def result(*args, **kwargs):
+ ref = session.addReference()
+ try:
+ return func(*args, **kwargs)
+ finally:
+ session.removeReference(ref)
+
+ return result
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/suspend_updates.py b/2023/scripts/rigging_tools/ngskintools2/api/suspend_updates.py
new file mode 100644
index 0000000..078b0b8
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/suspend_updates.py
@@ -0,0 +1,17 @@
+from ngSkinTools2.api import plugin
+from ngSkinTools2.api.python_compatibility import Object
+
+
+def suspend_updates(target):
+ return SuspendUpdatesContext(target)
+
+
+class SuspendUpdatesContext(Object):
+ def __init__(self, target):
+ self.target = target
+
+ def __enter__(self):
+ plugin.ngst2Layers(self.target, suspendUpdates=True)
+
+ def __exit__(self, _type, value, traceback):
+ plugin.ngst2Layers(self.target, suspendUpdates=False)
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/target_info.py b/2023/scripts/rigging_tools/ngskintools2/api/target_info.py
new file mode 100644
index 0000000..c5ea229
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/target_info.py
@@ -0,0 +1,86 @@
+import json
+
+from maya import cmds
+
+from ngSkinTools2.api import plugin
+
+from .influenceMapping import InfluenceInfo
+
+
+def get_related_skin_cluster(target):
+ """
+ Returns skinCluster if provided node name represents skinned mesh. Returns true for shapes that have
+ skinCLuster in their deformation stack, or it's a skinCluster node itself.
+
+ For invalid targets, returns None
+ """
+
+ return plugin.ngst2Layers(target, q=True, layerDataAttachTarget=True)
+
+
+def get_related_data_node(target):
+ """
+ :returns: ngSkinTools data node name for this target
+ """
+ return plugin.ngst2Layers(target, q=True, layerDataNode=True)
+
+
+def unserialize_influences_from_json_data(info):
+ def as_influence_info(data):
+ influence = InfluenceInfo()
+ influence.pivot = data['pivot']
+ influence.path = data.get('path', None)
+ influence.name = data.get('name', None)
+ influence.labelText = data['labelText']
+ influence.labelSide = InfluenceInfo.SIDE_MAP[data['labelSide']]
+ influence.logicalIndex = data['index']
+
+ return influence
+
+ if not info:
+ return []
+
+ return [as_influence_info(i) for i in info]
+
+
+def list_influences(target):
+ """
+ List influences in the given skin cluster as InfluenceInfo objects
+
+ :param str target: target mesh or skin cluster
+ :rtype: list[InfluenceInfo]
+ """
+ info = json.loads(plugin.ngst2Layers(target, q=True, influenceInfo=True))
+ return unserialize_influences_from_json_data(info)
+
+
+def add_influences(influences, target):
+ """
+ A shortcut for adding additional influences to a skincluster, without impacting existing weights
+
+ :param list[str] influences: list of influence paths
+ :param str target: target mesh or skin cluster
+ """
+
+ skin_cluster = get_related_skin_cluster(target)
+
+ def long_names(names):
+ result = set(cmds.ls(names, long=True))
+ if len(result) != len(names):
+ raise Exception("could not convert to a list of influences names: " + str(names))
+ return result
+
+ existing = long_names([i.name if not i.path else i.path for i in list_influences(skin_cluster)])
+ influences = long_names(influences)
+ for i in influences - existing:
+ cmds.skinCluster(skin_cluster, edit=True, addInfluence=i, weight=0)
+
+
+def is_slow_mode_skin_cluster(target):
+ """
+ returns true, if ngSkinTools chose to use slow ngSkinTools api for this target. Right now this only happens when skinCluster has non-transform
+ nodes as influences (e.g. inverseMatrix node).
+
+ :param str target: target mesh or skin cluster
+ """
+ return plugin.ngst2Layers(target, q=True, skinClusterWriteMode=True) == "plug"
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/tools.py b/2023/scripts/rigging_tools/ngskintools2/api/tools.py
new file mode 100644
index 0000000..c10a304
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/tools.py
@@ -0,0 +1,189 @@
+from ngSkinTools2.api import Layer, Layers
+from ngSkinTools2.api import layers as api_layers
+from ngSkinTools2.api import plugin
+from ngSkinTools2.api.layers import generate_layer_name
+from ngSkinTools2.api.log import getLogger
+from ngSkinTools2.api.paint import PaintModeSettings
+from ngSkinTools2.api.target_info import list_influences
+from ngSkinTools2.decorators import undoable
+
+log = getLogger("tools")
+
+
+def assign_from_closest_joint(target, layer, influences=None):
+ # type: (str, Layer, List[int]) -> None
+ """
+ For each selected vertex, picks a nearest joint and assigns 1.0 weight to that joint.
+
+ Operates on the currently active component selection, or whole mesh, depending on selection.
+
+ :param str target: skinned mesh or skin cluster node name;
+ :param Layer layer: int or :py:class:`Layer` object to apply weights to;
+ :param List[int] influences: selects only from provided subset of skinCluster influences.
+ """
+
+ if influences is None:
+ influences = [i.logicalIndex for i in list_influences(target)]
+
+ if len(influences) == 0:
+ # nothing to do?
+ return
+
+ plugin.ngst2tools(
+ tool="closestJoint",
+ target=target,
+ layer=api_layers.as_layer_id(layer),
+ influences=[int(i) for i in influences],
+ )
+
+
+def unify_weights(target, layer, overall_effect, single_cluster_mode):
+ """
+ For all selected vertices, calculates average weights and assigns that value to each vertice. The effect is that all vertices end up having same weights.
+
+ Operates on the currently active component selection, or whole mesh, depending on selection.
+
+ :param str target: skinned mesh or skin cluster node name;
+ :param Layer layer: int or :py:class:`Layer` object to apply weights to;
+ :param float overall_effect: value between `0.0` and `1.0`, intensity of the operation. When applying newly calculated weights to the skin cluster,
+ the formula is `weights = lerp(originalWeights, newWeights, overallEffect)`.
+ :param bool single_cluster_mode: if `true`, all weights will receive the same average. If `false`, each connected mesh shell will be computed independently.
+ """
+ plugin.ngst2tools(
+ tool="unifyWeights",
+ target=target,
+ layer=api_layers.as_layer_id(layer),
+ overallEffect=overall_effect,
+ singleClusterMode=single_cluster_mode,
+ )
+
+
+def flood_weights(target, influence=None, influences=None, settings=None):
+ """
+ Apply paint tool in the layer with the given settings.
+
+ :param target: layer or mesh to set the weights in.
+ :param influence: target influence: either an int for the logical index of the influence, or one of :py:class:`NamedPaintTarget` constants. Can be skipped if tool mode is Smooth or Sharpen.
+ :param influences: if specified, overrides "influence" and allows passing multiple influences instead. Only supported by flood and sharpen at the moment.
+ :type settings: PaintModeSettings
+ """
+
+ if settings is None:
+ settings = PaintModeSettings() # just use default settings
+
+ args = {
+ 'tool': "floodWeights",
+ 'influences': influences if influences is not None else [influence],
+ 'mode': settings.mode,
+ 'intensity': settings.intensity,
+ 'iterations': int(settings.iterations),
+ 'influencesLimit': int(settings.influences_limit),
+ 'mirror': bool(settings.mirror),
+ 'distributeRemovedWeight': settings.distribute_to_other_influences,
+ 'limitToComponentSelection': settings.limit_to_component_selection,
+ 'useVolumeNeighbours': settings.use_volume_neighbours,
+ 'fixedInfluencesPerVertex': bool(settings.fixed_influences_per_vertex),
+ }
+ layer = None if not isinstance(target, Layer) else target # type: Layer
+ if layer:
+ args['layer'] = api_layers.as_layer_id(layer)
+
+ args['target'] = target if layer is None else layer.mesh
+
+ plugin.ngst2tools(**args)
+
+
+@undoable
+def merge_layers(layers):
+ """
+ :type layers: list[Layer]
+ :rtype: Layer
+ """
+ if len(layers) > 1:
+ # verify that all layers are from the same parent
+ for i, j in zip(layers[:-1], layers[1:]):
+ if i.mesh != j.mesh:
+ raise Exception("layers are not from the same mesh")
+
+ result = plugin.ngst2tools(
+ tool="mergeLayers",
+ target=layers[0].mesh,
+ layers=[api_layers.as_layer_id(i) for i in layers],
+ )
+
+ target_layer = Layer.load(layers[0].mesh, result['layerId'])
+ target_layer.set_current()
+
+ return target_layer
+
+
+@undoable
+def duplicate_layer(layer):
+ """
+
+ :type layer: Layer
+ :rtype: Layer
+ """
+
+ result = plugin.ngst2tools(
+ tool="duplicateLayer",
+ target=layer.mesh,
+ sourceLayer=layer.id,
+ )
+
+ target_layer = Layer.load(layer.mesh, result['layerId'])
+
+ import re
+
+ base_name = re.sub(r"( \(copy\))?( \(\d+\))*", "", layer.name)
+ other_layers = [l for l in Layers(target_layer.mesh).list() if l.id != target_layer.id]
+ target_layer.name = generate_layer_name(other_layers, base_name + " (copy)")
+
+ target_layer.set_current()
+
+ return target_layer
+
+
+@undoable
+def fill_transparency(layer):
+ """
+
+ :type layer: Layer
+ """
+
+ plugin.ngst2tools(
+ tool="fillLayerTransparency",
+ target=layer.mesh,
+ layer=layer.id,
+ )
+
+
+def copy_component_weights(layer):
+ """
+ :type layer: Layer
+ """
+
+ plugin.ngst2tools(
+ tool="copyComponentWeights",
+ target=layer.mesh,
+ layer=layer.id,
+ )
+
+
+def paste_average_component_weights(layer):
+ """
+ :type layer: Layer
+ """
+
+ plugin.ngst2tools(
+ tool="pasteAverageComponentWeights",
+ target=layer.mesh,
+ layer=layer.id,
+ )
+
+
+def refresh_screen(target):
+ plugin.ngst2tools(
+ tool="refreshScreen",
+ target=target,
+ )
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/transfer.py b/2023/scripts/rigging_tools/ngskintools2/api/transfer.py
new file mode 100644
index 0000000..9c175c9
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/transfer.py
@@ -0,0 +1,110 @@
+import itertools
+
+from ngSkinTools2.api.python_compatibility import Object
+from ngSkinTools2.decorators import undoable
+
+from . import plugin
+from .influenceMapping import InfluenceMapping, InfluenceMappingConfig
+from .layers import init_layers, target_info
+from .mirror import Mirror
+from .suspend_updates import suspend_updates
+
+
+class VertexTransferMode(Object):
+ """
+ Constants for vertex_transfer_mode argument
+ """
+
+ closestPoint = 'closestPoint' #: When vertices from two surface are matched, each destination mesh vertex finds a closest point on source mesh, and weights are calculated based on the triangle weights of that closest point.
+ uvSpace = 'uvSpace' #: Similar to closestPoint strategy, but matching is done in UV space instead of XYZ space.
+ vertexId = 'vertexId' #: Vertices are matched by ID. Not usable for mirroring; this is used for transfer/import cases where meshes are known to be identical
+
+
+class LayersTransfer(Object):
+ def __init__(self):
+ self.source = None
+ self.target = None
+ self.source_file = None
+ self.vertex_transfer_mode = VertexTransferMode.closestPoint
+ self.influences_mapping = InfluenceMapping()
+ self.influences_mapping.config = InfluenceMappingConfig.transfer_defaults()
+ self.keep_existing_layers = True
+ self.customize_callback = None
+
+ def load_source_from_file(self, file, format):
+ from .import_export import FileFormatWrapper
+
+ with FileFormatWrapper(file, format=format, read_mode=True) as f:
+ data = plugin.ngst2tools(
+ tool="importJsonFile",
+ file=f.plain_file,
+ )
+
+ self.source = "-reference-mesh-"
+ self.source_file = file
+ influences = target_info.unserialize_influences_from_json_data(data['influences'])
+
+ self.influences_mapping.influences = influences
+
+ def calc_influences_mapping_as_flat_list(self):
+ mapping_pairs = list(self.influences_mapping.asIntIntMapping(self.influences_mapping.calculate()).items())
+ if len(mapping_pairs) == 0:
+ raise Exception("no mapping between source and destination influences")
+ # convert dict to flat array
+ return list(itertools.chain.from_iterable(mapping_pairs))
+
+ def execute(self):
+ # sanity check: destination must be skinnable target
+ if target_info.get_related_skin_cluster(self.target) is None:
+ return False
+
+ if not self.influences_mapping.influences:
+ if target_info.get_related_skin_cluster(self.source) is None:
+ return False
+ self.influences_mapping.influences = target_info.list_influences(self.source)
+ self.influences_mapping.destinationInfluences = target_info.list_influences(self.target)
+
+ if self.customize_callback is None:
+ self.complete_execution()
+ else:
+ self.customize_callback(self)
+
+ @undoable
+ def complete_execution(self):
+ l = init_layers(self.target)
+ Mirror(self.target).recalculate_influences_mapping()
+
+ with suspend_updates(self.target):
+ if not self.keep_existing_layers:
+ l.clear()
+
+ plugin.ngst2tools(
+ tool="transfer",
+ source=self.source,
+ target=self.target,
+ vertexTransferMode=self.vertex_transfer_mode,
+ influencesMapping=self.calc_influences_mapping_as_flat_list(),
+ )
+
+
+def transfer_layers(
+ source, destination, vertex_transfer_mode=VertexTransferMode.closestPoint, influences_mapping_config=InfluenceMappingConfig.transfer_defaults()
+):
+ """
+ Transfer skinning layers from source to destination mesh.
+
+ :param str source: source mesh or skin cluster node name
+ :param str destination: destination mesh or skin cluster node name
+ :param str vertex_transfer_mode: describes how source mesh vertices are mapped to destination vertices. Defaults to `closestPoint`
+ :param InfluenceMappingConfig influences_mapping_config: configuration for InfluenceMapping; supply this, or `influences_mapping` instance; default settings for transfer are used if this is not supplied.
+ :param InfluenceMapping influences_mapping: mapper instance to use for matching influences; if this is provided, `influences_mapping_config` is ignored.
+ :return:
+ """
+
+ t = LayersTransfer()
+ t.source = source
+ t.target = destination
+ t.vertex_transfer_mode = vertex_transfer_mode
+ t.influences_mapping.config = influences_mapping_config
+
+ t.execute()
diff --git a/2023/scripts/rigging_tools/ngskintools2/api/versioncheck.py b/2023/scripts/rigging_tools/ngskintools2/api/versioncheck.py
new file mode 100644
index 0000000..bdaaa6d
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/api/versioncheck.py
@@ -0,0 +1,51 @@
+import datetime
+
+from ngSkinTools2 import version
+from ngSkinTools2.api import http_client
+from ngSkinTools2.api.python_compatibility import Object
+
+
+class UpdateInfo(Object):
+ def __init__(self):
+ self.update_available = False
+ self.update_date = ''
+ self.latest_version = ''
+ self.download_url = ''
+
+
+def download_update_info(success_callback, failure_callback):
+ """
+ executes version info download in separate thread,
+ then runs provided callbacks in main thread when download completes or fails
+
+ returns thread object that gets started.
+ """
+
+ import platform
+
+ from maya import cmds
+
+ os = platform.system()
+ maya_version = str(int(cmds.about(api=True)))
+
+ url = http_client.encode_url(
+ "https://versiondb.ngskintools.com/releases/ngSkinTools-v2-" + os + "-maya" + maya_version,
+ {
+ 'currentVersion': version.pluginVersion(),
+ 'uniqueClientId': version.uniqueClientId(),
+ },
+ )
+
+ def on_success(response):
+ try:
+ info = UpdateInfo()
+ info.update_date = datetime.datetime.strptime(response['dateReleased'], "%Y-%m-%d")
+ info.latest_version = response['latestVersion']
+ info.download_url = response['downloadUrl']
+ info.update_available = version.compare_semver(version.pluginVersion(), info.latest_version) > 0
+
+ success_callback(info)
+ except Exception as err:
+ failure_callback(str(err))
+
+ return http_client.get_async(url, success_callback=on_success, failure_callback=failure_callback)
diff --git a/2023/scripts/rigging_tools/ngskintools2/cleanup.py b/2023/scripts/rigging_tools/ngskintools2/cleanup.py
new file mode 100644
index 0000000..fa72833
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/cleanup.py
@@ -0,0 +1,23 @@
+"""
+The purpose of the module is mostly for testing: close everything and prepare for source reload
+"""
+from __future__ import print_function
+
+from ngSkinTools2.api.log import getLogger
+
+handlers = []
+
+log = getLogger("cleanup")
+
+
+def registerCleanupHandler(handler):
+ handlers.append(handler)
+
+
+def cleanup():
+ while len(handlers) > 0:
+ handler = handlers.pop()
+ try:
+ handler()
+ except Exception as err:
+ log.error(err)
diff --git a/2023/scripts/rigging_tools/ngskintools2/decorators.py b/2023/scripts/rigging_tools/ngskintools2/decorators.py
new file mode 100644
index 0000000..f2f03b2
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/decorators.py
@@ -0,0 +1,78 @@
+from functools import wraps
+
+from maya import cmds
+
+from ngSkinTools2.api.log import getLogger
+from ngSkinTools2.api.python_compatibility import Object
+
+log = getLogger("decorators")
+
+
+def preserve_selection(function):
+ """
+ decorator for function;
+ saves selection prior to execution and restores it
+ after function finishes
+ """
+
+ @wraps(function)
+ def undoable_wrapper(*args, **kargs):
+ selection = cmds.ls(sl=True, fl=True)
+ highlight = cmds.ls(hl=True, fl=True)
+ try:
+ return function(*args, **kargs)
+ finally:
+ if selection:
+ cmds.select(selection)
+ else:
+ cmds.select(clear=True)
+ if highlight:
+ cmds.hilite(highlight)
+
+ return undoable_wrapper
+
+
+def undoable(function):
+ """
+ groups function contents into one undo block
+ """
+
+ @wraps(function)
+ def result(*args, **kargs):
+ with Undo(name=function.__name__):
+ return function(*args, **kargs)
+
+ return result
+
+
+class Undo(Object):
+ """
+ an undo context for use "with Undo():"
+ """
+
+ def __init__(self, name=None):
+ self.name = name
+
+ def __enter__(self):
+ log.debug("UNDO chunk %r: start", self.name)
+ cmds.undoInfo(openChunk=True, chunkName=self.name)
+ return self
+
+ def __exit__(self, _type, value, traceback):
+ log.debug("UNDO chunk %r: end", self.name)
+ cmds.undoInfo(closeChunk=True)
+
+
+def trace_exception(function):
+ @wraps(function)
+ def result(*args, **kwargs):
+ try:
+ return function(*args, **kwargs)
+ except Exception:
+ import sys
+ import traceback
+
+ traceback.print_exc(file=sys.__stderr__)
+ raise
+
+ return result
diff --git a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/appstore-combined.min.css b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/appstore-combined.min.css
new file mode 100644
index 0000000..6fa4209
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/appstore-combined.min.css
@@ -0,0 +1,9 @@
+/*!
+ * Bootstrap v2.3.2
+ *
+ * Copyright 2013 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world by @mdo and @fat.
+ */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.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)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.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:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,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:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{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}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,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:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}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{background-color:#fff;border:1px solid #ccc;-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,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select: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}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-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)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[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}.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}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.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}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.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}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.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}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.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}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus: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}.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;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.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,.input-append .popover,.input-prepend .popover{font-size:14px}.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}.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 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.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}.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:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.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}.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}.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}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.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}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.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}.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}.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}.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}.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;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.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}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:15px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.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}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;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 #ddd}.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}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.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}.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}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table 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}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.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:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.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:#fff;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}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.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}.dropdown-submenu:hover>.dropdown-menu{display:block}.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}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.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}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.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)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border: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);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.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)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;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;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);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;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;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);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;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;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);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;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;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);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.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}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.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}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.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}.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}.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}.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}.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}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.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,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.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}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.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,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.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}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.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}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-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)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;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}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;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)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;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;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);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.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)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.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:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.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{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.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:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline: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)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;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;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-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)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.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-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.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;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.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}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;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;outline:0;-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}.modal.fade{top:-25%;-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}.modal.fade.in{top:20%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.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;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;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);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;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}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.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 .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-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)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-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{height:20px;margin-bottom:20px;overflow:hidden;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;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;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)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;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 .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.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}.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}.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)}.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)}.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)}.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)}.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)}.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)}.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)}.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)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.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:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}[hidden]{display:none}html{font-size:100%;overflow-y:scroll;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0;font-size:13px;line-height:1.231}body,button,input,select,textarea{font-family:sans-serif;color:#222}::-moz-selection{background:#7c85d8;color:#fff;text-shadow:none}::selection{background:#7c85d8;color:#fff;text-shadow:none}a{color:#08e}a:visited{color:#08e}a:hover{color:#04e}a:focus{outline:thin dotted}a:hover,a:active{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}blockquote{margin:1em 40px}dfn{font-style:italic}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}ins{background:#ff9;color:#000;text-decoration:none}mark{background:#ff0;color:#000;font-style:italic;font-weight:bold}pre,code,kbd,samp{font-family:monospace,monospace;_font-family:'courier new',monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}ul,ol{margin:0;padding:0 0 0 20px}dd{margin:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none;margin:0;padding:2px 0 0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:0;margin:0;padding:0}label{cursor:pointer}legend{border:0;*margin-left:-7px;padding:0}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal;*overflow:visible}table button,table input{*overflow:auto}button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}input[type="checkbox"],input[type="radio"]{box-sizing:border-box}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top;resize:none}input:invalid,textarea:invalid{background-color:#f0dddd}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.clearfix:before,.clearfix:after{content:"";display:table}.clearfix:after{clear:both}.clearfix{zoom:1}@media print{*{background:transparent!important;color:black!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;z-index:99999;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;cursor:col-resize;width:5px;right:-2px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-button{display:inline-block;position:relative;padding:0;margin:0;text-decoration:none!important;cursor:pointer;text-align:center;zoom:1;overflow:hidden;color:#2a2a2a;background:#d8d8d8 url(../images/buttons/ui-button.png) repeat-x left top;border:1px solid #a8a8a8;border-bottom-color:#9e9e9e;font-size:12px;height:24px;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}input.ui-button{border-color:#888}.ie7 .ui-button{overflow:visible}a.ui-button,span.ui-button{height:22px;line-height:22px;color:#2a2a2a}input.ui-button,.ui-button .ui-button-text{line-height:23px;color:#2a2a2a;text-shadow:0 1px 1px #f2f2f2;padding:0 10px}.ui-button-text-only .ui-button-text{padding:0 20px}button.ui-button::-moz-focus-inner{border:0;padding:0}.ie7 input.ui-button,.ie7 button.ui-button .ui-button-text{line-height:20px}.ie9 .ui-button .ui-button-text{line-height:24px}.ui-button:focus{outline:0 none}.ui-button:focus,.ui-button:hover,.ui-state-focus,.ui-state-hover{background-position:left -40px}.ui-custom-active,.ui-custom-active:focus,.ui-custom-active:hover,.ui-state-active,.ui-state-active:focus,.ui-state-active:hover,.ui-button:active{background-position:left -120px;border-color:#909090}.ui-button[disabled],.ui-button[disabled]:hover,.ui-button.default[disabled],.ui-custom-active[disabled],.ui-button[disabled]:active{background-position:left top;border-color:#999;cursor:default;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}input.ui-button[disabled],input.ui-button[disabled]:hover{border-color:#ccc;color:#999;text-shadow:0 0 transparent}.ui-button.transparent[disabled]:hover{background:none!important;border-color:transparent!important;-moz-box-shadow:0 0 transparent!important;-webkit-box-shadow:0 0 transparent!important;box-shadow:0 0 transparent!important}.ui-button[disabled] .ui-button-text,.ui-button[disabled]:hover .ui-button-text,.ui-custom-active[disabled] .ui-button-text,.ui-button[disabled]:active .ui-button-text{color:#777;text-shadow:0 1px 1px #ddd}.ui-button.default{border-color:#2e52bc;-moz-box-shadow:0 0 3px #2e52bc,0 0 2px #2e52bc;-webkit-box-shadow:0 0 3px #2e52bc,0 0 2px #2e52bc;box-shadow:0 0 3px #2e52bc,0 0 2px #2e52bc}.ui-button-medium,a.ui-button-medium,span.ui-button-medium{height:30px;background-image:url(../images/buttons/ui-button-medium.png)}a.ui-button-medium,span.ui-button-medium{height:28px;line-height:28px}.ui-button-medium .ui-button-text{line-height:28px}.ie7 button.ui-button.ui-button-medium .ui-button-text{line-height:26px}.ie9 .ui-button-medium .ui-button-text{line-height:28px}.ui-button-medium-blue,a.ui-button-medium-blue,span.ui-button-medium-blue{font-weight:bold;font-size:14px;border-color:#2e6dc5;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.15);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.15);box-shadow:0 1px 0 rgba(0,0,0,0.15)}.ui-button-medium-blue:active,.ui-button-medium-blue.ui-custom-active{border-color:#1e5be6}.cssgradients .ui-button-medium-blue{background:-webkit-gradient(linear,left top,left bottom,from(#699bdc),to(#3464b1));background:-moz-linear-gradient(#699bdc,#3464b1);background:-webkit-linear-gradient(#699bdc,#3464b1)}.cssgradients .ui-button-medium-blue:hover,.cssgradients .ui-button-medium-blue:focus{background:-webkit-gradient(linear,left top,left bottom,from(#7ca9e8),to(#4575c1));background:-moz-linear-gradient(#7ca9e8,#4575c1);background:-webkit-linear-gradient(#7ca9e8,#4575c1)}.cssgradients .ui-button-medium-blue:active,.cssgradients .ui-button-medium-blue.ui-custom-active{background:-webkit-gradient(linear,left top,left bottom,from(#5e8bca),to(#2757a3));background:-moz-linear-gradient(#5e8bca,#2757a3);background:-webkit-linear-gradient(#5e8bca,#2757a3)}.no-cssgradients .ui-button-medium-blue{background-color:#5b88c8;background-image:url(../images/buttons/btn_blue_28.png)}.no-cssgradients .ui-button-medium-blue:focus,.no-cssgradients .ui-button-medium-blue:hover{background-position:0 -30px}.no-cssgradients .ui-button-medium-blue:active{background-position:0 -60px}.ui-button-medium-blue .ui-button-text{line-height:26px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.60);font-size:14px;letter-spacing:-0.01em;padding:0}.ui-button-small,span.ui-button-small{height:16px;line-height:15px;background-image:url(../images/buttons/ui-button-small.png)}.ui-button-icon-only .ui-button-text{height:16px;display:block}span.ui-button-thin{height:21px;line-height:22px}.ui-button-thin .ui-button-text{line-height:20px}.ui-button-small.ui-button-icon-only{width:16px}.ui-button.transparent{min-width:0;background-image:none;background-color:transparent;border-color:transparent;-moz-box-shadow:0 0 transparent;-webkit-box-shadow:0 0 transparent;box-shadow:0 0 transparent}.ui-button.transparent:focus,.ui-button.transparent:hover,.ui-button.transparent:active,.ui-custom-active.transparent{background-color:#d8d8d8;background-image:url(../images/buttons/ui-button.png);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button-medium.ui-button.transparent:focus,.ui-button-medium.ui-button.transparent:hover,.ui-button-medium.ui-button.transparent:active,.ui-button-medium.ui-custom-active.transparent{background-image:url(../images/buttons/ui-button-medium.png);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button-small.ui-button.transparent:focus,.ui-button-small.ui-button.transparent:hover,.ui-button-small.ui-button.transparent:active,.ui-button-small.ui-custom-active.transparent{background-image:url(../images/buttons/ui-button-small.png);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button-small.ui-button.transparent:active,.ui-button-small.ui-custom-active.transparent{background-color:#a7a7a7;outline:0 none}.ui-button.transparent:focus,.ui-button.transparent:hover{border-color:#a8a8a8;border-bottom-color:#9e9e9e;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button.transparent:active,.ui-state-active.transparent,.ui-state-active.transparent:focus,.ui-state-active.transparent:hover,.ui-custom-active.transparent,.ui-custom-active.transparent:focus,.ui-custom-active.transparent:hover{border-color:#909090;-moz-box-shadow:0 1px 0 rgba(0,0,0,0.05);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.05);box-shadow:0 1px 0 rgba(0,0,0,0.05)}.ui-button.transparent .ui-button-text{padding:0 10px}.ui-button.ui-plain-button:focus,.ui-button.ui-plain-button:hover{border-color:#e0e0e0;border-top-color:#e7e7e7;border-bottom-color:#ddd;background:#e7e7e7;background:-webkit-gradient(linear,left top,left bottom,from(#e7e7e7),to(#ddd));background:-moz-linear-gradient(#e7e7e7,#ddd);background:-webkit-linear-gradient(#e7e7e7,#ddd);-moz-box-shadow:0 0 transparent;-webkit-box-shadow:0 0 transparent;box-shadow:0 0 transparent}.ui-button.ui-plain-button:active,.ui-custom-active.ui-plain-button:focus,.ui-custom-active.ui-plain-button:hover,.ui-custom-active.ui-plain-button{border-color:#b2b2b2;border-top-color:#b7b7b7;border-bottom-color:#a8a8a8;background:#b7b7b7;background:-webkit-gradient(linear,left top,left bottom,from(#b7b7b7),to(#a8a8a8));background:-moz-linear-gradient(#b7b7b7,#a8a8a8);background:-webkit-linear-gradient(#b7b7b7,#a8a8a8);-moz-box-shadow:0 0 transparent;-webkit-box-shadow:0 0 transparent;box-shadow:0 0 transparent}.ui-button.selected,.ui-button.selected:focus,.ui-button.selected:active,.ui-button.selected:hover,.ui-state-focus.selected,.ui-state-hover.selected{background-image:url(../images/buttons/ui-button.png);background-position:left -80px;border-color:#404e69;background-color:#536587}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;width:16px;height:16px}.ui-button-medium .ui-icon{width:24px;height:24px;margin-left:4px}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon,.ui-button .spinner{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{position:static;margin-top:0;float:left}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-button-icons-only .ui-icon{margin-left:0!important}.ui-icon-menu{background-image:url(../images/buttons/btn_popup_sort.png);background-position:right 7px}.ui-icon-add{background-image:url("../images/icons/ico_add.png");background-position:center center}.ui-icon-addressbook{background-image:url("../images/buttons/addressBook.png");background-position:left center}.ui-icon-addressbook:hover{background-position:-22px center}.ui-icon-grid-view{background-image:url("../images/icons/ico_view_modes.png");margin-top:-7px!important}.selected .ui-icon-grid-view{background-position:0 -25px}.ui-icon-list-view{background-image:url("../images/icons/ico_view_modes.png");background-position:-24px 0;margin-top:-7px!important}.selected .ui-icon-list-view{background-position:-23px -25px}.ui-icon-upload{background-image:url(../images/buttons/upload.png);margin-left:4px;margin-right:-4px;height:17px!important;margin-top:3px!important}.ui-icon-new-folder{background-image:url(../images/buttons/new_folder.png);background-position:left bottom;margin-left:3px;margin-right:-3px;margin-top:3px!important;height:18px!important;width:18px!important}.ui-icon-back{background-image:url('../images/buttons/back_button.png');background-position:8px 0;margin-top:2px!important}.ui-icon-empty-trash{background-image:url(../images/buttons/empty_trash.png);height:18px!important;width:18px;margin-left:5px;margin-top:3px!important}.ui-icon-drop-down{background-image:url(../images/buttons/btn_drop_down.png);background-position:50% 6px}.ui-icon-up-button{background-image:url(../images/icons/ico_up_button.png);background-position:2px 1px}.ui-icon-comment{background-image:url("../images/icons/ico_comment.png");background-position:center center}.ie7 .ui-icon-comment,.ie9 .ui-icon-comment{margin-top:-7px!important}.ie8 .ui-icon-comment{margin-top:-9px!important}.ui-icon-comment+.ui-button-text{height:19px}.ui-icon-actions{background-image:url("../images/buttons/btn_file_actions.png");background-position:-20px 0;width:16px!important;height:17px!important;left:4px}.ui-icon-categories{background-image:url("../images/buttons/btn_file_actions.png");background-position:-40px 0;width:18px!important;height:18px!important;left:3px;margin-top:-8px!important}.ui-icon-comments{background-image:url("../images/buttons/btn_file_actions.png");background-position:-100px -41px;width:18px;margin-left:3px;margin-top:4px!important}.ui-icon-actions-big{background-image:url("../images/buttons/btn_file_actions.png");background-position:-20px 0;width:16px!important;height:17px!important;left:4px!important;top:3px!important;position:relative!important}.ui-icon-categories-big{background-image:url("../images/buttons/btn_file_actions.png");background-position:-40px 0;width:18px!important;height:18px!important;left:3px!important;top:3px!important;position:relative!important}.ui-button.ui-button-text-icon-primary .ui-button-text{padding-left:5px;vertical-align:middle}.ui-button-medium.ui-button.ui-button-text-icon-primary .ui-button-text{padding-left:4px;line-height:28px}.ui-button.ui-button-text-icon-secondary .ui-button-text{padding-right:16px}.ui-button.with_spinner{padding-left:6px}.ui-button .spinner{margin-top:-11px}.ui-icon-wrench{background:url('../images/buttons/wrench.png') no-repeat 0 0;left:4px!important}.ui-menu{display:block;float:left;list-style:none outside none;margin:0;padding:0}.ui-autocomplete{border:1px solid #666;border-top:0 none;background-color:white}.ui-menu .ui-menu-item{clear:left;float:left;margin:0;padding:0;width:100%;overflow:hidden}.ui-autocomplete .ui-menu-item a{display:block;padding:5px;cursor:pointer}.ui-autocomplete .ui-menu-item a:focus,.ui-autocomplete .ui-menu-item a:hover,.ui-autocomplete .ui-menu-item a.ui-state-hover{color:#222;background-position:top left}.ui-autocomplete .ui-menu-item a.ui-state-hover{background:#f2f2f2}#fancybox-loading{position:fixed;top:50%;left:50%;width:40px;height:40px;margin-top:-20px;margin-left:-20px;cursor:pointer;overflow:hidden;z-index:1104;display:none}#fancybox-loading div{position:absolute;top:0;left:0;width:40px;height:480px;background-image:url('../images/layout/fancybox/fancybox.png')}#fancybox-overlay{position:absolute;top:0;left:0;width:100%;z-index:1100;display:none}#fancybox-tmp{padding:0;margin:0;border:0;overflow:auto;display:none}#fancybox-wrap{position:absolute;top:0;left:0;padding:20px;z-index:1101;outline:0;display:none}#fancybox-outer{position:relative;width:100%;height:100%;background:#fff}#fancybox-content{width:0;height:0;padding:0;outline:0;position:relative;overflow:hidden;z-index:1102;border:0 solid #fff}#fancybox-hide-sel-frame{position:absolute;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1101}#fancybox-close{position:absolute;top:-15px;right:-15px;width:30px;height:30px;background:transparent url('../images/layout/fancybox/fancybox.png') -40px 0;cursor:pointer;z-index:1103;display:none}#fancybox-error{color:#444;font:normal 12px/20px Arial;padding:14px;margin:0}#fancybox-img{width:100%;height:100%;padding:0;margin:0;border:0;outline:0;line-height:0;vertical-align:top}#fancybox-frame{width:100%;height:100%;border:0;display:block}#fancybox-left,#fancybox-right{position:absolute;bottom:0;height:100%;width:35%;cursor:pointer;outline:0;background:transparent url('../images/layout/fancybox/blank.gif');z-index:1102;display:none}#fancybox-left{left:0}#fancybox-right{right:0}#fancybox-left-ico,#fancybox-right-ico{position:absolute;top:50%;left:-9999px;width:30px;height:30px;margin-top:-15px;cursor:pointer;z-index:1102;display:block}#fancybox-left-ico{background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -30px}#fancybox-right-ico{background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -60px}#fancybox-left:hover,#fancybox-right:hover{visibility:visible}#fancybox-left:hover span{left:20px}#fancybox-right:hover span{left:auto;right:20px}.fancybox-bg{position:absolute;padding:0;margin:0;border:0;width:20px;height:20px;z-index:1001}#fancybox-bg-n{top:-20px;left:0;width:100%;background-image:url('../images/layout/fancybox/fancybox-x.png')}#fancybox-bg-ne{top:-20px;right:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -162px}#fancybox-bg-e{top:0;right:-20px;height:100%;background-image:url('../images/layout/fancybox/fancybox-y.png');background-position:-20px 0}#fancybox-bg-se{bottom:-20px;right:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -182px}#fancybox-bg-s{bottom:-20px;left:0;width:100%;background-image:url('../images/layout/fancybox/fancybox-x.png');background-position:0 -20px}#fancybox-bg-sw{bottom:-20px;left:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -142px}#fancybox-bg-w{top:0;left:-20px;height:100%;background-image:url('../images/layout/fancybox/fancybox-y.png')}#fancybox-bg-nw{top:-20px;left:-20px;background-image:url('../images/layout/fancybox/fancybox.png');background-position:-40px -122px}#fancybox-title{font-family:Helvetica;font-size:12px;z-index:1102}.fancybox-title-inside{padding-bottom:10px;text-align:center;color:#333;background:#fff;position:relative}.fancybox-title-outside{padding-top:10px;color:#fff}.fancybox-title-over{position:absolute;bottom:0;left:0;color:#FFF;text-align:left}#fancybox-title-over{padding:10px;background-image:url('../images/layout/fancybox/fancy_title_over.png');display:block}.fancybox-title-float{position:absolute;left:0;bottom:-20px;height:32px}#fancybox-title-float-wrap{border:0;border-collapse:collapse;width:auto}#fancybox-title-float-wrap td{border:0;white-space:nowrap}#fancybox-title-float-left{padding:0 0 0 15px;background:url('../images/layout/fancybox/fancybox.png') -40px -90px no-repeat}#fancybox-title-float-main{color:#FFF;line-height:29px;font-weight:bold;padding:0 0 3px 0;background:url('../images/layout/fancybox/fancybox-x.png') 0 -40px}#fancybox-title-float-right{padding:0 0 0 15px;background:url('../images/layout/fancybox/fancybox.png') -55px -90px no-repeat}.fancybox-ie6 #fancybox-close{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_close.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-left-ico{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_nav_left.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-right-ico{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_nav_right.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-title-over{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_over.png',sizingMethod='scale');zoom:1}.fancybox-ie6 #fancybox-title-float-left{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_left.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-title-float-main{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_main.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-title-float-right{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_title_right.png',sizingMethod='scale')}.fancybox-ie6 #fancybox-bg-w,.fancybox-ie6 #fancybox-bg-e,.fancybox-ie6 #fancybox-left,.fancybox-ie6 #fancybox-right,#fancybox-hide-sel-frame{height:expression(this.parentNode.clientHeight+"px")}#fancybox-loading.fancybox-ie6{position:absolute;margin-top:0;top:expression((-20+(document.documentElement.clientHeight ? document.documentElement.clientHeight/2:document.body.clientHeight/2)+(ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop:document.body.scrollTop))+'px')}#fancybox-loading.fancybox-ie6 div{background:transparent;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_loading.png',sizingMethod='scale')}.fancybox-ie .fancybox-bg{background:transparent!important}.fancybox-ie #fancybox-bg-n{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_n.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-ne{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_ne.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-e{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_e.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-se{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_se.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-s{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_s.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-sw{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_sw.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-w{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_w.png',sizingMethod='scale')}.fancybox-ie #fancybox-bg-nw{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/layout/fancybox/fancy_shadow_nw.png',sizingMethod='scale')}.jcarousel-skin-tango .jcarousel-container{background:#FFF;border:1px solid #cecece;-moz-border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.jcarousel-skin-tango .jcarousel-item.jcarousel-item-horizontal.jcarousel-item-selected{border:solid 2px #09c}.jcarousel-skin-tango .jcarousel-container-horizontal{padding:15px 23px 15px 22px}.jcarousel-skin-tango .jcarousel-clip{overflow:hidden}.jcarousel-skin-tango .jcarousel-clip-horizontal{height:90px;width:843px}.jcarousel-skin-tango .jcarousel-item{width:93px;height:70px}.jcarousel-skin-tango .jcarousel-item-horizontal{margin:0 10px;padding:3px;border:solid 1px #ccc;background:#fafafa}.jcarousel-skin-tango .jcarousel-item-horizontal:hover,.jcarousel-skin-tango .jcarousel-item-horizontal:focus{padding:2px;border:solid 2px #bfbfbf}.jcarousel-skin-tango .jcarousel-direction-rtl .jcarousel-item-horizontal{margin-left:10px;margin-right:0}.jcarousel-skin-tango .jcarousel-item-vertical{margin-bottom:10px}.jcarousel-skin-tango .jcarousel-item-placeholder{background:#fff;color:#000}.jcarousel-skin-tango .jcarousel-next-horizontal{position:absolute;top:32px;right:5px;width:12px;height:16px;cursor:pointer;background:transparent url(../images/icons/carousel/icon_slideshow_triangle.png) no-repeat 0 -60px}.jcarousel-skin-tango .jcarousel-next-horizontal:hover,.jcarousel-skin-tango .jcarousel-next-horizontal:focus,.jcarousel-skin-tango .jcarousel-next-horizontal:active{background-position:0 -100px}.jcarousel-skin-tango .jcarousel-next-disabled-horizontal,.jcarousel-skin-tango .jcarousel-next-disabled-horizontal:hover,.jcarousel-skin-tango .jcarousel-next-disabled-horizontal:focus,.jcarousel-skin-tango .jcarousel-next-disabled-horizontal:active{cursor:default;background:0}.jcarousel-skin-tango .jcarousel-prev-horizontal{position:absolute;top:32px;left:5px;width:12px;height:16px;cursor:pointer;background:transparent url(../images/icons/carousel/icon_slideshow_triangle.png) no-repeat 0 0}.jcarousel-skin-tango .jcarousel-prev-horizontal:hover,.jcarousel-skin-tango .jcarousel-prev-horizontal:focus,.jcarousel-skin-tango .jcarousel-prev-horizontal:active{background-position:0 -40px}.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal,.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal:hover,.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal:focus,.jcarousel-skin-tango .jcarousel-prev-disabled-horizontal:active{cursor:default;background:0}.about_contents div,.about_contents span,.about_contents object,.about_contents p,.about_contents strong,.about_contents ul,.about_contents li,.about_contents label,.about_contents header,.about_contents section{background:none repeat scroll 0 0 transparent;border:0 none;font-size:100%;margin:0;outline:0 none;padding:0;vertical-align:baseline}.about_contents{width:500px}.about_contents header{background-color:#000;height:28px;border-radius:6px 6px 0 0;border-bottom:1px solid #333;color:#fff;font-size:13px;font-weight:bold;padding:10px 0 0 10px}.about_contents .about_banner{background:url("../images/layout/Exchangebanner.png") no-repeat scroll 0 0 transparent;height:74px}.about_contents .about_banner p{font-size:16px;color:#fff;text-shadow:0 2px 2px rgba(0,0,0,0.65);width:344px;padding-top:18px;padding-left:30px}.about_contents .about_content{height:212px;overflow-y:scroll;overflow-x:hidden;background-color:#eee;font-size:9px;color:#2a2a2a}.about_contents .margin_top{height:20px;left:0;position:absolute;right:0;top:113px;width:483px;background-color:#eee}.about_contents .margin_bottom{bottom:0;height:15px;left:0;position:absolute;right:0;width:483px;border-bottom:20px solid #eee;background:-webkit-gradient(linear,left top,left bottom,from(rgba(238,238,238,0)),to(rgba(238,238,238,1)));background:-webkit-linear-gradient(rgba(238,238,238,0),rgba(238,238,238,1));background:-moz-linear-gradient(rgba(238,238,238,0),rgba(238,238,238,1));background:-ms-linear-gradient(rgba(238,238,238,0),rgba(238,238,238,1))}.no-cssgradients .about_contents .margin_bottom{background:url("../images/layout/about_box_gradient_fade.png") repeat-x 0 0 transparent}.about_contents div.about_terms{margin-left:15px;margin-right:20px;padding-top:20px}.about_contents .about_terms p{margin-bottom:15px}.about_contents .about_terms p a{color:#06e}.about_contents .about_wrapper{padding-bottom:30px}.no_border{border:0!important;border-radius:6px 6px 0 0!important}.dropdown,.dropdown div,.dropdown li,.dropdown div::after{-webkit-transition:all 150ms ease-in-out;-moz-transition:all 150ms ease-in-out;-ms-transition:all 150ms ease-in-out;transition:all 150ms ease-in-out}.dropdown .selected::after,.dropdown.scrollable div::after{-webkit-pointer-events:none;-moz-pointer-events:none;-ms-pointer-events:none;pointer-events:none}.dropdown{position:relative;width:200px;border:1px solid #ccc;cursor:pointer;background:#fff;border-radius:3px;-webkit-user-select:none;-moz-user-select:none;user-select:none}.dropdown.open{z-index:2}.dropdown:hover{box-shadow:0 0 5px rgba(82,168,236,0.8);border:solid 1px #52a8ec}.dropdown.focus{box-shadow:0 0 5px rgba(51,102,248,.4)}.dropdown .carat{position:absolute;right:12px;top:50%;margin-top:-4px;border:6px solid transparent;border-top:8px solid #000}.dropdown.open .carat{margin-top:-10px;border-top:6px solid transparent;border-bottom:8px solid #000}.dropdown.disabled .carat{border-top-color:#999}.dropdown .old{position:absolute;left:0;top:0;height:0;width:0;overflow:hidden}.dropdown select{position:absolute;left:0;top:0}.dropdown.touch .old{width:100%;height:100%}.dropdown.touch select{width:100%;height:100%;opacity:0}.dropdown .selected,.dropdown li{display:block;font-size:12px;line-height:1;color:#000;padding:9px 12px;overflow:hidden;white-space:nowrap}.dropdown.disabled .selected{color:#999}.dropdown .selected::after{content:'';position:absolute;right:0;top:0;bottom:0;width:60px;border-radius:0 2px 2px 0;box-shadow:inset -55px 0 25px -20px #fff}.dropdown div{position:absolute;height:0;left:-1px;right:-1px;top:100%;margin-top:-1px;background:#fff;border:1px solid #ccc;border-top:1px solid #eee;border-radius:0 0 3px 3px;overflow:hidden;opacity:0}.dropdown.open div{opacity:1;z-index:2}.dropdown.scrollable div::after{content:'';position:absolute;left:0;right:0;bottom:0;height:50px;box-shadow:inset 0 -50px 30px -35px #fff}.dropdown.scrollable.bottom div::after{opacity:0}.dropdown ul{position:absolute;left:0;top:0;height:100%;width:100%;list-style:none;overflow:hidden}.dropdown.scrollable.open ul{overflow-y:auto}.dropdown li{list-style:none;padding:8px 12px}.dropdown li.focus{background:#d24a67;position:relative;z-index:3;color:#fff}.dropdown li.active{font-weight:700}.bootstrap-tagsinput{display:inline-block;padding-right:6px;color:#555;vertical-align:middle;border-radius:4px;max-width:200px;line-height:22px;position:relative;top:-1px}.bootstrap-tagsinput input{display:none;border:0;box-shadow:none;background-color:transparent;padding:0;margin:0;width:auto!important;max-width:inherit}.bootstrap-tagsinput input:focus{border:0;box-shadow:none}.bootstrap-tagsinput .tag{margin-right:2px;color:#666;padding:5px 5px 5px 5px;font-size:12px;background:white;text-shadow:none;font-weight:lighter}.bootstrap-tagsinput .tag [data-role="remove"]{margin-left:2px;cursor:pointer;font-size:15px;color:#aaa;position:relative;top:0}.bootstrap-tagsinput .tag [data-role="remove"]:after{content:"| x";padding:0 2px}.bootstrap-tagsinput .tag [data-role="remove"]:hover{box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.bootstrap-tagsinput .tag [data-role="remove"]:hover:active{box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.search-page span{font-family:Arial;color:#666}.search-page a{font-size:12px;color:#29abe2}.overview-title{min-width:1220px}.search-page .overview-title{border-bottom:1px solid #CCC;font-size:16px;height:36px;left:0;padding:10px 0 6px 0;-moz-box-align:initial;-moz-box-pack:initial;-ms-flex-align:start;-webkit-box-pack:initial;-webkit-box-align:baseline;-ms-flex-pack:inherit}.overview-title>div>a{font-size:16px;font-weight:bold;color:#666}.overview-title div:first-child{padding-top:7px;margin-left:30px}.overview-title .emphasized{font-weight:bold;color:#333}.overview-title .view-selection input{display:none}.overview-title .view-selection input+label{padding:0}.overview-title .view-selection input:checked+label{background:#DDD;border-radius:5px}.search-page .list-display-options{height:50px;left:0;-moz-box-align:initial;-ms-flex-align:start;position:relative}.widget-element-app-search-list-view.widget-hoverable{width:auto;height:auto}.widget-element-app-search-list-view{padding:15px 10px;border:1px solid #e3e3e3;width:initial}.widget-element-app-search-list-view:nth-child(2n){margin-left:-5px}.widget-element-app-search-list-view:nth-child(n+2){margin-top:-5px}.list-display-options .list-display-option-left{left:0;margin-top:18px;position:absolute}.list-display-option-left span{color:#29abe2}.list-header-fancy .list-display-options .list-display-option-left{margin-top:0}.list-display-options .list-display-option-right{position:absolute;right:0;margin-top:10px;display:block;align-items:baseline;width:auto;min-width:400px;text-align:right}.list-display-option-right span{color:#29abe2}.list-display-option-right .dropdown{width:50px;height:24px;float:right;margin-left:4px;text-align:left;border:1px solid #b3b3b3;border-radius:3px}.list-display-option-right .dropdown .selected{padding:6px}.list-display-option-right .dropdown .selected::after{box-shadow:none}.list-display-options input{width:16px;margin-bottom:0;height:16px;border:1px solid #b3b3b3}.list-display-options select{width:70px}.list-display-options span{font-size:12px}.filter-catalog-container{width:200px;margin-right:5px}a.filter-catalog-show-more{color:#808080}.filter-catalog-seperator{height:1px;background:#AAA}.filter-catalog span{width:120px;flex-shrink:0;-webkit-flex-shrink:0;-ms-flex:0 0 auto;font-size:12px;padding-right:5px}.filter-title label{height:24px;width:16px;padding:0;border:0}.filter-catalog label[class="radio"]{margin-right:25px}.filter-catalog .radio{position:relative;bottom:1px;font-size:12px;display:inline-block}.filter-catalog input{position:absolute;left:0;top:-1px}.filter-catalog .filter-catalog-item label{font-size:12px}.filter-catalog .filter-title{margin-top:20px;margin-bottom:5px}.filter-catalog .filter-title span{font-size:14px;color:#29abe2}.filter-catalog .filter-catalog-item{line-height:20px;position:relative;padding-left:20px;margin-bottom:5px;color:#808080;font-size:12px}.filter-catalog-container .filter-tag-input{margin-top:10px}.filter-catalog-container .bootstrap-tagsinput .tag{margin-top:5px;margin-right:5px;background:#29abe2;color:white;white-space:normal}.bootstrap-tagsinput .tag [data-role="remove"]{color:white}.bootstrap-tagsinput .tag [data-role="remove"]:after{content:"x"}#clear-all-tags{margin-top:6px;display:inline-block}.view-selection{float:right;margin-right:3px}.view-selection input{width:0;height:0;visibility:collapse}.view-selection .btn{padding:0;height:24px;width:24px;border:0}.search-page span.message-with-link{color:#29abe2}.show_all{cursor:pointer;color:#369} html,body{background-color:#f8f8f8}.bold{font-weight:bold}.float-left{float:left}.float-right{float:right}.busy{cursor:progress}.hidden{display:none}body a{cursor:pointer}body a:focus{outline:0}.min-size{min-width:975px}.clear{clear:both;display:block;overflow:hidden;visibility:hidden;width:0;height:0}.highlight-text{color:#29abe2!important}.display-table{display:table!important}.display-table .row{display:table-row!important}.display-table .cell{display:table-cell!important}.text-center-align-container{text-align:center}.text-right-align-container{text-align:right}.vertical-top-align-container>*{vertical-align:top}.vertical-middle-align-container>*{vertical-align:middle}.vertical-bottom-align-container>*{vertical-align:bottom}.inline-container>*{display:inline-block}.inline{display:inline}.inline-block{display:inline-block}.block{display:block!important}.message-with-link,.message-with-link a{font-size:12px;color:#29abe2}.message-with-link a{font-weight:normal;text-decoration:underline!important}.thin-border{border:solid 1px #CCC}.color-blue1{color:#29abe2}a.flat-button:visited,.flat-button{color:white;width:auto;text-align:center;font-size:14px;border-radius:6px;border:0;padding:4px 20px;margin:1px;-webkit-transition:opacity .8s;-moz-transition:opacity .8s;-o-transition:opacity .8s;transition:opacity .8s;display:inline-block}.flat-button-slim{font-size:12px;line-height:14px}.flat-button[disabled]{opacity:.5}.flat-button[disabled]:hover{cursor:not-allowed;opacity:.5}.flat-button:hover{color:white;cursor:pointer;opacity:.8;-webkit-transition:opacity .2s;-moz-transition:opacity .2s;-o-transition:opacity .2s;transition:opacity .2s}.flat-button:active{opacity:1}.flat-button.flat-button-normal{background:#29abe2}.flat-button.app-os-lang-btn{background:#dcdcdc}.flat-button.flat-button-emphasis{background:#0071bc}.flat-button.flat-button-radio{min-width:100px}.flat-button.flat-button-radio input[type=radio]{display:none;border-radius:0}.flat-button.flat-button-radio input:checked+span{background:#29abe2;color:white;border-color:transparent}.flat-button.flat-button-radio input+span{background:#f2f2f2;display:inline-block;color:black;min-width:100px;padding:7px 15px;border:1px #ccc solid;width:100%}.flat-button.flat-button-group{width:100%;background:#e6e6e6;color:black;border-radius:0;border:1px #b8b8b8 solid;margin:5px 5px;padding:5px 3px}.flat-button.flat-button-group-active{background:#29abe2;color:white;border-radius:0;border-style:none}.flat-button.flat-button-positive{background:#77bb68}.flat-button.flat-button-negative{color:#29abe2;background:white;border:1px #29abe2 solid}.flat-button.flat-button-warning{background:#fcb237}.table{color:#595959;font-size:12px}.table .color-bar-left{border-left:5px solid #e6e6e6}.color-bar-right{display:inline-block;width:5px!important;padding:0!important;height:20px;right:30px;position:relative}.table th,.table td{padding:5px 10px;border:0;vertical-align:middle;text-align:center}.table.left-align th,.table.left-align td{text-align:left}.table td:first-child~td{border-left:solid 1px #e6e6e6}.table th{background:#e6e6e6}.table th .order-arrow{float:right;color:#4d4d4d;display:block}.table th .order-arrow.up:after{content:"▴"}.table th .order-arrow.down:after{content:"▾"}.table tr{border-bottom:solid 1px #29abe2;background:white}.table .show-all:hover~div{visibility:visible}.table .show-all-container{border:solid 1px #29abe2;background:white;position:absolute;padding:5px 10px;visibility:hidden}.table .show-all-container ul{padding:0;margin:0}.table .show-all-container ul li{padding:3px}.table .show-all-container i{display:block;background:url(../images/icons/dialog-arrow.png) no-repeat;width:15px;height:6px;position:absolute;top:-6px;left:23px}a{text-decoration:none!important}h1,h2,h3,h4,h5,h6{font-weight:bold;font-size:100%;margin:0;padding:0;line-height:normal}ul,ol,li,dl,dd,dt{list-style:none}li{line-height:normal}.nomarginpadding{margin:0;padding:0}.detail-main .description ul,.developer-submit-product ul,.helpdoc-page ul,.detail-main .description ol,.developer-submit-product ol,.helpdoc-page ol{padding-left:17px}.detail-main .description ul li,.developer-submit-product ul li,.helpdoc-page ul li{list-style:disc}.detail-main .description ol li,.developer-submit-product ol li,.helpdoc-page ol li{list-style:decimal}.details-main .seller{float:left}body,button,input,select,textarea{font-family:Arial,Verdana,Sans-Serif}.overlay_text{color:#999;line-height:18px;font-weight:normal!important;position:absolute;cursor:text!important;text-shadow:none!important}.spinner{width:16px;height:16px;background:url(../images/icons/spinner_16.png) no-repeat left top}.spinned{display:none!important}.spinner_container{padding-left:20px;line-height:24px;position:relative;cursor:wait;white-space:nowrap;display:inline-block}.spinner_container .spinner{position:absolute;top:4px;left:0}.popup_menu.flat_menu .spinner_container{padding-left:25px;padding-right:3px}.popup_menu.flat_menu .spinner_container .spinner{left:5px}.local_spinner{padding-left:31px}.local_spinner .spinner{left:9px}.line-separator{height:1px;width:100%;background:#CCC;margin:6px 0 6px 0}.sub-title{font-size:12px;color:black;display:inline-block}#flash_message{z-index:11203;position:fixed;left:50%;padding:11px 30px 9px 50px;color:#fff;font-size:14px;cursor:default;text-shadow:0 1px 0 #000;text-shadow:0 1px 0 rgba(0,0,0,0.85);border:1px solid #75a3ff;border-color:rgba(117,163,255,0.7);background-color:#1e3559;background:-webkit-gradient(linear,left top,left bottom,from(#1e3559),to(#172944));background:-webkit-linear-gradient(#1e3559,#172944);background:-moz-linear-gradient(#1e3559,#172944);-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#flash_message img,#flash_message .spinner{position:absolute;left:26px;top:13px}#flash_message #off_button_div{width:24px;height:24px;position:absolute;right:5px;top:8px;background-image:url(../images/buttons/close_24.png);cursor:pointer}#flash_message.success{background:#1e3559 url(../images/icons/flash_success.png) no-repeat 26px 13px;background:url(../images/icons/flash_success.png) no-repeat 26px 13px,-webkit-gradient(linear,left top,left bottom,from(#1e3559),to(#172944));background:url(../images/icons/flash_success.png) no-repeat 26px 13px,-webkit-linear-gradient(#1e3559,#172944);background:url(../images/icons/flash_success.png) no-repeat 26px 13px,-moz-linear-gradient(#1e3559,#172944)}#flash_message.error{background:#1e3559 url(../images/icons/error_16.png) no-repeat 26px 13px;background:url(../images/icons/error_16.png) no-repeat 26px 13px,-webkit-gradient(linear,left top,left bottom,from(#1e3559),to(#172944));background:url(../images/icons/error_16.png) no-repeat 26px 13px,-webkit-linear-gradient(#1e3559,#172944);background:url(../images/icons/error_16.png) no-repeat 26px 13px,-moz-linear-gradient(#1e3559,#172944)}.header-icon{width:18px!important;height:23px!important;margin:0 10px 0 5px!important;position:relative;top:-4px}.icon-my-downloads{background:url('../images/icons/mydownloads_idle.png') no-repeat!important}li.disabled .icon-my-downloads{background:url('../images/icons/mydownloads_disabled.png')!important}li:hover .icon-my-downloads{background:url('../images/icons/mydownloads_hover.png') no-repeat!important}.icon-my-uploads{background:url('../images/icons/myuploads_idle.png') no-repeat!important}li.disabled .icon-my-uploads{background:url('../images/icons/myuploads_disabled.png') no-repeat!important}li:hover .icon-my-uploads{background:url('../images/icons/myuploads_hover.png') no-repeat!important}.main-middle-content{width:1280px;margin-left:auto;margin-right:auto;margin-top:15px;display:flex;padding-bottom:15px}.left-mainmiddlecontent{width:190px;margin-right:15px;float:left}.navigation-content .navigation-header,.filter-catalog-container .filter-catalog-title{border:1px solid #d3d3d3;min-height:30px;text-align:center;line-height:30px;background:#e6e6e6;font-size:18px;color:#4d4d4d}.navigation-content .navigation-a{position:relative;margin:0;padding:0}.dropdown-menu-store,.navigation-content .navigation-a .popover{min-width:190px}.navigation-content li{text-align:left;min-height:25px;line-height:24px;color:#808080}.first-a{margin-left:35px}.sub-a{margin-left:5px}.second-a{margin-left:5px}.navigation-content .navigation-a-li{border-bottom:1px solid #838383;position:relative}.navigation-content li:hover{background:#29abe2;color:White}.navigation-content li a{font-size:12px;color:inherit}.navigation-content .btn-group .dropdown-toggle{width:189px}.apps-wrapper{margin:0 auto}.right-mainmiddlecontent{min-height:500px;width:1050px;padding-left:14px;float:left;border-left:1px solid #b3b3b3}.apps-content .apps-section .show-all{float:right;font-size:13px;text-decoration:none}.apps-section h2{margin-bottom:10px;margin-top:10px;color:#777;line-height:40px;font-size:24px;font-family:Arial}.apps-content .apps-carousel{width:1051px;padding:10px 0}.apps-content .apps-carousel h2{margin-bottom:12px}.apps-content .apps-carousel-box{float:left}.short-carousel-wrapper .apps-carousel-box{width:525px}.long-carousel-wrapper .apps-carousel-box{width:100%}.apps-carousel .apps-carousel-box .carousel .carousel-item-ul{margin:0;padding:0}.short-carousel-wrapper .apps-carousel-box-not-first h2{margin-left:10px}.widget-title{height:40px;overflow:hidden;text-overflow:ellipsis}ul.apps-list .s-price-cont{float:left!important;height:18px}ul.apps-list .s-price-cont>span.price,ul.apps-list .s-price-cont .sr-subscriberonly{color:#29abe2!important;font-size:12px!important}ul.apps-list .badge-hover-stub div{text-align:left}ul.apps-list li{background-color:rgba(255,255,255,0.7);cursor:pointer}ul.apps-list li:hover,#result-list .widget-element-app-layout:hover{-moz-box-shadow:0 0 5px rgba(170,170,170,0.4);-webkit-box-shadow:0 0 5px rgba(170,170,170,0.4);-ms-box-shadow:0 0 5px rgba(170,170,170,0.4);box-shadow:0 0 5px rgba(170,170,170,0.4);background-color:rgba(255,255,255,1)}ul.apps-list li img,ul.apps-list li .product-data-container{float:left}ul.apps-list li .product-data-container{padding-left:10px;width:90px}ul.apps li.small-widget-element .product-data-container{max-width:85px}ul.apps li.middle-widget-element .product-data-container{max-width:128px}ul.apps li.large-widget-element .product-data-container{max-width:110px}ul.apps-list li .product-data-container .seller{color:grey}ul.apps-list li.large-widget-element .product-data-container .seller{font-size:11px;height:17px}ul.apps-list li.middle-widget-element .product-data-container .seller,ul.apps-list li.small-widget-element .product-data-container .seller{font-size:12px;height:14px;line-height:13px}ul.apps-list li.small-widget-element .product-data-container .product-rating-small{margin:0}ul.apps-list li .product-data-image{float:left}ul.apps-list li.large-widget-element{width:260px;height:90px}ul.apps-list li.middle-widget-element{width:208px}ul.apps-list li.small-widget-element{width:165px;height:72px}.apps-section-middle ul.apps-list li.small-widget-element{margin:12px 12px 0}.apps-content .apps-section-last{margin-bottom:0;padding-bottom:27px}ul.apps-list li.large-widget-element .product-data-image{margin-left:5px}ul.apps-list li.middle-widget-element .product-data-image,ul.apps-list li.small-widget-element .product-data-image{margin-left:3px}ul.apps-list li h3{color:#444;font-weight:bold;font-family:Arial}ul.apps-list li .product-comment{margin:0;font-size:12px;width:13px!important}ul.apps-list li.large-widget-element h3{line-height:14px;font-size:12px;color:#4d4d4d;height:30px}ul.apps-list li.middle-widget-element h3,ul.apps-list li.small-widget-element h3{line-height:15px;font-size:12px}ul.apps-list li.large-widget-element .ellipsis{width:160px!important}ul.apps-list li.middle-widget-element .ellipsis{width:125px!important}ul.apps-list li.small-widget-element .ellipsis{width:85px!important}ul.apps-list li.large-widget-element h3.ellipsis{white-space:normal!important}ul.apps-list .product-data-image img{-o-border-radius:5px;-ms-border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;border:1px solid #e3e3e3}ul.apps-list li.large-widget-element img{width:80px;height:80px}ul.apps-list li.middle-widget-element img,ul.apps-list li.small-widget-element img{width:60px;height:60px}.long-carousel-wrapper #carousel-slider-widget-layout-0{padding-right:0}.short-carousel-wrapper #carousel-slider-widget-layout-1{padding-left:5px;border-left:1px solid #ccc}.long-carousel-wrapper #carousel-slider-widget-layout-1{padding-left:0}.short-carousel-wrapper .carousel-slider-widget-sub-layout{width:525px}.long-carousel-wrapper .carousel-slider-widget-sub-layout{width:1030px}.carousel-slider-widget{margin:0 13px 0 12px}.carousel-slider-widget .carousel-inner{overflow:visible}.carousel-slider-widget .carousel-inner .item{height:auto;overflow:visible}.carousel-slider-widget .carousel-control{top:55%!important;width:12px!important;height:20px!important;background-position:center!important;background-repeat:no-repeat!important}.carousel-slider-widget .left.carousel-control{left:-15px;background:url('../images/buttons/Arrow_Left.png')}.carousel-slider-widget .right.carousel-control{right:-15px;background:url('../images/buttons/Arrow_Right.png')}.carousel-slider-widget .carousel-item-ul{float:left}.apps-list-big .widget-element-app-content{height:80px}#header #base{max-width:1205px;min-width:1110px;padding:4px 0;margin:0 auto}#header .branding{color:#CCC;text-decoration:none;float:left;position:relative;top:7px;line-height:16px;border:0}#header .branding h1{margin:0;padding:0;line-height:27px;font-size:22px}#header .language-changer{float:left;margin:10px 0 0 20px}#header .btn-group .dropdown-toggle:focus{outline:0}#header .dropdown-toggle{background-color:transparent;border:1px solid #ccc;box-shadow:none;-webkit-box-shadow:none;-moz-box-shadhow:none}#header .language-changer .dropdown-menu>li:hover{background-color:#0081c2}#header .language-changer .dropdown-menu{border-radius:6px;-webkit-border-radius:6px;-moz-border-radius:6px}#logged_user_name{cursor:default;padding-right:10px;color:#29abe2;background:url("../images/icons/menu_arrow_blue.png") no-repeat right center}nav.user-panel .signin_link{cursor:pointer;color:#29abe2}nav.user-panel .drop_down ul,#neck .drop_down ul{background-color:#000;background-color:rgba(0,0,0,0.75);border:1px solid #222;border-color:rgba(204,204,204,0.33);padding:5px 5px 3px;margin:0;white-space:nowrap;min-width:0;position:absolute;right:0;top:90%;z-index:9999;line-height:1.75;list-style-type:none;visibility:hidden}.product-info .drop_down ul{background-color:#f2f2f2;border-color:#555;border-style:solid;border-width:1px;padding:0 0 3px 0;margin-top:0;white-space:nowrap;min-width:0;position:absolute;z-index:9999;line-height:1.75;list-style-type:none;visibility:hidden}.product-info .drop_down .details_link{cursor:default;padding-right:10px;background:url(../images/buttons/btn_popup_sort.png) no-repeat right 7px}#neck .drop_down ul{left:0;top:25px;width:150px;background-color:#d7d7d7;border:1px solid #222;border-color:rgba(204,204,204,0.33);padding:5px;margin:0;white-space:nowrap;min-width:0;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;position:absolute;z-index:9999;line-height:1;list-style-type:none;visibility:hidden}nav.user-panel .drop_down ul li,#neck .drop_down ul li{padding-top:5px;padding-bottom:0;margin-top:5px;border-top:1px solid #383838;height:auto!important;line-height:normal!important}nav.user-panel .drop_down ul li:first-child,#neck .drop_down ul li:first-child{border:0 none;padding:0;margin:0}.product-info .drop_down ul li{padding-left:3px;padding-right:3px;padding-top:3px}.drop_down a{padding:0 5px;text-decoration:none;cursor:pointer}.product-info a.details_link,.product-info .drop_down{float:left}.product-info .drop_down a{padding-right:5px}nav.user-panel .drop_down a{display:block;line-height:22px!important;height:22px!important;font-size:12px;color:#fff!important;filter:alpha(opacity=100)!important;-moz-opacity:1!important;-khtml-opacity:1!important;opacity:1!important;padding:0;border:none!important}.product-info .drop_down a,#neck .drop_down a{display:block;line-height:22px;font-size:12px;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;color:#000!important}.product-info .drop_down a:hover{color:#fff!important}nav.user-panel .drop_down a:hover,.product-info .drop_down a:hover,#neck .drop_down a:hover{background:#29abe2}nav.user-panel li.drop_down:hover,#neck span.drop_down:hover{position:relative;z-index:599;cursor:default}.product-info .drop_down :hover{z-index:599;cursor:default}nav.user-panel li.drop_down:hover>ul,.product-info .drop_down:hover>ul,#neck span.drop_down:hover>ul{visibility:visible}.bannertext{left:250px;position:absolute;right:150px;text-align:center;top:11px;color:#dc0719;font-style:italic;overflow:hidden;white-space:nowrap}.error_page{margin:20px auto}#neck .neck-content{height:50px;width:100%;margin:auto;padding-top:15px}#neck .breadcrumb{float:left;padding:0;margin-right:10px;margin-left:20px;margin-bottom:0}#neck .breadcrumb>a,#neck .breadcrumb>span:not(.breadcrumb-divider){display:inline-block;vertical-align:-2px;font-size:20px}#neck .breadcrumb .breadcrumb-divider{color:#111}#neck .breadcrumb a:link,#neck .breadcrumb a:visited{color:#343434}#neck .breadcrumb a:hover,#neck .breadcrumb a:active{color:#06e}#neck .breadcrumb .home{display:inline-block;width:22px;height:22px;background:url(../images/icons/icon_home.svg) no-repeat;vertical-align:-4px}#neck .breadcrumb span.drop_down{padding:0 12px 0 10px}#neck .breadcrumb span span.arrow{background:url(../images/buttons/btn_popup_sort.png) no-repeat right 6px;padding:0 10px 0 0}#my-drafts .details_link,#my-drafts .details_link:hover,#my-drafts .details_link:active,#my-drafts .details_link:visited,#my-publishedlist .details_link,#my-publishedlist .details_link:hover,#my-publishedlist .details_link:active,#my-publishedlist .details_link:visited,#my-published .details_link,#my-published .details_link:hover,#my-published .details_link:active,#my-published .details_link:visited,#detail .app-benefit-notification a:focus{border:0;width:400px;text-align:left;word-wrap:break-word;outline-style:none}.navbar-toolbar #search-plugin{margin-top:9px}#search-plugin .dropdown{float:left}#fancybox-outer{padding:0;background:transparent;-ms-box-shadow:0 0 12px rgba(0,0,0,0.65);-moz-box-shadow:0 0 12px rgba(0,0,0,0.65);-webkit-box-shadow:0 0 12px rgba(0,0,0,0.65);box-shadow:0 0 12px rgba(0,0,0,0.65);-moz-background-clip:padding;-webkit-background-clip:padding;background-clip:padding-box}#fancybox-content{background:transparent;border:1px solid #5b5b5b;-moz-background-clip:padding;-webkit-background-clip:padding;background-clip:padding-box}#fancybox-close{top:10px;right:9px;width:13px;height:13px;background-image:url("../images/buttons/close_13.png");background-position:0 0}.license-add{top:10px;right:9px;width:13px;height:13px;background-image:url("../images/buttons/close_13.png");background-position:0 0;transform:rotate(45deg)}.license-remove{top:10px;right:9px;width:13px;height:13px;background-image:url("../images/buttons/close_13.png");background-position:0 0}#fancybox-close:focus,#fancybox-close:hover{background-position:0 bottom}.license-add:focus,.license-add:hover{background-position:0 bottom}.license-remove:focus,.license-remove:hover{background-position:0 bottom}.img-mask{position:absolute;left:0;top:0;width:100%;height:100%;background-color:rgba(255,255,255,0.7)}.overlay_window{background-color:#f5f5f5}.overlay_window>header{background-color:#e6e6e6;padding:0 10px;height:29px;position:relative}.overlay_window>header h1{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:14px;font-weight:normal;padding-top:6px}.overlay_window .body_container{border-top:solid 1px #cfcfcf;background-color:#fff}.overlay_window .body{padding:15px;background-color:#f4f4f4}.overlay_window .un-body{margin:0 -15px;padding-bottom:1px;overflow:hidden}.overlay_window .body h2{font-size:16px}.overlay_window .body p{margin-bottom:15px}.overlay_window .body p:last-child{margin-bottom:0}.overlay_window .body label{font-size:12px}.overlay_window .body .title.simple{font-weight:normal}.overlay_window .body .title.error{color:#f00}.overlay_window .body #select_btn{margin-top:10px}.overlay_window .controls{text-align:right}.overlay_window .controls button.close_btn{float:left}.overlay_window .controls.highlighted{padding:10px;margin:0}.overlay_window header .minimize{position:absolute;right:0;top:6px;border-right:1px solid #999;padding:1px 6px 1px 0}.overlay_window header .minimize_btn{cursor:pointer;display:block;height:16px;width:16px;background:url(../images/buttons/btn_minimize.png) no-repeat left top}.overlay_window header .minimize_btn:focus,.overlay_window header .minimize_btn:hover{background-position:left bottom}#download-link-popup{font-size:12px}#download-link-popup>.body_container{padding:15px;text-align:center}#download-link-popup .body_container>span{margin-bottom:5px;display:inline-block}#download-link-popup .body_container>span:last-of-type{font-style:italic;font-size:11px}#main{margin:0 auto;width:1280px}.search-main#main,.detail-main#main,.language-os-selector#main,.boutique#main{padding-left:0}.search-main#main{width:1265px}.search-main #facets-pane{margin-left:30px}.my-uploads-page#main{padding-left:0}.developer-description#main{padding-left:0}#main.search-page,#main.boutique{overflow:auto}.boutique #content{margin-left:120px}#goTop{display:none;position:fixed;right:20px;bottom:145px;width:50px;height:50px;-webkit-transition:opacity .2s;-moz-transition:opacity .2s;-o-transition:opacity .2s;transition:opacity .2s;z-index:9999}#goTop:hover{-moz-opacity:.8;-khtml-opacity:.8;opacity:.8;cursor:pointer}.sort-option{height:25px;background:#fff;margin-right:6px;border-bottom:solid 1px #29abe2}.sort-img-group{width:12px;height:14px;margin-bottom:-3px;display:-moz-inline-box;display:inline-block}.sort-img-group-asc{background:url("../images/icons/up_arrow_idle.png"),url("../images/icons/down_arrow_selected.png") 0 7px;background-repeat:no-repeat}.sort-img-group-desc{background:url("../images/icons/up_arrow_selected.png"),url("../images/icons/down_arrow_idle.png") 0 7px;background-repeat:no-repeat}.sort-option .sort-common{font:12px arial;text-align:center;height:25px;line-height:25px;padding-left:15px;padding-right:15px;margin-right:-4px;display:-moz-inline-box;display:inline-block}.sort-option .sort-common:hover{color:#29abe2;background:#e6e6e6;cursor:pointer}.sort-option .sort-unhightlighted{color:#29abe2;background:#fff}.sort-option .sort-hightlighted{color:#fff;background:#29abe2}.widget-hoverable{width:200px;height:100px}.widget-hoverable{background:white;border:1px solid #e3e3e3}.widget-hoverable .default-area{width:100%;height:100%}.widget-drawer{height:0;width:260px;background:white;border:1px solid #e3e3e3;border-top:0;margin-left:-1px;overflow:hidden;outline:1px solid transparent;-webkit-transform:scaleY(0);-o-transform:scaleY(0);-ms-transform:scaleY(0);transform:scaleY(0);-webkit-transform-origin:top;-o-transform-origin:top;-ms-transform-origin:top;transform-origin:top;overflow:hidden;-webkit-transition:-webkit-transform .3s ease;-webkit-transition:-webkit-transform .3s ease;-webkit-transition:-webkit-transform .3s ease;transition:transform .3s ease}.widget-hoverable:hover .widget-drawer{max-height:120px;position:absolute;height:auto;z-index:999;-webkit-transform:scaleY(1);-o-transform:scaleY(1);-ms-transform:scaleY(1);transform:scaleY(1);box-shadow:0 2px 5px -2px rgba(170,170,170,0.4);-moz-box-shadow:0 2px 5px -2px rgba(170,170,170,0.4);-webkit-box-shadow:0 2px 5px -2px rgba(170,170,170,0.4);-ms-box-shadow:0 2px 5px -2px rgba(170,170,170,0.4)}.widget-drawer span{color:#666;font-size:12px;display:block;word-wrap:break-word;margin:6px}.apps-carousel-section .widget-hoverable{height:80px;margin-right:-5px}.apps-carousel-section .widget-drawer{width:165px}.apps-section-middle ul.apps-list .widget-hoverable{height:70px;width:203px}.apps-section-middle .widget-drawer{width:203px}ul.apps-list li{padding-top:8px}ul.apps-list li.widget-element-app.large-widget-element:not(:nth-child(4n+1)){margin-left:-5px}ul.apps-list li.widget-element-app.large-widget-element:nth-child(n+5){margin-top:-5px}.apps-section-middle ul.apps-list li.widget-element-app:not(:nth-child(5n+1)){margin-left:-5px}.apps-section-middle ul.apps-list li.widget-element-app:nth-child(n+5){margin-top:-5px}#result-list.apps-list-big .s-price-cont{position:absolute;right:auto;bottom:10px;left:310px;width:110px}#result-list.apps-list-big .s-price-cont .price{text-align:left;font-size:12px;color:#29abe2;overflow:hidden;text-overflow:ellipsis}#result-list.apps-list-big .title.ellipsis{width:305px;color:#444;font-weight:bold}#result-list .widget-element-app-layout{background-color:rgba(255,255,255,0.7);cursor:pointer}#result-list.apps-list-big .sr-subscriberonly.ellipsis{width:100px;text-align:left}.search-results h3{color:#4d4d4d;margin:0;font-size:12px;font-weight:bold;line-height:20px}#result-list-new-wrapper #result-list{margin:0;border:0;background-color:transparent}#result-list-new-wrapper ul.apps-list li.small-widget-element{margin:12px 12px 0;border:1px solid #b3b3b3;-ms-border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}ul.apps-list-big .product-data-container{float:left;width:411px;position:relative;height:82px;margin-left:8px}ul.apps-list-big .seller{position:absolute;left:230px;top:6px;color:#666;font-size:12px;text-align:right}ul.apps-list-big .rating-wrapper{position:absolute;left:310px;width:110px;top:0}ul.apps-list-big .small-widget-element{-ms-border-radius:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px;border:1px solid #d3d3d3;padding:9px;box-shadow:3px 3px 2px rgba(0,0,0,0.2);-moz-box-shadow:3px 3px 2px rgba(0,0,0,0.2);-webkit-box-shadow:3px 3px 2px rgba(0,0,0,0.2);-ms-box-shadow:3px 3px 2px rgba(0,0,0,0.2)}ul.apps-list-big .small-widget-element .product-data-image{-o-border-radius:18px;-ms-border-radius:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px;width:80px;border:1px solid #aaa}ul.apps-list-big .small-widget-element .product-data-image img{-o-border-radius:18px;-ms-border-radius:18px;-moz-border-radius:18px;-webkit-border-radius:18px;border-radius:18px;width:80px;height:80px}.widget-element-app-search-list-view .product-data-image{width:82px}.widget-element-app-search-list-view img{width:80px;height:80px;-webkit-border-radius:5px;border-radius:5px;border:1px solid #e3e3e3}ul.apps-list .short-description-wrapper{position:absolute;top:73px;word-wrap:break-word;width:150px;color:#666;font-size:12px}ul.apps-list-big .short-description-wrapper{display:block;color:#808080;width:305px;word-wrap:break-word;font-size:11px;height:60px;overflow-y:hidden}#content{width:700px;display:inline;float:left;margin:0 10px}.normal-search#search-form{float:left;width:600px}#search-form .search-form-filter{width:235px;height:22px;float:left;margin:1px 0}#search-form .search-form-keyword{color:#666;font-size:12px;height:16px;line-height:16px;width:90%;margin:0;border:0;background:transparent;margin-top:6px;margin-bottom:6px;-ms-box-shadow:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;padding-right:0;padding-left:4px;outline:0}.show-all-wrapper{float:left;line-height:38px;margin-left:10px}#search-form .show_all{font-size:12px;color:#4674a7;float:left;margin-left:8px;line-height:22px;cursor:pointer;width:140px;text-align:right}#search-form .show_all:hover{color:#039}#search-form #show_all_display{float:left;width:100px;height:18px;overflow:hidden;text-overflow:ellipsis}#search-form .search-form-submit,#app-management .app-search .search-form-submit{right:1px;padding:0;background:url(../images/icons/icon_search.png) no-repeat scroll center center transparent;border:0;cursor:pointer;position:relative}#categories-nav{margin-top:10px}ul.dropdown,ul.dropdown li,ul.dropdown ul{list-style:none;margin:0;padding:0}ul.dropdown{position:relative;z-index:597;float:left;width:660px;height:26px;background:#000;padding:0 20px}ul.dropdown li{float:left;line-height:26px;zoom:1;font-size:15px;padding:0 33px 0 0;cursor:default;border:0}ul.dropdown li a{color:#FFF;cursor:pointer}ul.dropdown li:hover{position:relative;z-index:599;cursor:default}ul.dropdown li:hover>ul{visibility:visible}ul.dropdown .dirr span{background:url(../images/icons/menu_arrow_white.png) no-repeat right 8px;padding-right:15px}ul.dropdown ul{visibility:hidden;position:absolute;top:100%;left:0;z-index:598;width:100%;background:#0d0d0d;-moz-box-shadow:2px 2px 2px rgba(24,24,24,0.33);-webkit-box-shadow:2px 2px 2px rgba(24,24,24,0.33);-ms-box-shadow:2px 2px 2px rgba(24,24,24,0.33);box-shadow:2px 2px 2px rgba(24,24,24,0.33)}ul.dropdown ul.nav-1{width:300px;left:0}ul.dropdown ul.nav-2{width:280px;left:0}ul.dropdown ul.nav-3{width:225px;left:-50px}ul.dropdown ul li{float:none;padding:2px 5px}ul.dropdown ul li:hover{background:#507fc1}ul.dropdown ul li a{color:#d9d9d9;font-size:13px}.homepage-module,.detailpage-module{margin-bottom:20px;float:left}.image-homepage{position:relative;min-height:220px}#image-title-homepage{position:absolute;left:23px;top:23px;color:#000;font-size:16px;width:654px;font-weight:bold;text-shadow:0 0 8px rgba(255,255,255,1)}#image-des-homepage{position:absolute;left:23px;top:48px;color:#000;font-size:12px;width:420px;line-height:1.3;text-shadow:0 0 8px rgba(255,255,255,1)}#carousel-slider{height:200px}.carousel-control{background:url('../images/sprite.png');width:35px;height:72px;border:0;zoom:60%}.left.carousel-control{background-position:-50px -50px}.right.carousel-control{background-position:-100px -50px}.carousel-indicators{bottom:15px;right:auto;top:auto;left:60px}.carousel-indicators li{cursor:pointer;border-radius:0;margin-left:20px;width:10px;height:10px;background-color:grey}.carousel-inner .item{width:100%;height:200px;overflow:hidden;background-repeat:no-repeat;background-position:center center}.landing-view #carousel-slider{-moz-box-shadow:0 0 5px rgba(0,0,0,0.4);-webkit-box-shadow:0 0 5px rgba(0,0,0,0.4);-ms-box-shadow:0 0 5px rgba(0,0,0,0.4);box-shadow:0 0 5px rgba(0,0,0,0.4);height:200px}.landing-view .carousel-caption,.home-view .carousel-caption{top:0;padding:35px 0 0 120px;position:absolute;top:0;background:-webkit-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:-moz-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:-o-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:-ms-linear-gradient(left,rgba(35,35,35,0.8),rgba(35,35,35,0));background:linear,left,rgba(35,35,35,0.8),rgba(35,35,35,0);filter:alpha(opacity=80 finishopacity=0 style=1) progid:DXImageTransform.Microsoft.gradient(startColorstr='rgb(35,35,35)',endColorstr='rgb(35,35,35)',GradientType=0)}#landing-container{width:1280px;margin-left:auto;margin-right:auto}#landing-container .button-wrapper{position:absolute;z-index:4;top:150px;right:80px}#landing-container .carousel .button-wrapper button{height:30px;min-width:150px;font-size:14px;color:#fff;font-family:'Open Sans',Arial,'FrutigerNextPro',sans-serif;text-shadow:none;border-radius:0}#landing-container .carousel .button-wrapper .btn-signup{background:#00c000;border:0;margin-right:10px}#landing-container .carousel .button-wrapper .btn-fusion-hero{background:#f89706 url('../images/icons/fusion-download.png') no-repeat center right 10px;border:0;padding-right:35px}#landing-container .carousel .button-wrapper .btn-signin{background:#259fff;border:0}.landing-view .carousel .carousel-inner .item .carousel-caption h2,.home-view .carousel .carousel-inner .item .carousel-caption h2{font-family:'Open Sans',Arial,'FrutigerNextPro',sans-serif;font-size:20px;text-shadow:0 0 10px rgba(0,0,0,0.6);color:#FFF;padding:5px 10px;display:inline-block;font-weight:initial}.landing-view .carousel .carousel-inner .item .carousel-caption pre,.home-view .carousel .carousel-inner .item .carousel-caption pre{line-height:22px;font-family:'Open Sans',Arial,'FrutigerNextPro',sans-serif;font-size:16px;padding:5px 10px;color:#FFF;text-shadow:0 0 10px rgba(0,0,0,0.6);max-width:700px;border:0;background-color:transparent;overflow:hidden;word-wrap:normal;word-break:keep-all}.button-wrapper .signin_link{text-decoration:none}.page-tool-wrapper{width:1220px;margin:0 auto;border-top:1px solid #cecece;overflow:auto}#main .page-tool{margin:10px auto;width:730px;padding:20px 0}#main .page-tool #signup-box{height:48px;width:332px;padding-top:20px;padding-bottom:20px}#main .page-tool #signup-box .text{margin:10px 0 0;color:#666;font-size:12px}#main .overlay-link{margin-right:30px}#main .opening-soon{margin-left:auto;margin-right:auto;width:604px;height:270px;background-repeat:no-repeat;padding:20px;background-image:url("../images/layout/opening_soon_bg.png")}.landing-view #main,.home-view#main{margin:0!important;width:auto!important;background:#f1f0f0}.landing-view #landing-banner #banner-carousel .carousel-list li h1{color:#444;text-shadow:0 0 8px rgba(255,255,255,1);font-size:40px;font-weight:normal;margin:48px 0 0 130px}.landing-view #landing-banner #banner-carousel .carousel-list li h1.maintenance-header{margin-top:100px}.landing-view #landing-banner #banner-carousel .carousel-list li h2{color:#444;text-shadow:0 0 8px rgba(255,255,255,1);font-size:19px;width:600px;font-weight:bold;margin:20px 0 0 130px}.landing-view #landing-banner #banner-carousel .carousel-list li p{color:#444;text-shadow:0 0 8px rgba(255,255,255,1);font-size:14px;width:400px;margin:20px 0 0 130px}.landing-view #landing-banner{margin:0 auto;width:1180px;position:relative}.landing-view #learn-more{width:920px;margin:0 auto 80px auto}.landing-view #landing-banner #banner-carousel{width:1180px;height:400px;position:relative;overflow:hidden}.landing-view #landing-banner #banner-carousel .carousel-list{width:20000em;position:absolute;list-style:none;margin:0;padding:0}.landing-view #landing-banner #banner-carousel .carousel-list li{float:left;width:1180px;height:400px}.landing-view #landing-banner #banner-carousel .carousel-list li.banner-carousel-0{background:url('../images/layout/landing_hero.jpg') no-repeat 0 0}.landing-view #learn-more .maintenance-page{width:435px;margin:54px 0;float:right}.landing-view #learn-more .maintenance-page h1{font-size:16px;font-weight:bold}.landing-view #learn-more .maintenance-page p{font-size:14px}.landing-view #learn-more .maintenance-page{float:none}.landing-view #header #base{min-width:400px}.storenav-button{background:transparent url(../images/buttons/storenav_btn.png?timestamp=20131012) repeat-x 0 0;display:inline-block;margin:0;border:0;min-width:300px;height:45px;color:#555;text-align:center;line-height:45px;font-size:12pt;text-shadow:0 0 8px rgba(255,255,255,1);font-weight:normal;padding:0 10px;-moz-box-shadow:.5px .5px 1px 1px #959595;-webkit-box-shadow:.5px .5px 1px 1px #959595;-ms-box-shadow:.5px .5px 1px 1px #959595;box-shadow:.5px .5px 1px 1px #959595}.storenav-button:hover{background:transparent url(../images/buttons/storenav_btn.png?timestamp=20131012) repeat-x 0 -45px;cursor:pointer}.storenav-button:active,.storenav-button.ui-custom-active{background:transparent url(../images/buttons/storenav_btn.png?timestamp=20131012) repeat-x 0 -90px}a.storenav-button.select-store{color:#fff}.landing-view .dropdown-menu>li>a{line-height:25px}.navbar .dropdown-menu .popover-menu{padding:0;margin:5px 0!important}.navbar .dropdown-menu .popover-menu>li{line-height:25px}.navbar .dropdown-menu .popover-menu>li>a{display:block;padding:0 20px;text-decoration:none;color:black}.navbar .dropdown-menu .popover-menu>li>a:hover{color:white;background-color:#0081c2}.navbar .nav{padding:0}.navbar-header{margin-top:15px}.navbar-brand{background:url(../images/layout/Header_Logo.png) no-repeat;width:241px;height:23px;float:left;text-indent:-9999px;overflow:hidden;background-size:100%}.navbar-default{margin:0;padding:0 20px;border-bottom:1px solid #ccc;background:white}.navbar-toolbar{margin:0;padding:0 20px;background:#f1f0f0}.navbar-default .container{height:50px}.navbar-toolbar .container{height:52px}.navbar-toolbar .navbar{margin:14px 0 11px}.landing-view .navbar-toolbar .navbar{margin:11px 0}.navbar-toolbar .navbar .btn-group{margin-top:0}.btn{background-image:none}.navbar-collapse{height:auto;overflow:visible}.navbar .navbar-nav li{padding:5px 0;height:24px;line-height:24px}.user-panel li.drop_down{padding:0}.navbar .navbar-nav li a{cursor:pointer;padding:0 15px;height:45px;line-height:45px;position:relative;top:-2px;color:#29abe2}.navbar .navbar-nav li a:hover{color:#40cdf5}.login-panel li.depression,.login-panel li.depression{outline:1px solid lightgrey;background:-webkit-gradient(linear,top,bottom,from(#ccc),to(#ededed));background:-webkit-linear-gradient(#ccc,#ededed);background:-moz-linear-gradient(#ccc,#ededed)}.login-panel .depression-panel-myDownloads>li a{border-left:none}.login-panel .depression-panel-myUploads>li.myUploads-li a,.login-panel .depression-panel-myUploads .user-panel{border-left:none}.user-panel{border-left:solid 1px rgba(187,196,198,0.5);padding-left:15px;margin-top:8px}.navbar .navbar-nav li a.a-help-20{border-left:none;padding:0}[class^="icon-"],[class*=" icon-"]{width:20px;height:20px;margin-top:0}.icon-help-20{background:url(../images/icons/help-20x20.png) no-repeat}.search-wrapper .search-box-store-selector{visibility:visible;opacity:0;filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity:0;position:absolute;top:8px;right:-35px;width:180px}.search-wrapper .nav-search-scope{overflow:hidden;position:relative}.nav-right{float:right;width:auto;display:inline-block}.nav-fill{width:auto;height:35px;position:relative;margin-right:110px}.nav-search-field{position:relative;height:35px}.search-wrapper .search-form-content{border:1px solid lightgrey;background:white}.search-wrapper .search-form-content.active{border-color:#51a7e8;-ms-box-shadow:0 0 5px rgba(81,167,232,0.5);-webkit-box-shadow:0 0 5px rgba(81,167,232,0.5);-moz-box-shadow:0 0 5px rgba(81,167,232,0.5);box-shadow:0 0 5px rgba(81,167,232,0.5)}.search-wrapper .nav-search-scope{position:relative;float:left;height:37px;margin:0;overflow:hidden}.search-wrapper .nav-search-facade{position:relative;float:left;padding:6px 5px 7px 5px;font-size:12px;line-height:14px;margin:5px 0;cursor:pointer;border-left:1px solid lightgrey}.search-wrapper .nav-search-facade .caret{margin-top:5px;margin-left:2px}.search-wrapper .nav-search-submit{position:relative;float:left;height:35px;width:35px;overflow:hidden;cursor:pointer;background:#29abe2}.search-suggestions-box-ul{font:12px Arial;color:#666;position:relative;left:-1px;top:-1px;border:1px solid #ccc;background:#fff;z-index:99;overflow:hidden}.search-suggestions-box-ul li{line-height:25px;cursor:pointer;margin-left:-20px;padding-left:5px}.search-suggestions-box-ul li.selected{background-color:#eee}#search-suggestions-box li:hover{background:#eee}.detail-search-suggestion ul{overflow:hidden;top:0}.detail-search-suggestion li{margin-left:0}.nav-search-submit .nav-input{position:relative;display:block;height:100%;width:100%;line-height:33px;text-indent:-1000px;padding:0;border:0;cursor:pointer;outline:0}.navbar .popover{width:400px;-webkit-border-top-left-radius:0;-webkit-border-bottom-left-radius:0;border-top-left-radius:0;border-bottom-left-radius:0;overflow:hidden}.navbar .popover-content{text-align:center}.navbar .dropdown-menu{-webkit-border-top-right-radius:0;-webkit-border-bottom-right-radius:0;border-top-right-radius:0;border-bottom-right-radius:0;-ms-box-shadow:0 0 5px #000;-webkit-box-shadow:5px 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:5px 5px 10px rgba(0,0,0,0.2);box-shadow:5px 5px 10px rgba(0,0,0,0.2)}.navbar .dropdown-menu>li>a:hover{background-image:none;color:white;background-color:#0081c2;background-color:rgba(0,129,194,0.5)}.navbar .dropdown-menu>li>a.maintainHover{color:white;background-color:#0081c2}#featured-products{margin-top:10px;margin-bottom:10px;background-color:White;border:1px solid #cecece;background-color:white;-moz-border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;-ms-box-shadow:0 1px 0 #f1f1f1;-moz-box-shadow:0 1px 0 #f1f1f1;-webkit-box-shadow:0 1px 0 #f1f1f1;box-shadow:0 1px 0 #f1f1f1}#featured-products h2{font-size:16px;color:#404040;font-weight:bold;line-height:28px;height:28px;padding:10px 20px 10px;background-color:white}#featured-products h3{font-size:16px;color:black;margin:7px 0 0;font-weight:normal}#featured-products ul{padding:0 12px 8px;width:674px;color:black;margin:0}#featured-products ul li{position:relative;height:90px;float:left;width:216px;margin:3px 3px 12px 0;padding:0}#featured-products ul li:hover,#featured-products ul li:focus{background:#d5deeb;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;cursor:pointer}#featured-products ul li:hover a{cursor:pointer}#featured-products ul li:active{background:#9fb3d1}#featured-products .featured_image{width:80px;height:80px;float:left;margin:0 5px 0 0;overflow:hidden}#featured-products ul li div.product-content-container{padding:5px}#featured-products .product-data-container{float:left}#featured-products .product-data-container #product-title{width:120px}#featured-products ul li .title{font-size:12px;color:#000;margin:0}#featured-products ul li .seller,#featured-products ul li .reviews{font-size:10px;color:#808080;display:block}#featured-products ul li .reviews{clear:both}#featured-products ul li .ratingamount{font-size:10px;color:#666;display:block;margin-bottom:3px}#featured-products ul li .price{color:#000;display:block}#featured-products ul li .price.free{color:green}#featured-products ul li .overlay-link{width:100%;height:100%;position:absolute;left:0;top:0;outline:0;z-index:100}#featured-products ul li.clear{height:0}#show_more_all div{text-align:right;padding-top:10px;padding-bottom:20px;padding-right:20px;vertical-align:bottom;font-family:Arial;font-size:12px;color:#4675a8}#show_more_all div a{color:#4675a8}.product-rating-small{float:left;width:65px;height:15px;margin:2px 0 0 0}.product-comment{float:left;height:15px;width:35px;margin:2px 0 0 10px;vertical-align:middle;font:12px arial,Helvetica,sans-serif;color:#808080}.product-comment img{margin:0 0 0 3px}.search-results-stars{float:right}.product-rating-small .star-rating{float:left;width:13px;height:12px;cursor:default;display:block;background:url(../images/icons/star_small.png) no-repeat 0 0;overflow:hidden}.product-rating-small .star-on{background-position:0 -12px!important}.product-rating-small .star-off{background-position:0 0!important}.product-rating-search{float:none}#add-comment .errors{color:red;float:right}#add-comment .not_visible{display:none}#add-comment .error_tag,#add-comment .error{color:red}#add-comment #title{margin-bottom:10px;width:351px;height:16px}#add-comment textarea.error_border,#add-comment input.error_border{border-color:red}#add-comment .comment-rate.error_border{border:1px solid red}.search-page #right{margin-left:20px}#right{width:220px;margin-left:10px;display:inline;float:left}#bestsellers{width:223px}.no-cssgradients #bestsellers h2{background:#e1e1e1 url(../images/layout/backgrounds/bg_h2_title.png) repeat-x 0 0}#bestsellers h2{font-size:16px;font-weight:normal;text-align:center;height:28px;color:#404040;margin:0;padding:0;border:1px solid #cecece;border-bottom:0;line-height:28px;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3)}#bestsellers ul{position:relative;top:0;margin:0;padding:0;border:1px solid #cecece;background-color:#fff;-moz-border-radius:0 0 4px 4px;-webkit-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;-ms-box-shadow:0 1px 0 #f1f1f1;-moz-box-shadow:0 1px 0 #f1f1f1;-webkit-box-shadow:0 1px 0 #f1f1f1;box-shadow:0 1px 0 #f1f1f1}#bestsellers li{border-top:1px solid #d9d9d9;position:relative;height:54px;padding:0;margin:0;display:block}#bestsellers .container{height:42px;width:auto;padding:6px 10px;cursor:pointer}#bestsellers ul li:first-child{border-top:0 none}#bestsellers li:hover,#bestsellers li:focus{background:#d5deeb}#bestsellers li:active{background:#9fb3d1}#bestsellers div.container img.bestseller-icon{width:40px;height:40px;float:left;margin-right:10px;overflow:hidden}#bestsellers .title{color:#000;font:12px arial,Helvetica,sans-serif;margin:0;display:inline-block;width:78px}#bestsellers .description{color:#666;font-size:10px;float:left;margin:0}#bestsellers .price{float:right;font:12px arial,Helvetica,sans-serif;color:#000;vertical-align:bottom}#bestsellers .price.free{color:#008000}#bestsellers .overlay-link{width:100%;height:100%;position:absolute;left:0;top:0;outline:0;z-index:100}.bestsellers-content{float:left;width:150px;height:40px}.leftwing #bestsellers{width:234px}.leftwing .bestsellers-content{width:161px}.leftwing #bestsellers .title{width:89px}.ga-data{text-align:center}.ga-value span{font-size:16px;color:#333}.ga-image-sliders{border-radius:4px;border:1px solid #cecece;overflow-x:hidden;width:348px!important}.ga-image-sliders ul{width:1400px;border:0;height:49px;margin:0;padding:0;background:#e4e4e4;border-bottom:1px solid #cecece}.ga-image-sliders li,.ga-image-sliders li span{width:350px;height:50px}.ga-image-sliders li .ga-title{padding-top:5px;padding-bottom:5px}.ga-image-sliders li .ga-title span{font-size:12px;color:#1c2e84}.ga-image-sliders li{float:left;color:#333;border-top:0}.ga-image-sliders .ga-more-static{height:38px;text-align:center;font-size:15px;background:#f2f2f2}.ga-image-sliders .ga-more-static div{padding-top:10px}.ga-image-sliders .ga-more-static a{font-weight:bold;font-size:12px}.ga-image-sliders .ga-more-static a:link,.ga-image-sliders .ga-more-static a:visited,.ga-image-sliders .ga-more-static a:hover{color:#1c2e84}#quicklinks{float:left;clear:both;padding:0;margin:0 10px 20px 0;display:inline-block;border:1px solid #cecece}#quicklinks a{color:#369}#quicklinks h2{font-size:16px;font-weight:normal;text-align:center;height:28px;color:#333;line-height:28px;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3)}#quicklinks ul{padding-left:10px;width:220px;float:left}#quicklinks ul li{padding-bottom:5px}#quicklinks .quicklinks-body{border-top:1px solid #cecece}#facets .facets-constraints .title,#quicklinks li .title{font-size:12px;color:#369;cursor:pointer}#quicklinks li .title{font-size:12px}#quicklinks li.hidden-links{display:none}#facets .facets-constraints .count,#quicklinks li .count{font-size:12px;color:#999}#quicklinks li .count{font-size:11px}#quicklinks .show-all-body{width:210px;padding:10px 10px 10px 12px;border-top:1px solid #cecece}#quicklinks .show-all-body span.show_all{cursor:pointer;font-size:12px;color:#4674a7;font-weight:bold}.no-cssgradients #signup-box{background:#eee}.no-cssgradients #signup-box:hover{background-color:#d9d9d9}#signup-box{float:left;width:205px;text-align:center;color:#222;font-size:11px;padding:13px 8px;background:#e4e4e4;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;-ms-box-shadow:0 1px 0 #f1f1f1;-moz-box-shadow:0 1px 0 #f1f1f1;-webkit-box-shadow:0 1px 0 #f1f1f1;box-shadow:0 1px 0 #f1f1f1;border:1px solid #cecece;cursor:pointer;display:block}#signup-box .title{margin:0;color:#1c2e84;font-size:14px;font-weight:bold;line-height:1.2}#signup-box .text{margin:5px 0 5px}#signup-box .overlay-link{width:100%;height:100%;position:absolute;left:0;top:0;outline:0;z-index:100}#twitter-widget-0{width:85px!important;float:right}.fb-like{margin-right:2px;float:right}.s-price-cont.s-price-cont-hidden{display:none}.detail-page .detail-module{float:left}.detail-page #content{width:938px;margin:0;margin-bottom:100px}.detail-page #content-wrapper{margin-bottom:10px}.detail-page #detail{padding:10px;background:#fff;border:1px solid #ccc;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.detail-page #detail subscriptionDes .subscriptionDes{vertical-align:middle}.detail-page #detail img.subscriptionBadge{float:none;width:24px;height:24px;margin:0}.detail-page #detail .strikeout-price{text-decoration:line-through;vertical-align:middle;padding:0 10px 0 0;cursor:default}.detail-page .description p{word-wrap:break-word;word-break:normal}.detail-page #detail img.product-icon,#app-detail-for-publisher img.product-icon{float:left;height:120px;width:120px;margin:0 15px 5px 0}#app-detail-for-publisher hr{width:960px}.detail-page #detail .title-rating{float:left}.detail-page #detail .icons-cont{width:100%;margin-top:20px}.detail-page #detail .badge-div{float:left}.detail-page #detail .badge-div-visible{visibility:visible}.detail-page #detail .badge-div-hidden{visibility:hidden}.detail-page .badge-div .subscriptionBadge{float:left}.detail-page .purchase-container .caret{border-top:4px solid #fff}#detail-title{margin:0 10px 2px 0;font-size:20px;padding:0;width:80%;color:#4d4d4d;overflow:hidden;text-overflow:Ellipsis;white-space:nowrap;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis}#detail-social{float:right}#detail .detail-versions-cont .detail-version-cat{float:left;cursor:default;line-height:26px;width:135px}#detail .detail-versions-cont{margin-bottom:10px}#detail .{background:left}.product-rating-big{float:left;width:90px;height:15px;margin:7px 0}.title-rating .product-rating-big{margin:0}.product-rating-big .star-rating{float:left;width:18px;height:16px;cursor:default;display:block;background:url(../images/icons/star_big.png) no-repeat 0 0;overflow:hidden}.product-rating-big .star-on{background-position:0 -16px!important}.product-rating-big .star-off{background-position:0 0!important}.product-rating-search{float:none}.detail-versions-cont .flat-button{border-radius:2px;min-width:150px}.detail-versions-cont .app-version-btn{color:#4d4d4d}#content-wrapper .reviews-count{line-height:32px;margin-left:5px;font-size:12px}#detail .seller{font-size:14px;color:#29abe2}#detail .release-date{font-size:12px;float:right;color:#808080}#detail .description{color:#333;margin:10px 0 10px;font-size:14px;line-height:130%;-ms-word-break:break-word;word-break:break-word;-ms-word-wrap:break-word;word-wrap:break-word}#detail .download-free-notification{clear:both;color:#4675a8;margin:20px 0 20px;font-size:12px;font-weight:bold}#detail .education-free-notification,#detail .app-benefit-notification{clear:both;color:gray;font-size:12px;float:right;font-style:italic}#detail .app-benefit-notification{float:left}#detail .education-free-notification a,#detail .app-benefit-notification a{color:#1a52ad}#detail .description p{margin:0}#detail #extra hr{margin-top:10px;margin-bottom:10px}#detail #extra .detail-versions-cont hr{margin-top:2px;margin-bottom:2px}#extra .purchase-container{height:25px;float:right;max-width:300px;cursor:pointer;margin-bottom:16px}#extra .purchase-container .btn{height:30px;line-height:30px}#extra .version-title{color:#808080;font-size:14px}.price_btn_blue{width:auto;padding:0 20px;border:0;font-size:14px;cursor:pointer;height:25px;text-align:center;line-height:25px;color:#fff}#extra a.price_btn_blue,#extra span.price_btn_blue,#extra a.price_btn_blue:hover{color:white}#detail #detail_testinfo{border:1px solid #00c;padding:5px}#detail .detail_testresult{margin-left:10px;font-style:italic}#extra .purchase_container{display:none}#screenshots .jcarousel-skin-tango .jcarousel-container{background:0;border:0;padding:0 22px}.no-cssgradients #screenshots h2.title,.no-cssgradients .jcarousel-skin-tango{background-color:#f0f0f0}#screenshots ul{height:140px;overflow:hidden;margin:0;padding:0}#screenshots ul li{position:relative}#screenshots .text-container{margin:0 50px 10px;font-size:12px;color:#666}#screenshots .text-container .title{font-weight:bold;line-height:26px}#screenshots ul li span{text-align:center;overflow:hidden;display:block;color:#4d4d4d}#screenshots ul li img{display:block;position:absolute;margin:auto;top:0;bottom:0;left:0;right:0;max-height:74px}.preview-container{height:505px;margin:0 50px 15px 50px;border:1px solid #cecece;position:relative}.preview-container>iframe{width:100%}.preview-container>img,.preview-container>iframe{position:absolute;max-height:100%;max-width:100%;top:0;bottom:0;right:0;left:0;margin:auto;border:0}.preview-next:hover,.preview-prev:hover{opacity:1}.preview-next,.preview-prev{width:20px;height:30px;top:160px;z-index:10;cursor:pointer;position:absolute;opacity:.5}.preview-container .preview-next{background:url(../images/icons/next.png) no-repeat;right:-30px}.preview-container .preview-prev{background:url(../images/icons/prev.png) no-repeat;left:-30px}.preview-overlay{z-index:10;position:relative;height:100%;cursor:pointer}.preview-overlay:hover{background:rgba(0,0,0,0.1) url(../images/icons/zoom.png) no-repeat center;background-size:10%}.video-overlay{background:rgba(0,0,0,0.15) url(../images/buttons/play.png) no-repeat center;height:100%;width:100%;position:absolute;z-index:10;margin:-3px}.video-overlay:hover{cursor:pointer;background:transparent url(../images/buttons/play.png) no-repeat center}.detail-page #right{width:328px;margin-bottom:100px}.side-panel{font-size:12px}.side-panel span#language{word-break:normal}.side-panel h2{font-size:16px;font-weight:normal;padding:0 10px;height:28px;color:#404040;border:1px solid #cecece;line-height:28px;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3);text-align:center}.side-panel h3{height:25px;background:-webkit-gradient(linear,left top,left bottom,from(#f0f0f0),to(#e3e3e3));background:-webkit-linear-gradient(#f0f0f0,#e3e3e3);background:-moz-linear-gradient(#f0f0f0,#e3e3e3);font-weight:normal;border:1px solid #cecece;border-bottom:0;border-top:0;line-height:25px;padding:0 8px;color:#000}.side-panel ul.compatible-with-list,ul.subscriber-benefit-product-list{margin:0;padding:0}.side-panel li.hidden-subscriber-benefit-products,li.hidden-compatible-with-list{display:none}.side-panel li.your-subscription{font-weight:bold}.side-panel #purchase{border:1px solid #bfbfbf;background-color:White;padding:10px;margin-bottom:10px;padding-bottom:42px}.side-panel #purchase .price-str{font-size:24px}#purchase .flat-button{width:100%;padding:4px 0}#price-options .flat-button{height:50px;border-radius:0;font-size:24px;color:#29abe2;border:2px solid #29abe2}#price-options .flat-button.selected{color:white}.side-panel .download-info{min-height:15px;padding:5px 0;margin-top:10px}.side-panel .download-info-subscription{padding-bottom:10px}.side-panel .show-more,.show-less{color:#1a52ad;display:inline-block;white-space:nowrap;cursor:pointer}.break-word{word-wrap:break-word;word-break:break-all}.side-panel .download-info .property{float:left}.side-panel .download-info-subscription .property{margin-bottom:10px}.side-panel #show-more-benefit-products,.side-panel #show-less-benefit-products{margin-bottom:10px}.side-panel .download-info .compatible-with-list .compatible-with-list-group{margin-top:8px}.side-panel .download-info .subscriber-benefit-product-list li,.side-panel .download-info .compatible-with-list li{margin:0 0 2px 0}.side-panel .download-info .value{float:right}.side-panel .detail-comptible{padding-bottom:0}.side-panel .promote-item:hover{background:#f0f0f0}.side-panel .promote-item>img{width:50px;height:50px;float:left;margin-right:10px}.side-panel .s-price-cont{float:none;margin-top:5px}.detail-page .product-rating-small{margin-right:5px}.side-panel .product-rating-small{width:auto}.side-panel .ellipsis{width:190px}.side-panel .show-more-apps{margin:5px;float:right}.side-panel .show-more-apps a{color:steelblue}.side-panel.apps-promote-panel{border:1px solid #cecece;background-color:white;padding-bottom:10px}.side-panel.apps-promote-panel H2{border:0;border-bottom:1px solid #cecece;padding:5px;text-align:center;margin-top:0}.side-panel.apps-promote-panel .company-title{font-size:18px}.side-panel.apps-promote-panel .company-numberitem{font-size:14px;color:#4d4d4d}.side-panel.apps-promote-panel .company-number{font-size:18px;font-weight:bold;color:#808080}.side-panel.apps-promote-panel .info-logo{width:80px;height:80px;margin-right:5px;margin-left:10px}.side-panel.apps-promote-panel .promote-item{height:80px;margin-top:5px;margin-bottom:5px;color:#4d4d4d}.side-panel.apps-promote-panel .company-info-cont{height:80px}.side-panel.apps-promote-panel .promote-item .product-title{margin-bottom:20px;font-size:14px;width:220px;font-weight:bold}.side-panel.apps-promote-panel .promote-item .s-price-cont{color:#29abe2}.side-panel.apps-promote-panel .company-info-cont .info-logo{float:left;margin-right:10px}.side-panel.apps-promote-panel .service-list li{font-size:12px;color:#4d4d4d;margin:0 0 10px 10px}.side-panel.apps-promote-panel ul{margin-top:15px}.side-panel.apps-promote-panel .list-title{font-size:18px;color:#4d4d4d;margin:5px 0 5px 10px}.detail-page h2{font-size:18px;margin:10px 0 10px 0;font-weight:normal;text-align:left;height:28px;color:#4d4d4d;border-bottom:0;line-height:28px}#reviews #summary{background-color:white;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px 4px 4px 4px;border-radius:4px 4px 4px 4px;border:1px solid #cecece;padding:10px;overflow:hidden}#reviews #summary img{width:40px;padding-right:10px;float:left}#reviews #summary .title-author{display:inline-block;float:left}#reviews #summary .title-author span{padding-top:4px;float:left;max-width:100px}#reviews #summary .title-author h3{max-width:100px}#reviews #summary .reviews-info{display:inline-block;padding-left:10px;width:auto;overflow:hidden}#reviews #summary .write-review-link{width:auto;display:inline-block;float:left}.compatible-version{color:grey}.compatible-version-title{font-weight:bold}.reviews-info h3{float:left;line-height:35px;font-size:20px;font-weight:normal;color:#ccc}.get-tech-help{margin:0 5px;color:#1a52ad;line-height:35px}.reviews-info a.get-tech-help:hover{color:#1a52ad}.detail-page span.comment,.detail-page a.comment{padding:8px;margin-right:5px;color:#4d4d4d;cursor:pointer;float:left;border:1px solid #ccc;font-size:14px;width:auto}.detail-page span.noncomment{background:transparent url(../images/icons/comment.png) no-repeat 0 1px;padding-left:20px;margin-left:5px;color:Gray}.detail-page a.comment:hover{color:#3d87ff}#extra .log-in-to-comment span.pending:hover,.detail-page span.pending:hover{color:#1a52ad;cursor:default}.detail-page span.pending,.detail-page a.pending,.detail-page span.pending:hover,.detail-page a.pending:hover{color:#c3c3c3}#reviews #summary .reviews-stars{margin-top:6px}#reviews #summary .reviews-stars .product-rating-small{padding-right:5px}#reviews #summary .reviews-info .averagereview{float:left;margin-right:2px;max-width:190px;width:auto}#reviews #summary .reviews-info .reviews-count{display:block}#comments{width:650px;float:left;padding-bottom:30px}#comments-list{padding:0;margin:0}#comments .add-sub-comments{width:850px}.add-sub-comments .app-publisher{font-weight:bold}#comments .sub-comment-warning,#comments .delete-comment-warnning{color:#f60}#comments .delete-comment-warnning{display:inline}.sub-comment-form textarea{margin-bottom:10px;width:645px}.edit-a-comment-form textarea{margin-bottom:10px;width:600px}#comments .sub-comment-description-warning{border:1px solid #f60;padding:10px}.sub-comment-form-hidden,.sub-comment-link-hidden,.edit-a-comment-hidden,.edit-delete-comment-actions-hidden,.realdelete-cancel-comment-actions-hidden,.sub-comment-hidden,.edit-a-comment-form-hidden{display:none}.comment-action{color:#1a52ad;cursor:pointer}.comment-action:hover{color:#3d87ff;cursor:pointer}.comment-subject{display:block;font-size:13px;color:#595959;font-weight:bold;margin-bottom:10px}.comment-item{margin:20px 0;float:left;width:900px}.comment-item .add-sub-comments{float:left;margin-left:50px}#comments-list hr{width:938px;margin:0;float:left}#comments-list .sub-comment-entity hr{width:888px}.sub-comment-warning{margin-top:10px}.sub-comment-entity{margin-top:15px}.write-a-comment{margin-top:5px;float:left;padding-left:5px}.write-comment-form-submit,.write-a-comment-cancel{margin-right:10px;padding:2px}.sub-comment-description p{margin:0}.sub-comment-description{margin:10px 0;color:#595959}.comment-item .comment-info{float:left;padding-left:5px;width:895px}.comment-item .comment-date{display:inline;color:#a6a6a6;margin-bottom:15px}.comment-item .comment-name{margin-bottom:15px}.comment-item .comment-description{color:#595959}.comment-item .comment-description p{margin-bottom:0}.comment-item .veirified-download{font-size:11px;font-weight:bold;color:#f90}.comment-item .whats-verified-download{font-size:10px;color:#c9c9c9;text-decoration:underline;cursor:pointer}#add-comment{margin-bottom:40px;float:left;background-color:white;-moz-border-radius:4px 4px 4px 4px;-webkit-border-radius:4px 4px 4px 4px;border-radius:4px 4px 4px 4px;border:1px solid #cecece;padding:10px;display:none}#add-comment .title{font-weight:bold;margin-bottom:20px}#add-comment .title a{color:#1f5397}#comment-form .own-rate{float:left;width:260px;text-align:center}#comment-form .own-rate h2{display:inline}#comment-form .own-rate label{font-size:10px;font-weight:bold}#comment-form .own-rate span{font-size:10px}#comment-form .own-rate .product-rating-big{float:none;margin-left:auto;margin-right:auto;padding:10px}#comment-form .own-review{float:left;width:366px;text-align:center}#comment-form .own-review div{position:relative}#comment-form .own-review textarea{margin-top:0;margin-bottom:0;height:65px;width:351px;resize:none}#comment-form input,#comment-form textarea{padding:5px;border:solid 1px #bfbfbf;font-size:13px;font-style:normal;background:white url('../images/bg_form.png') left top repeat-x;background:-webkit-gradient(linear,left top,left 3,from(white),color-stop(1%,#f1f1f1),to(#fcfcfc));background:-moz-linear-gradient(top,white,#f1f1f1 1px,#fcfcfc 2px);box-shadow:rgba(0,0,0,0.1) 0 0 4px;-ms-box-shadow:rgba(0,0,0,0.1) 0 0 4px;-moz-box-shadow:rgba(0,0,0,0.1) 0 0 4px;-webkit-box-shadow:rgba(0,0,0,0.1) 0 0 4px}#comment-form .submit-comment,#comment-form .cancel-comment{width:auto;padding:0 11px;border:0;font-size:14px;color:white;cursor:pointer;height:25px;text-align:center;line-height:25px;margin-top:10px;-moz-box-shadow:none;-webkit-box-shadow:none;-ms-box-shadow:none;box-shadow:none}#comment-form .cancel-comment{margin-right:10px;display:inline-block;margin:0;border:1px solid #797979;white-space:nowrap;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#999;-moz-box-shadow:none;-webkit-box-shadow:none}.gradient-button{background:linear-gradient(#6a91df,#314d7b);background:-webkit-gradient(linear,left top,left bottom,from(#6a91df),to(#314d7b));background:-webkit-linear-gradient(#6a91df,#314d7b);background:-moz-linear-gradient(#6a91df,#314d7b);background:-o-linear-gradient(#6a91df,#314d7b);display:inline-block;margin:0;border:1px solid #335080;white-space:nowrap;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-ms-box-shadow:0 1px 0 rgba(0,0,0,0.4);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.4);-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.4);box-shadow:0 1px 0 rgba(0,0,0,0.4)}.no-cssgradients .gradient-button{background:#314d7b url(../images/icons/bg-gradient-dropdown.png) repeat-x 0 0}a .no-cssgradients .gradient-button:hover,a .no-cssgradients .gradient-button:focus{background-position:0 -26px}.no-cssgradients .gradient-button:active:hover{background-position:0 -32px}.no-cssgradients .gradient-button.disabled{color:#fff;background-position:0 -78px;cursor:default!important}.gradient-button:hover,.gradient-button:focus{background:linear-gradient(#80a1e4,#50688f);background:-webkit-gradient(linear,left top,left bottom,from(#80a1e4),to(#50688f));background:-webkit-linear-gradient(#80a1e4,#50688f);background:-moz-linear-gradient(#80a1e4,#50688f)}.gradient-button:active{background:linear-gradient(#5a7bbe,#2a4269);background:-webkit-gradient(linear,left top,left bottom,from(#5a7bbe),to(#2a4269));background:-webkit-linear-gradient(#5a7bbe,#2a4269);background:-moz-linear-gradient(#5a7bbe,#2a4269)}.gradient-button.disabled{color:#fff;opacity:.3;-moz-opacity:.3;-khtml-opacity:.3;background:linear-gradient(#96b1e9,#577ebc);background:-webkit-gradient(linear,left top,left bottom,from(#96b1e9),to(#577ebc));background:-webkit-linear-gradient(#96b1e9,#577ebc);background:-moz-linear-gradient(#96b1e9,#577ebc);cursor:default!important}.ui-button.disabled{opacity:.8;-moz-opacity:.8;-khtml-opacity:.8}.detail-page .helpdoc-element{margin-top:25px;width:830px}.detail-page .helpdoc-command{margin-top:10px}.detail-page .helpdoc-block{margin-top:10px;width:830px}.detail-page #helpdoc-element-screenshot{width:900px}.detail-page #helpdoc-tag{width:830px}.detail-page #helpdoc-tag a:link,.detail-page #helpdoc-tag a:hover,.detail-page #helpdoc-tag a:visited,.detail-page #helpdoc-tag a:active{float:left;font:12px arial,sans-serif;color:#4675a8;height:16px;padding:0 3px}.detail-page #helpdoc-tag a.helpdoc-breadcrumb{border-right:1px solid black}.detail-page .helpdoc-element a:link,.detail-page .helpdoc-element a:hover,.detail-page .helpdoc-element a:visited,.detail-page .helpdoc-element a:active{color:#4675a8}.detail-page .helpdoc-text{width:830px;word-wrap:break-word;font:12px arial,sans-serif black}.detail-page #helpdoc-head{margin-top:25px;width:830px}.detail-page #helpdoc-head-icon{float:left;width:80px;height:80px;margin-right:15px}.detail-page #helpdoc-head-description{width:735px;float:right}.detail-page #helpdoc-product-title{float:left}.detail-page #helpdoc-product-os{float:right;width:235px;text-align:right;overflow:hidden;font:12px arial,sans-serif black}.detail-page #helpdoc-head hr{margin-top:5px;margin-bottom:2px}.detail-page #helpdoc-head .seller{overflow:hidden;width:735px;font:12px arial,sans-serif #666}.detail-page #helpdoc-head .description{width:735px;margin-top:10px;height:32px;overflow:hidden;word-wrap:break-word}.detail-page a.helpdoc{color:#1a52ad}.detail-page #helpdoc-head .description p{width:735px;margin:0;overflow:hidden}.detail-page #helpdoc-tag{margin-top:10px}.detail-page .helpdoc-element-hidden{display:none}.detail-page .helpdoc-screenshot{float:left;width:215px;height:173px}.detail-page .helpdoc-img-container{width:180px;height:140px;text-align:center;border:1px solid #ccc}.detail-page .helpdoc-img-container:hover{border:1px solid gray}.detail-page .helpdoc-screenshot-img{max-height:130px;max-width:170px}.helpdoc-img-container .helper{display:inline-block;height:100%;vertical-align:middle}.detail-page .helpdoc-screenshot-label{text-align:center;text-overflow:ellipsis;width:180px;height:15px;float:left;overflow:hidden;margin-top:2px;font:12px arial,sans-serif black}.detail-page .helpdoc-table th{background-color:#f2f2f2}.detail-page .helpdoc-table td,.detail-page .helpdoc-table th{border:1px #b3b3b3 solid}.detail-page .helpdoc-version{margin-bottom:420px}.detail-page .helpdoc-table th{height:35px;text-align:left;padding-left:10px}.detail-page #helpdoc-table-command td{height:100px}.detail-page #helpdoc-table-version td{height:70px}.detail-page .helpdoc-table td img{max-width:80px;max-height:80px;margin:10px}.detail-page .helpdoc-table td p{margin-left:10px}.detail-page #helpdoc-head h1{font:bold 18px arial,sans-serif black;width:500px;overflow:hidden}.detail-page .helpdoc-element h1{font:bold 16px arial,sans-serif black;margin-bottom:5px}.detail-page #right-wrapper{color:#4d4d4d}.helpdoc-page #content{width:830px;margin:0 auto 100px auto;float:none;display:block}.detail-main .drawer{margin:0}.detail-main .subscriber-drawer{float:left}.no-result .purchase-panel{display:block}.no-result .purchase-result{display:none}.result-success .purchase-result-success{display:block}.result-success .purchase-result-not-success{display:none}.result-not-success .purchase-result-success{display:none}.result-not-success .purchase-result-not-success{display:block}.purchase-result-not-success-text a{color:red;text-decoration:underline}.multi-purchase-input-error{background:darksalmon!important}.purchase-panel{margin-top:5px}.purchase-panel>.purchase-action{margin-top:5px}.side-panel>span{font-size:14px}.purchase-panel #multi-purchase-btn{width:100%}.price-qty-total>.purchase-subtotal{font-weight:bold;font-size:14px}.purchase-action>.ui-button{width:100px;height:26px;border-radius:3px;font-size:14px;line-height:25px}.qty-purchased-limit>.off-button{background:url(../images/buttons/close_13.png) no-repeat 0 0;width:13px;height:13px;float:right;cursor:pointer}.qty-to-purchase{margin-top:10px}.qty-to-purchase-title{float:left;margin-right:5px;line-height:24px}.price-qty-total .stepper-input{float:left}.purchase-result-success-text{color:green}#multi-purchase-input{max-width:45px;padding:2px;text-align:center;margin-bottom:15px}.purchase-result-not-success-text{color:red}.purchase-result-info{margin:12px 0}.purchase-result-actions a{color:#1a52ad;cursor:pointer}.purchase-result-actions a:hover{color:#3d87ff}.purchase-result{margin-top:5px}.dealer-code{margin-top:10px}.dealer-code-title{float:left;margin-right:24px;line-height:24px}#dealer-code-input{max-width:45px;padding:2px;margin-bottom:4px}.dealer-code .explanation{display:inline-block;font-size:11px;color:#969696}.detail-page .dropdown.dropdown-wishlist{width:100%;margin-top:8px;border:0;box-shadow:none}.purchase-panel>.purchase-action{width:100%;border:0}#purchase>.dropdown-wishlist .dropdown-toggle{border:1px solid #29abe2;color:#29abe2;background:#fff;margin-top:0}.detail-page .purchase-container .dropdown-toggle .caret{border-top:4px solid #29abe2;position:relative;left:30%}.detail-page .purchase-container .dropdown-wishlist .dropdown-menu{border:1px solid #29abe2;color:#29abe2;background:#fff;text-align:center;height:inherit;margin-top:28px;color:#29abe2;border-top:0}.dropdown-wishlist .dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{background:0}.detail-page .purchase-container .dropdown-wishlist .divider{border-bottom:1px solid #29abe2;background-color:#fff;padding:0}.detail-page .purchase-container .dropdown-wishlist .dropdown-menu a{color:#29abe2}.side-panel .modal-header{border:0}.side-panel .modal-header h3{background:0;color:#29abe2;border:0;font-weight:700}.side-panel .modal-body .img-wrapper{padding-right:10px}.side-panel .modal-body input{width:97%;border:1px solid #29abe2}.side-panel .modal-footer{background:0;border:0}.side-panel .modal-footer .text-info{width:48%;background:0;border:1px solid #29abe2;color:#29abe2}.side-panel .modal-footer .btn-primary{width:49%;background:#29abe2}.side-panel #purchase #wishlistsmodel .price-str{font-size:20px;margin-top:14px}.pagination-content{display:inline-flex;display:-ms-flexbox;padding:0;border:1px solid #b3b3b3;border-radius:7px;background:white;height:24px}.pagination-content li.beginning-dots,.pagination-content li.final-dots{float:left;width:18px;line-height:20px;padding:0 6px;margin:0;text-align:center}.pagination-content li.beginning-dots:hover,.pagination-content li.final-dots:hover{background:0}.pagination-content li.pag,.pagination-content li.prev,.pagination-content li.next{float:left;width:22px;height:22px;line-height:20px;padding:2px 0 0 0;text-align:center;cursor:pointer}.pagination-content li.first{border-top-left-radius:7px;border-bottom-left-radius:7px}.pagination-content li.last{border-top-right-radius:7px;border-bottom-right-radius:7px}.pagination-content li.leftborder-pageitem{border-left:1px solid #b3b3b3}.pagination-content li.pag:hover,.pagination-content li.prev:hover,.pagination-content li.next:hover{background:#DDD;border-color:#999}.pagination-content li.current a{color:#29abe2}.pagination-content li a{color:#808080;display:block}.page_input_container{margin:4px 0 0 20px}.page_input_label{margin:3px 0 0 0;float:left}.page_input_textbox{float:left;height:16px;width:26px;border:1px solid #cecece;margin:0 4px 0 4px;padding:1px;text-align:center;height:10px!important}.page_input_go{float:left;border:1px solid #cecece;padding:2px 5px 1px 5px;height:15px;background:#f7f7f7}.page_input_go span,.page_input_go span:visited,.page_input_go span:hover{color:#4d4d4d}.quick-search-wrapper{margin-bottom:5px;height:22px}.quick-search-wrapper h3{float:left;margin:0 20px 0 0;height:22px;line-height:22px}.quick-search-wrapper .quick-search-form-filter{width:235px;height:22px;float:left}#search-results-extra hr{clear:both;margin:10px 0}.pagination-spinner{float:left;margin:7px;height:16px;width:16px;line-height:16px;display:none}.my-downloads-page#main{margin-bottom:50px}.my-downloads-page #content{width:1000px;display:block;float:none;margin:0 auto}.my-downloads-page .page-title{margin-bottom:30px;margin-left:-132px}.my-downloads-page .description-container{width:200px;word-wrap:break-word;word-break:normal}.my-downloads-page .cancel-subscription{text-align:right}#my-downloads table{margin:10px 0 20px 0;text-align:left;font-size:11px}#my-downloads table td,#my-downloads table thead th{border:0 none;padding:5px;vertical-align:middle}#my-downloads table td{border-left:1px solid #e6e6e6}#my-downloads table td:first-child{border:0}#my-downloads table tr{border-bottom:1px solid #e6e6e6}#my-downloads table td.info-cell{width:170px;min-width:147px}#my-downloads table td.description-cell{width:200px}#my-downloads table td.company-cell,#my-downloads table td.store-cell{width:90px}#my-downloads table td.update-cell{width:80px}#my-downloads table td.purchase-qty-cell{width:100px}#my-downloads table td.info-cell img{width:40px;height:40px;float:left;margin:3px 6px 3px 2px}#my-downloads table td.info-cell .product-info{float:left;width:95px;margin-top:4px}#my-downloads table td.info-cell .product-info a,#my-downloads table td.info-cell .product-info span{display:block;margin-bottom:5px;color:#595959}#my-downloads table td.info-cell .product-info a:focus,#my-downloads table td.info-cell .product-info a:hover{color:#06e}#my-downloads table td.update-cell img{margin:0 2px}#my-downloads table td.update-cell a{color:#1a52ad}#my-downloads table td.update-cell a:hover{color:#3d87ff}#my-downloads table td.help-cell img{margin:0 6px}#my-downloads table caption,#my-downloads h2{font:20px Arial;color:#4d4d4d;margin-bottom:2px;text-align:left}#my-downloads h2{margin-top:10px}#my-downloads h3{font-size:16px;font-weight:normal;color:#333}#my-downloads table thead tr{background:#999}#my-downloads table thead tr th{color:#FFF;text-align:left;font-size:12px}#my-downloads table tbody{color:#595959}#my-downloads table tbody .fullDescription-container p{margin:0 0 5px}#my-downloads table .odd-row{background:#f2f2f2}#my-downloads table .even-row{background:#FFF}.purchase-qty-cell,.purchase-date-cell{text-align:center}.purchase-date-div{width:120px}.purchase-date-span{float:left}.open .purchase-date-more{display:block}.purchase-date-more{display:none}.open .cell-more{display:none}.cell-more{cursor:pointer;display:inline}.open .cell-less{display:inline}.cell-less{cursor:pointer;display:none}td.description-cell .more_less{cursor:pointer;font-weight:bold;text-decoration:underline}.tooltip{display:none;position:absolute;min-height:10px;padding:7px 8px;z-index:84001;color:#666;border:1px solid #808080;border-color:rgba(0,0,0,.5);background-color:#f7f7f7;background:-webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,0.95)),to(rgba(230,230,230,0.95)));background:-webkit-linear-gradient(rgba(255,255,255,0.95),rgba(230,230,230,0.95));background:-moz-linear-gradient(rgba(255,255,255,0.95),rgba(230,230,230,0.95));-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.3);-webkit-box-shadow:0 1px 2px rgba(0,0,0,.3);box-shadow:0 1px 2px rgba(0,0,0,.3);-moz-background-clip:padding;-webkit-background-clip:padding;background-clip:padding-box;max-width:200px}.tooltip .pointer{position:absolute;top:-6px;left:5px;width:100%;height:6px;background:url(../images/icons/tooltip_pointer.png) no-repeat left top}.tooltip.right .pointer{left:auto;right:5px;background-position:right top}.tooltip.visible{display:block}.has_tooltip{cursor:help}#my-downloads table thead tr th.sortable{cursor:pointer}#my-downloads table thead tr th:hover,#my-downloads table thead tr th:focus{background:#575757}#my-downloads table thead tr th:active,#my-downloads table thead tr th.current{background:#3d3d3d}#my-downloads .order-arrow{float:right;margin:5px 3px 5px 5px;background:url(../images/icons/sort_arrow.png) no-repeat;height:4px;width:7px;display:none}#my-downloads .up{background-position:0 -4px}#my-downloads .down{background-position:0 0}#my-downloads table thead tr th.current a.order-arrow{display:block}#my-downloads table thead tr .th-titles{float:left;margin-right:2px}.my-uploads-page{padding-top:20px;width:960px}.my-uploads-page label{cursor:default}.my-uploads-page #content{width:960px;margin-left:122px}#my-published table input{cursor:pointer;background-color:transparent;text-decoration:none;border:0;color:blue}.detail-page-for-publisher#main{width:1260px}.detail-page-for-publisher#main>div{display:inline-block;vertical-align:top;width:18%}.detail-page-for-publisher#main .p-detail-tabs{width:1000px;margin-left:20px}.detail-page-for-publisher#main .p-detail-notification{width:98%}.developer-description #content{width:1280px}.developer-description #content div p{text-align:justify;text-justify:inter-word}.developer-description #content .headline{margin:10px 0;color:#29abe2;font-size:18px;font-weight:normal}.developer-description #content .legal-content{border:1px solid #ccc;padding:15px 30px;overflow-y:auto;height:453px;background:white;margin-bottom:20px}.developer-description #content .legal-content p:first-child{margin-top:0}.developer-description #content .sell-notice-level-1{font-size:16px;font-weight:bold;margin:10px 0;color:#4d4d4d}.developer-description #content .sell-notice-level-2{font-size:16px;font-weight:normal;color:#333}.developer-description #content .sell-notice-level-3{font-size:12px;color:#4d4d4d}.developer-description #content .sell-notice-note{font-style:italic;color:#333;font-size:12px}.developer-description #content ul.list-items{padding-left:20px;color:#4d4d4d}.developer-description #content ul.list-items li{margin:0 0 5px 15px;list-style-type:disc}.developer-description #content .actions{margin-bottom:24px;padding:30px 0;height:33px}.developer-description #content .publish-link{width:150px;padding:5px 0;border:0;font-size:14px;cursor:pointer;text-align:center;color:white}.developer-description #content .back,.developer-description #content .signin_link{width:150px;border:0;padding:5px 0;font-size:14px;cursor:pointer;height:25px;text-align:center;color:white}.developer-description #content .publish-link,.developer-description #content .signin_link{float:right}.grey-button{background:linear-gradient(#666,#2e2e2e);background:-webkit-gradient(linear,left top,left bottom,from(#666),to(#2e2e2e));background:-webkit-linear-gradient(#666,#2e2e2e);background:-moz-linear-gradient(#666,#2e2e2e);background:-o-linear-gradient(#666,#2e2e2e);border:1px solid #303030}.no-cssgradients .grey-button{background:#2e2e2e url(../images/icons/bg-gradient-button-gray.png) repeat-x 0 0}.no-cssgradients .grey-button:hover,.no-cssgradients .grey-button:focus{background-position:0 -32px}.no-cssgradients .grey-button:active{background-position:0 -64px}.no-cssgradients .grey-button:disabled{background-position:0 -78px;cursor:default!important}.no-cssgradients .grey-button[disabled],.no-cssgradients .grey-button[disabled]:hover,.no-cssgradients .grey-button[disabled]:active{background-position:0 -96px;cursor:default!important}.grey-button:hover,.grey-button:focus{background:linear-gradient(#808080,#474747);background:-webkit-gradient(linear,left top,left bottom,from(#808080),to(#474747));background:-webkit-linear-gradient(#808080,#474747);background:-moz-linear-gradient(#808080,#474747)}.grey-button:active{background:linear-gradient(#595959,#1f1f1f);background:-webkit-gradient(linear,left top,left bottom,from(#595959),to(#1f1f1f));background:-webkit-linear-gradient(#595959,#1f1f1f);background:-moz-linear-gradient(#595959,#1f1f1f)}.grey-button:disabled{background:linear-gradient(#a6a6a6,#6e6e6e);background:-webkit-gradient(linear,left top,left bottom,from(#a6a6a6),to(#6e6e6e));background:-webkit-linear-gradient(#a6a6a6,#6e6e6e);background:-moz-linear-gradient(#a6a6a6,#6e6e6e);cursor:default!important}.developer-terms-and-conditions #content{width:1280px}.developer-terms-and-conditions #content .headline{margin:10px 0;color:#4d4d4d;font-size:16pt}.developer-terms-and-conditions #content .legal-content{border:1px solid #bfbfbf;background:white;padding:10px;overflow-y:auto;height:553px}.developer-terms-and-conditions #content .legal-content .legal-left{width:49%;float:left;margin-right:10px;padding-right:10px;border-right:solid 1px}.developer-terms-and-conditions #content .legal-content .legal-right{float:left;width:49%}.developer-terms-and-conditions #content .actions{margin-bottom:30px;padding-top:20px}.developer-terms-and-conditions #content p{color:#4d4d4d}.developer-terms-and-conditions #content .legal-content p:first-child{margin-top:0}.publisher-agreement-item-level-1{margin-left:12px;text-indent:-12px}.publisher-agreement-items-level-2-container p{margin-left:22px;text-indent:-22px}.publisher-agreement-items-level-3-container p{margin-left:52px;text-indent:-42px}.developer-terms-and-conditions #content .exhibit-a{margin-top:50px;text-decoration:underline}.eula-term-1-container p{margin-left:15px;padding-left:15px;text-indent:-15px}.eula-term-2-container p{margin-left:30px}.eula-term-3-container p{margin-left:45px}.developer-terms-and-conditions #content .agree-continue{float:right}.developer-terms-and-conditions #content .legal-form{height:25px}.developer-terms-and-conditions #content .legal-form .not-agree{margin-left:10px}.developer-terms-and-conditions #content .continue{padding:0 20px;font-size:14px;cursor:pointer;text-align:center;line-height:25px;color:white;float:left;background:#29abe2;border:1px #29abe2 solid;width:150px;height:25px}.developer-terms-and-conditions #content .cancel{padding:0 20px;font-size:14px;cursor:pointer;text-align:center;line-height:25px;color:#29abe2;float:left;background:white;border:1px #29abe2 solid;width:115px;height:25px}.developer-terms-and-conditions #content .legal-form .fields{margin-top:5px;line-height:25px;float:left;color:#4d4d4d}.developer-terms-and-conditions #legal-agree{float:left}.developer-terms-and-conditions #content .legal-form .label{display:block;float:left;margin-left:8px;background-color:transparent;color:red;font-weight:normal}.developer-terms-and-conditions #content .legal-form .separator{height:25px;width:1px;border-left:1px solid #a6a6a6;margin:0 8px;float:left}.wizard-navigation ul li span.status{position:absolute;top:24px;right:0;z-index:105;padding:0!important}.wizard-navigation ul li span.status.ok{background:transparent url(../images/icons/wizard_nav_ok.png) no-repeat left center;width:13px;height:16px}.developer-submit-product #content{color:#29abe2;width:1080px;padding-bottom:30px;padding-left:80px}.developer-submit-product label{cursor:default;margin:0;display:inline-block}.developer-submit-product #paymentgateway-settings label{display:block}.developer-submit-product .templates{display:none}.developer-submit-product #content h3.wizard-init{text-align:center;margin-top:190px}.developer-submit-product #content h2{color:#29abe2;margin:15px 0 5px;font-size:18px;float:left;font-weight:normal}.developer-submit-product #content .wizard-navigation{overflow:hidden;width:1080px;position:relative}.developer-submit-product #content .wizard-navigation ul{margin:20px 0 0 0;padding:0;height:27px;float:right;list-style:none}.developer-submit-product #content .wizard-navigation ul li{margin:0;padding:0;list-style:none;cursor:default;visibility:collapse;width:0;float:right}.developer-submit-product .topEmphasis{font-family:Arial;font-size:15px;color:#29abe2;font-weight:bold;margin-bottom:10px}.developer-submit-product #promptFlash,.developer-submit-product #promptFlash a,.developer-submit-product #promptFlash a:hover,.developer-submit-product #promptFlash a:active,.developer-submit-product #promptFlash a:visited{font-family:Arial;font-size:11px;color:#4675a8;font-weight:bold;margin-bottom:5px}.developer-submit-product #content .wizard-navigation ul li span{display:block;padding:5px 20px 5px 0;line-height:17px;font-size:14px;font-weight:normal}.developer-submit-product #content .wizard-navigation ul li.active{visibility:visible;width:auto}.developer-submit-product #content .wizard-side{border-top:1px solid #bfbfbf;border-bottom:1px solid #bfbfbf;border-left:1px solid #bfbfbf;width:152px;background-color:#4d4d4c;height:508px;float:left;color:white}.developer-submit-product #content .wizard-side li.add{display:none}.developer-submit-product #content .wizard-side p{padding:0 8px;margin:0;color:#b2b2b2;font-size:10px}.developer-submit-product #content .wizard-side h4{color:white;padding-left:12px;border-bottom:1px solid #333;margin:0;font-weight:bold;font-size:12px;line-height:27px}.developer-submit-product #content .wizard-side h5{color:white;padding:2px 0 2px 22px;margin:0;font-weight:normal;font-size:10px;line-height:13px}.developer-submit-product #content .wizard-side h5.add-language{background:transparent url(../images/icons/add_remove_language.png) no-repeat -400px center}.developer-submit-product #content .wizard-side h5.remove-language{background:transparent url(../images/icons/add_remove_language.png) no-repeat 0 center}.developer-submit-product #content .wizard-side ul{margin:0;padding:0}.developer-submit-product #content .wizard-side ul li{color:white;margin:0;padding:8px}.developer-submit-product #content .wizard-side ul li.selected{color:#fff;font-size:12px;background:#496b9b url(../images/icons/selected_language.png) no-repeat right center;border-bottom:1px solid #333}.developer-submit-product #content .wizard-side ul li.remove,.developer-submit-product #content .wizard-side ul li.template{display:none}.developer-submit-product #content .wizard-side .wizard-progress{height:20px;line-height:20px}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar{width:75px;height:6px;padding:2px;background-color:#b7b7b7;float:left;margin-top:8px;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar{display:block;height:6px;width:0;background-color:#666;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.developer-submit-product #VersionListDiv{float:left;padding-bottom:5px;width:100%}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar.red{background-image:-webkit-linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%);background-image:-moz-linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%);background-image:-ms-linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%);background-image:linear-gradient(bottom,#c0262c 0,#ec1b23 50%,#c0262c 100%)}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar.orange{background-image:-webkit-linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%);background-image:-moz-linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%);background-image:-ms-linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%);background-image:linear-gradient(bottom,#f6721d 0,#f3a22b 50%,#f6721d 100%)}.developer-submit-product #content .wizard-side .wizard-progress .progress-bar .bar.green{background-image:-webkit-linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%);background-image:-moz-linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%);background-image:-ms-linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%);background-image:linear-gradient(bottom,#38b448 0,#8ac53e 50%,#38b448 100%)}.developer-submit-product #content .wizard-side .wizard-progress .progress-percentage{float:left;padding:3px 0 0 7px}.developer-submit-product #content .wizard-side .wizard-progress .progress-help{background:url(../images/icons/help.png) no-repeat 0 0;width:16px;height:16px;float:left;margin:5px 0 0 9px}.developer-submit-product #content .wizard-content{border:1px solid #ccc;overflow-y:auto;overflow-x:hidden;width:1040px;padding:0 20px 10px 20px;float:left;background-color:#fff;position:relative}.developer-submit-product .wizard-content input[type="text"],.developer-submit-product .wizard-content textarea{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.developer-submit-product #content .wizard-actions{margin-top:15px;float:left;width:1080px}.developer-submit-product #content .wizard-actions input[type="button"],.developer-submit-product #content .wizard-actions a{width:auto;padding:0 20px;border:0;font-size:14px;cursor:pointer;height:25px;text-align:center;line-height:25px;color:white}.developer-submit-product #content .wizard-actions .cancel{float:left;color:#29abe2;background:white;border:1px #29abe2 solid;width:150px;height:25px}.developer-submit-product #content .wizard-actions .back{float:left;display:none}.developer-submit-product #content .wizard-actions .save{float:right;width:150px;height:25px}.developer-submit-product #content .wizard-actions .continue{float:right;margin-left:8px;width:150px;height:25px}.developer-submit-product #content .wizard-actions .backtosummary,.developer-submit-product #content .wizard-actions .submit,.developer-submit-product #content .wizard-actions .preview{float:right;display:none;margin-left:8px}.developer-submit-product #content .finish-link{width:auto;padding:0 20px;border:0;font-size:14px;cursor:pointer;height:25px;text-align:center;line-height:25px;color:white}.remindErrorDiv{margin-bottom:10px}.remindErrorDiv .errorRemind a{font-size:13px;font-weight:bold;color:red;padding-bottom:5px;text-decoration:underline}#publish-step2-products .compatibility-des-sep{margin:0}#publish-step2-products .compatibility-des{width:790px}#publish-step2-products .families-products td:first-child{width:200px}#publish-step2-products table.version-grid{width:100%}.fancy-layer-image{content:url(../images/icons/ajax-loader400.gif);width:30px}#fancy-layer{height:100px}#fancy-layer.overlay_window{background:white}.wizard-tab{font-size:12px;position:relative}.no_float{float:none!important}.wizard-tab h4{float:left;margin-bottom:5px}#wizard-help-documentation h4{float:left}#wizard-help-documentation>span.explanation{margin:0}.wizard-tab h4+span.explanation{margin-bottom:5px}.wizard-tab #contact-info+span.explanation{display:inline-block}.wizard-tab span.required{display:inline;color:Red;font-weight:bold}.wizard-tab .explanation{display:inline-block;color:#666;font-weight:normal;font-size:11px}.command_tools .explanation{display:block;color:#666;font-weight:normal;font-size:11px}.command_tools .commandName{width:400px}.command_tools .sub-title{display:block}.command_tools textarea{width:400px}.thumbnail-preview .browse-button{float:left;margin-right:5px;font-size:12px;height:25px;width:150px}.file-info .explanation{display:inline-block;color:#666;font-weight:normal;font-size:11px}#privacyDetail{font-size:15px}#privacyDetail ul{padding:0;margin-left:4px}#privacyDetail li{margin:8px;list-style:none}#publish-step2-products .explanation,#publish-step2-categories .explanation{float:left;display:inline;width:790px}.wizard-tab span.error,#contact-info span.error{display:none;margin:2px 27px 2px 15px;color:#c80000;font-size:11px;background:transparent url(../images/icons/wizard_error.png) no-repeat left center;padding-left:14px}#contact-info span.error{float:none;margin-right:2px;margin-top:4px}.wizard-tab .text span.error{margin:2px 0 2px 0;float:none}#contact-info span.error.visible,.wizard-tab span.error.visible{display:inline}.wizard-tab .separator{display:block;height:10px}#publish-step2-products .separator,#publish-step2-categories .separator{display:inline-block;width:790px;height:20px}.wizard-tab textarea,.wizard-tab input[type="text"]{width:100%;margin-bottom:1px;border:1px solid #bbb;padding:2px;display:block}.wizard-tab .command_tools textarea,.wizard-tab .command_tools input[type="text"]{width:772px}.wizard-tab textarea.error,.wizard-tab input[type="text"].error{border:1px solid #c80000}.wizard-tab textarea{resize:none}#wizard-help-documentation textarea{display:inline}.wizard-tab input[type="radio"]{display:inline}.wizard-tab input[type="checkbox"]{display:inline;margin-right:10px}.wizard-tab #prices label{margin:10px 0;cursor:pointer}.wizard-tab h5{font-weight:normal;margin:0}#app-file>*:not(label){margin-left:0;width:auto}#app-file>textarea{width:97%;margin-top:5px}#app-file>label{font-size:12px}#app-file>label>input{position:relative;top:1px;margin-right:4px}.wizard-tab h4+.file-uploader{margin-top:10px}.wizard-tab .file-uploader .file{width:auto;padding:4px 4px 4px 0;background-color:white;min-height:25px;margin:5px 0}.wizard-tab .file-uploader .file .plupload input{cursor:pointer}.wizard-tab .file-uploader .file .plupload input[disabled]{display:none}.wizard-tab .file-uploader .file .file-info .thumbnail{float:left}.wizard-tab .file-uploader .file .file-info .file-name,.wizard-tab .file-uploader .file .file-info .file-size{float:left;padding:6px 10px 4px}.wizard-tab .file-uploader .file[data-uploader-state="uploading"] .file-info .file-name{max-width:135px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="uploading"],.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="queuedOnHold"],.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="uploadedOnHold"],.wizard-tab #app-screenshot.file-uploader .file[data-uploader-state="queued"]{min-height:75px}.wizard-tab .file-uploader .file .file-info .upload-progress{width:280px;height:20px;line-height:20px;position:absolute;right:115px}.wizard-tab .file-uploader .file .file-info .progress-bar{width:230px;height:6px;padding:2px;background-color:white;float:left;margin-top:8px;-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.wizard-tab .file-uploader .file .file-info .progress-bar .bar{display:block;height:6px;width:0;min-width:1%;background-color:white;background-image:-webkit-linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);background-image:-moz-linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);background-image:-ms-linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);background-image:linear-gradient(bottom,#29abe2 0,#6ac6ed 50%,#29abe2 100%);-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px}.wizard-tab .file-uploader .file .file-info .progress-percentage{float:left;padding:3px 0 0 10px}.wizard-tab .upload-button,.wizard-tab .cancel-button,.wizard-tab .remove-button{float:right;width:100px}.wizard-tab .browse-button{float:left;margin-right:5px;font-size:12px;height:25px;width:150px}.wizard-tab .uploader-loading .browse-button{visibility:hidden}#app-screenshot .thumbnail{width:205px;min-height:120px;display:none}.screenshot_tools{position:absolute;right:5px;top:40px;left:219px;bottom:5px}.screenshot_tools .description_container{position:absolute;left:0;right:0}.screenshot_tools input[type="checkbox"]{float:left;margin-right:5px;padding:0}.screenshot_tools .description_container .description{width:519px;margin:0}#wizard-help-documentation .cert-span{margin-top:3px;display:block;float:none;margin-left:0}#wizard-help-documentation .cert-span .cert-explanation{margin-left:23px}#wizard-help-documentation .cert-image{margin-bottom:5px}#wizard-help-documentation h4+span.cert-explanation{margin-top:0;margin-bottom:8px}#wizard-help-documentation .cert-explanation a,#wizard-help-documentation .cert-explanation a:link,#wizard-help-documentation .cert-explanation a:hover,#wizard-help-documentation .cert-explanation a:active,#wizard-help-documentation .cert-explanation a:visited{color:#29abe2}#wizard-file-uploading .errors,wizard-help-documentation .errors{position:relative;float:right}#publish-step2-companyandprice #prices,#publish-step2-companyandprice #applogintypes{display:block;margin:5px 0 5px}#publish-step2-companyandprice input.priceinput{width:150px;display:inline}#wizard-app-information #app-versions{width:100%}#wizard-app-information #app-versions .version .remove,#wizard-help-documentation #app-commands .command .remove-command{background:url(../images/buttons/close_24.png) no-repeat 0 0;width:24px;height:24px;top:-7px;position:absolute;right:-12px;cursor:pointer}#version-changed-input .mceEditor{margin-bottom:10px}#wizard-help-documentation #app-commands .command .remove-command.with_spinner{background:0}.file-info{position:relative}.file-info .remove-button+.with_spinner{display:inline-block;right:5px;position:absolute;top:5px}#wizard-app-information #app-versions .version.template,#wizard-help-documentation #app-commands .template{display:none;position:relative}#wizard-app-information #app-versions .version{margin-top:10px}#wizard-app-information #app-versions .version .number input{width:120px;margin-top:5px}#wizard-app-information #app-versions .version .description textarea{width:560px;margin-top:5px}#wizard-app-information #app-versions .version .number{width:145px;float:left}#wizard-app-information #app-versions .description{float:left;width:100%}#wizard-app-information .new-version{width:auto;margin-top:6px;cursor:pointer;text-align:center}#wizard-app-information #app-versions .version .remove{background:url(../images/buttons/close_24.png) no-repeat 0 0;width:24px;height:24px;top:-7px;position:absolute;right:-12px;cursor:pointer}#wizard-app-information #app-versions .version.template{display:none;position:relative}#publish-step2-companyandprice #payment-settings{display:none}#publish-step2-companyandprice{margin-bottom:14px}#wizard-file-uploading .add-screenshot-container{margin-top:6px}#wizard-file-uploading .add-screenshot-container>*{vertical-align:middle;margin-bottom:10px}.wizard-app-compatibility input[type="checkbox"]{margin:0 5px 0 5px;position:relative;top:2px}table.expandable-grid tr.title{background-color:#e5e5e5;border-bottom:1px solid #797979}table.expandable-grid tr.title td{padding-left:10px;font-size:13px;font-weight:bold;height:30px;line-height:30px}table.expandable-grid tr.expansor{border-bottom:0 solid #797979}table.expandable-grid tr.expansor.expanded{border-bottom:0}table.expandable-grid tr.expandable{border-bottom:0 solid #797979}table.expandable-grid{margin-top:5px;float:left;width:100%;border:0 solid #797979;border-collapse:collapse}table.expandable-grid tr{width:100%;border-collapse:collapse}table.version-grid{width:100%;margin:5px 0 10px 0}table.version-grid tr{border:1px #29abe2 solid}table.version-grid thead .store-version{width:80px}table.expandable-grid tr.expansor td{height:20px;cursor:pointer}table.expandable-grid tr.expansor td span{font-size:13px}table.expandable-grid tr.expansor.expanded td span div.arrow{background:url(../images/icons/expand-collapse-sprite.png) no-repeat top right}table.expandable-grid tr.expansor td span div.arrow{background:url(../images/icons/expand-collapse-sprite.png) no-repeat top left;margin:0 5px 0 5px;width:13px;height:13px;display:inline-block}#wizard-app-categories #app-families,#wizard-app-categories #store-list{margin:8px 0 8px}#wizard-app-categories #store-list{width:755px}#wizard-app-categories #store-list .store-title{width:200px}#wizard-app-categories .families-products .store-title.disabled{color:#b1b1b1}#publish-step2-categories .families-products td.label{color:black;background:transparent;text-shadow:none}#publish-step2-categories table.version-grid{margin-top:2px}#wizard-app-categories #store-list .store-version{width:100px}#wizard-app-categories #store-list tbody tr:nth-child(even){background-color:#e8e8e8}#wizard-app-categories #recommend{margin-top:10px;background-color:#e8e8e8;padding:5px}#wizard-app-categories .othercategory-container{display:inline-block;margin-top:20px}#wizard-help-documentation #app-commands{width:100%}#wizard-help-documentation #app-commands .command{margin-top:10px;padding:5px;position:relative}#wizard-help-documentation #app-commands .command h3{margin:0;font-weight:normal}#wizard-help-documentation #app-commands .command .file{width:717px}#wizard-help-documentation #app-commands .command .save-command{right:7px;bottom:7px}#wizard-help-documentation .new-command{width:150px;margin-top:5px;cursor:pointer;height:25px;text-align:center;line-height:25px;font-size:12px;display:block}#wizard-help-documentation .mceEditor{margin-top:5px;display:block}#wizard-app-summary .info{min-height:20px;padding:2px 5px;line-height:20px}#wizard-app-summary .info:nth-child(even){background-color:#e8e8e8}#wizard-app-summary .info .description{float:left;width:210px;font-weight:normal;color:#666}#wizard-app-summary .info>*{display:inline-block;margin-left:10px;color:black}#wizard-app-summary .info .value p{margin:0}#wizard-app-summary .summary-icon{width:80px;height:80px}#wizard-app-summary .summary-screenshot{border:1px #29abe2 solid;width:200px;height:120px}#wizard-app-summary .summary-screenshot img{height:120px}.developer-submit-complete #content{width:940px}.developer-submit-complete #content h1,.developer-submit-complete #content h2{color:#4d4d4d}#footer{border-top:1px solid #c4c4c4;height:38px;line-height:38px;background-color:#f3f3f3;font-size:11px;color:#999}.footer_wrap{margin:0 auto;height:38px;line-height:38px;background:url(../images/icons/adsk_footer_logo.png) no-repeat right center}.footer_wrap .copy{line-height:38px;height:38px;float:left;color:#949494}.copy p{margin:0;padding:0}.footer_wrap .legalese{float:left;list-style-type:none;margin:0;padding:0;height:38px;line-height:38px;padding:0}.footer_wrap .btn-group button{font-size:12px}.footer_wrap .btn-group .dropdown-menu{top:auto;bottom:100%;min-width:80px}.footer_wrap .btn-group .dropdown-menu li{font-size:12px;padding-left:6px}.footer_wrap .btn-group .dropdown-menu li:hover{color:white;background-color:#0081c2}.legalese li{list-style-type:none;margin-left:12px;float:left;cursor:pointer;line-height:38px}.legalese li a{color:#999}.legalese li a:hover,.legalese li:hover{color:#666}.contact_us{font-size:104%;font-weight:bold!important;color:#666}.paynow_button form input[type="submit"]{background:none repeat scroll 0 0 transparent;border:0 none;color:#fff;margin:0;padding:0}#supported_languages{width:400px}#supported_languages ul{padding:0;margin:0}#supported_languages ul li{color:#000;padding-left:25px;line-height:23px;cursor:pointer}.odd{background-color:#fff}.even{background-color:#f2f2f2}#supported_languages ul li:hover{background-color:#dae2ef}#supported_languages ul li.selected{background-color:#8899b4;color:#fff}#accept_terms_section{font-size:12px;width:780px}#accept_terms_section label{display:inline}#accept_terms_section .group_body_container{margin:20px}#accept_terms_section .group_body_container input[type="checkbox"]{margin-right:10px}#accept_terms_section .group_body_container>div{margin-bottom:20px}#accept_terms_section .group_body_container a{color:#039}#accept_terms_section .group_body_container p.legal{font-size:10px;font-style:italic;margin-left:27px}#accept_terms_section .group_body_container .receiveEmail label{display:inline-block;margin-left:23px}#accept_terms_section .group_body_container .receiveEmail input{position:absolute}.input_text_readonly{background-color:#f4f4f4;color:#555}#accept_terms_section .alert{color:red;margin-left:13px}#confirmationPopup button[data-type="Cancel"]{margin-right:6px}#confirmationPopup button{min-width:35px}#wizard-app-categories .families-products td.categorycheck input[type=checkbox]{margin-left:0}#wizard-app-categories .families-products td.label{width:210px}#wizard-app-products .selectAll{font-size:10px}#wizard-app-products .version-grid td label{font-size:12px;white-space:normal;display:inline-block}.faq-page h1{font-size:15pt;margin:15px 0;text-align:center}.faq-page .leftalig-headline{text-align:left}.faq-page h3{font-size:11pt}.faq-page p{margin:0 0 15px}.faq-page ul{margin:0 0 15px;padding:0;list-style:square inside none}.faq-page ul li{list-style:square inside none;margin-top:10px;margin-bottom:3px;margin-left:20px}.faq-page .numbered-ul li{list-style-type:decimal}.faq-page .circled-ul li{list-style-type:disc}.faq-page .empty-circled-ul li{list-style-type:circle}.faq-page ul li img{margin-top:5px}.faq-page .faq_notediv{margin-top:5px;margin-bottom:5px;border-bottom:1px solid #5b9bd5;border-top:1px solid #5b9bd5;color:#5b9bd5;padding:5px}.faq-page .cancel_subscription ol,.faq-page .cancel_subscription ol li{list-style:decimal!important}.faq-page .cancel_subscription ul,.faq-page .cancel_subscription ul li{list-style:disc!important}.faq-page .cancel_subscription ul{padding-left:40px!important}#back-to-top,#back-to-top:visited{margin:7px 0 7px 0;text-align:center;float:left;color:#369}.strikeout-price{text-decoration:line-through;vertical-align:middle;font-size:10px;color:#808080;padding:0;margin-right:15px;display:inline;clear:both}.product-badge-div-placeholder{margin:1px 0 1px 0;height:16px}#detail-info span.subscriptionDes{vertical-align:middle;font-size:12px;float:right}.subscriptionBadge{float:none;position:relative;width:16px;height:16px;margin:0}.big-subscriptionbadge{width:24px;height:24px}.badge-popup-div{position:absolute;display:none;left:-82px;width:180px;font-size:10px;overflow:hidden;z-index:9999;text-align:center}.subscriber-pop-up{left:0;top:10px}.big-badge-popup-offset{left:-78px}.badge-popup-content-div{border-style:solid;border-width:0 1px 1px 1px;border-color:#6d6e70;background-color:white;margin:0;padding:10px}.badge-popup-content-div p{margin:0;padding:0;color:#000}.badge-popup-content-div a{color:blue}.badge-popup-header-div{height:0;margin:0;padding:0}.badge-popup-div img.badge-popup-header-img{float:none;height:10px;width:180px;margin:0}.badge-hover-stub:hover .badge-popup-div{display:block}.subscriber-hover-stub,.badge-hover-stub{position:relative}.product-rating-small-bestseller .star-rating{width:13px;height:12px;cursor:default;display:inline-block;background:url(../images/icons/star_small.png) no-repeat 0 0;overflow:hidden;vertical-align:middle;margin:0 0 4px 2px}.product-rating-small-bestseller .star-on{background-position:0 -12px!important}.product-rating-small-bestseller .star-off{background-position:0 0!important}.ellipsis{width:120px;overflow:hidden;text-overflow:ellipsis;-o-text-overflow:ellipsis;-ms-text-overflow:ellipsis;white-space:nowrap;display:inline-block}#restrict_access_wrapper h2{color:#000;font-size:20px;font-weight:normal}#restrict_access_wrapper h3{font-weight:normal;color:#666;font-size:14px;margin:0 0 15px 0}#restrict_access_wrapper label{font-weight:bold}#restrict_access_wrapper #no_passcode_label li{padding-bottom:20px}#restrict_access_wrapper #no_passcode_controls li{padding-bottom:10px}#restrict_access_wrapper .ui-button{width:70px}#restrict_access_wrapper .text-box{width:200px}#restrict_access_wrapper .multi-line{width:400px;height:100px}#restrict_access_wrapper{margin:10px auto;width:900px;padding:10px}#restrict_access_wrapper #left_panel{float:left;width:80px;margin:10px;padding:10px}#restrict_access_wrapper #right_panel{float:left;width:650px;margin:10px;padding:10px}#restrict_access_wrapper #passcode_label{float:left;width:100px;padding:5px;text-align:right;margin-top:5px}#restrict_access_wrapper #passcode_controls{float:left;width:200px;padding:5px}#restrict_access_wrapper #passcode_submit{position:relative;left:115px;top:5px;clear:both}#restrict_access_wrapper #divider{border-top:1px solid #666;margin:20px 0}#restrict_access_wrapper #no_passcode_label{float:left;width:100px;padding:5px;text-align:right;margin-top:5px}#restrict_access_wrapper #no_passcode_controls{float:left;width:200px;padding:5px}#restrict_access_wrapper #no_passcode_submit{position:relative;left:115px;top:5px;clear:both}#restrict_access_wrapper .validation-summary-errors{position:relative;clear:both;left:115px}#restrict_access_wrapper #passcode_description{margin-bottom:0}#restrict_access_wrapper a:link,#restrict_access_wrapper a:visited,#restrict_access_wrapper a:hover{color:#1a52ad}#HealthStatus table{margin:10px 0 20px 0;text-align:left;font-size:11px;width:700px}#HealthStatus table td,#HealthStatus table thead th{padding:5px;vertical-align:middle;text-align:left}div.developer-submit-product span.profile-notice{float:left;color:#666}#app-detail-for-publisher #icon{float:left}#app-detail-for-publisher #detail-info div.title-rating span{float:right;padding-top:2px}#app-detail-for-publisher #detail-info div.description{margin-top:10px}option.disabled{background-color:lightgray}#language-selector-title{color:#29abe2;font-weight:normal;font-family:Arial;font-size:18px;margin-top:20px}#language-os-selector-info{float:left;border:1px #a8a8a8 solid;border-radius:4px;padding:20px 20px 10px 20px;margin:5px 10px 30px 0;background:white}#os-selector-info{float:none}#language-os-selector-desc{clear:both;padding-top:15px;font-size:11px;color:#999;font-family:Arial}#detail .language-os-select,#language-os-selector-info .language-os-select{width:130px;height:28px;padding-left:8px;border:1px solid #666;border-radius:2px;margin-right:10px}#language-os-selector-info .language-selector-group .language-selector-title,#os-selector-info .os-selector-title{margin-right:10px;color:#29abe2;font-family:Arial;font-size:20px}#language-os-selector-info .language-selector-group{float:left}#detail .language-os-select option,#language-os-selector-info .language-os-select option{line-height:20px;color:#000;font-family:Arial!important;font-size:12px!important}#language-os-selector-info separator span{color:#666;font-weight:normal;font-family:Arial;font-size:11px}.language-selector-cancelButton{height:31px;width:100px;float:left;font-weight:normal;font-family:Arial;font-size:14px}.language-selector-continueButton{height:31px;width:100px;float:right;margin-right:10px;color:#fff;font-weight:normal;font-family:Arial;font-size:14px}#action-wrapper .flat-button,#app-detail-for-publisher{width:230px;float:left;margin-bottom:13px}#action-wrapper span#action-link{margin-left:10px}#my-published .product-info{width:150px;float:left}#my-published .info-cell>div{display:inline-block}#my-published .image-info{width:58px;height:58px;float:left;margin-right:6px}#my-published .product-info a.details_link{width:150px}#my-published .product-info div.details_div{height:16px}#my-published a.publish-link{display:block;width:160px;height:31px}#apps-description{margin:2px 0 2px 0}.product-info .details_dropdownul{margin-top:0;padding:0}.product-info .details_dropdownul .drop_down{padding-top:5px}.product-info .details_dropdownul .live_version_info,.product-info .details_dropdownul .preview_version_info{cursor:default;padding-right:10px;background:url(../images/buttons/btn_popup_sort.png) no-repeat right 7px}#my-published #published-products td.language-cell div.live_version_info,#my-published #published-products td.language-cell div.preview_version_info{height:40px;overflow:hidden}#my-published .has_preview_version .live_version_info{display:none}.keyword-font{font-weight:bold;font-size:13px;color:#000}.normal-font{font-size:13px;color:#595959;word-wrap:break-word}.link-font{font-family:Arial;font-size:12px;color:#4675a8}.cash-font{font-family:Arial;font-size:16px;color:#000}.submit-font{font-family:Arial;font-size:12px;color:#fff}.description-font{font-family:Arial;font-size:11px;color:#666}.learn-more-font{font-family:Arial;font-size:11px;color:#4675a8;margin-bottom:7px}.detail-page #detail .gotoUrl,.detail-page #detail #detailosselector{height:28px;width:130px;border-color:#a8a8a8;border-radius:2px;background:linear-gradient(#f9f9f9,#d5d5d5);color:#000;font-weight:normal;font-family:Arial;font-size:12px}#store-management{width:900px;margin:0 auto;min-height:1200px}#store-management h3,#store-management .show-top-title{float:left}#store-management h1{margin:33px 0 25px}#store-management h3,#store-management .show-top-title{display:inline;line-height:30px}@media only screen and (max-width:780px){#store-management{margin:5%;width:90%}}#store-management .section{margin:20px 0}#store-management #selection.section{height:50px}#store-management .section .resp-content-div ul.sortable{margin-top:40px}#horizontalTab .resp-tabs-container{margin:0 7px 15px 0}#horizontalTab .settings-button{float:right;margin:5px 10px 5px 10px}#storeActions input{margin:5px}#store-management .special-group-widget-img{float:left;margin-right:7px}.selection-div{display:inline;margin-right:10px}.selection-div *{font-size:12px}.selection-div select{width:130px}#languageSelection{margin-left:10px}#store-management ul{list-style-type:none;margin:0;padding:0;margin-bottom:10px}#store-management .sortable li{float:left;width:180px;height:100px;margin:10px 10px;background:#ddd;border:1px solid lightgray;padding:1px;border-radius:5px}#store-management .sortable li:hover{border:1px solid #2a6496}#store-management li#draggable{float:left}#store-management .store-apps-container .sortable{width:650px;min-height:900px}#store-management .store-apps-container .sortable img{width:80px;height:80px;float:left}#store-management div.product-info{float:left;width:98px;position:relative;top:-20px;padding-left:2px}#store-management .publisher-name{display:block;overflow:hidden;width:98px;height:15px;font-weight:bold}#store-management #visible-settings{display:inline;font-weight:bold;font-size:14px;margin-left:10px}#store-management #select-app{display:inline;font-weight:bold;font-size:14px}#store-management #select-app{float:right;margin-right:80px}#store-management #select-app input{display:block;float:right}#store-management #select-app span{display:block}#store-management .button{width:auto;border:0;font-size:14px;cursor:pointer;height:24px;text-align:center;color:white}#store-management .store-action-input{width:70px}#store-management #store-reset-input{width:auto}#store-management span.add-app-hint-hidden{visibility:hidden;text-align:center}#store-management span.add-app-hint-visible{visibility:visible;text-align:center}#store-management .app-name{overflow:hidden;width:98px;height:62px;line-height:16px;word-wrap:break-word}.resp-vtabs .resp-tabs-list li span,.resp-vtabs .resp-tabs-list .input_widget_title{float:left;max-width:172px;width:172px}.resp-vtabs .resp-tabs-list .input_widget_title{display:none}#store-images .file{background:lightgray;margin-bottom:10px;height:205px;width:900px}#store-images .thumbnail,#store-images .thumbnail img{max-width:400px;max-height:165px}#store-images .storeimage_tools{position:absolute;top:5px;left:415px}#store-images .storeimage_tools label{margin-bottom:0}#store-images .storeimage_tools input{margin-bottom:2px;width:450px}#store-images .storeimage_tools textarea{margin-bottom:2px;width:450px}.fancy-chosen-tr,.fancy-chosen-tr span{color:red!important}.fancy-remove-app{visibility:hidden;position:relative;top:-10px;left:-10px;width:24px;height:24px;z-index:1;background-image:url(../images/buttons/close_24.png);cursor:pointer}.remove-widget{float:left;width:15px;height:15px;background:url(../images/buttons/widgetgroup_buttons.png) no-repeat -15px 0;cursor:pointer}.wg_edit-hidden,.wg_edit-widget,.eg-edit-widget{visibility:hidden;float:left;width:15px;height:15px;background:url(../images/buttons/widgetgroup_buttons.png) no-repeat 0 0;cursor:pointer;margin-right:5px;margin-left:5px}.wg_edit-accept,.eg-edit-accept{display:none;float:left;width:15px;height:15px;background:url(../images/buttons/widgetgroup_buttons.png) no-repeat -30px 0;cursor:pointer;margin-right:5px;margin-left:5px}.eg-edit-widget,.eg-edit-accept{float:right}.eg-name-input{width:140px;float:left;margin-bottom:0}#search-fancy-iframe{width:1300px;height:800px}#search-fancy-iframe thead{text-align:left;font-size:13px;border:1px solid #797979;background:gray;color:white}#search-fancy-iframe table td{border:1px solid #797979;padding:8px;vertical-align:middle}.fancy-search-main{height:760px;overflow-y:scroll}#result-list-div thead{text-align:left;font-size:13px;color:white;background:#999}#result-list-div th{height:25px;border:1px gray solid}#result-list-div td{border:1px gray solid;height:45px;vertical-align:middle}#result-list-div th:hover{background:#575757}#result-list-div .row-odd{background:#ededed}#result-list-div{width:100%}.fancy-compatibility{float:left;width:190px}.fancy-compatibility-visible{display:inline}.fancy-compatibility-hidden{display:none}.fancy-show-option,span.fancy-show-option{width:180px;float:left;cursor:pointer;color:#4675a8!important}.copy-settings{margin:10px 0}#copy-settings-info{color:red}#copy-settings-title{font-weight:bold}.fancy-copy-tabs{margin-right:5px}#copy-settings-tabs-title{font-weight:bold}.container-with-fixed-footer{margin-bottom:39px}#analytics-report{width:1370px;position:relative}#analytics-report #myTab>li>a{color:black}#analytics-report #selection .selection-div>h3{line-height:38px;color:#333;font-size:14px;font-weight:bold;margin-right:10px}#analytics-report #selection #languageSelection .dropdown{width:100px}#analytics-report #selection .selection-div>h3,#analytics-report #selection .selection-div>div{float:left}#analytics-report #selection .radio-wrapper{float:right}#analytics-report #selection #go{float:right;margin-left:20px;height:38px}#analytics-report #selection .recent-wrapper{float:left}#analytics-report #selection .radio-wrapper input[type="radio"]{float:left;margin-top:14px;margin-right:5px}#analytics-report #selection .radio-wrapper>span,#analytics-report #selection .radio-wrapper .recent-wrapper>span{line-height:40px;font-size:14px;color:#333;float:left;margin-right:5px}#analytics-report #selection .or{float:right;font-size:14px;font-weight:bold;line-height:40px;margin:0 10px}#analytics-report #selection .recent-wrapper .dropdown,#analytics-report #selection .recent-wrapper h3{float:left}#analytics-report #selection .recent-wrapper h3{line-height:38px;font-size:14px;color:#333;font-weight:normal}#analytics-report #selection .selection-div{float:left}#analytics-report #selection .input-daterange{float:left}#analytics-report #selection .input-daterange .input-sm{height:30px;margin-bottom:0;width:100px}#analytics-report #selection .input-daterange .input-group-addon{padding:11px 5px;margin-left:-4px}#analytics-report .nav-tabs>li{width:25%;text-align:center}#analytics-report .nav-tabs{padding:0}#analytics-report #info-box{position:absolute;right:0;top:-50px;background-color:#d9edf7;font-size:14px;line-height:30px;width:500px;text-align:center;display:none}#analytics-report .chart_act{cursor:pointer}#analytics-report #Statistics{min-height:1000px}#analytics-report .statistics-chart-div{float:left;margin-right:12px;margin-top:12px;display:flex;display:-moz-flex;display:-ms-flex;display:-webkit-flex}#analytics-report .statistics-detail{margin-top:50px;min-height:500px}#analytics-report .statistics-detail-header .detail-header-wrapper{float:left}#analytics-report .statistics-detail-header #goLineChart{margin-left:30px}#analytics-report .statistics-detail-header #granularity-span{margin-left:30px}#analytics-report .statistics-detail-body{padding:10px}#analytics-report .statistics-detail-body .pie-chart{display:block;height:400px;width:650px;float:left;margin:0 5px}#analytics-report .statistics-detail-body .pie-chart-content{position:relative;padding:0;width:100%;height:100%}#analytics-report .statistics-detail-body #line-chart-placeholder{height:400px}#analytics-report .nav-tabs{margin-top:25px}#analytics-report .nav-tabs li{text-align:center;width:200px}#analytics-report .nav-tabs .active{font-weight:bold}#analytics-report .nav-tabs li a,#analytics-report .nav-tabs li a:visited{color:Black}.chart_title{display:-moz-box;display:-webkit-box;display:box;box-pack:center;box-align:center}.chart-title-left .dropdown{height:25px;border:0;background:transparent;width:initial;font-size:13px;font-weight:bold}.chart-title-left .dropdown.focus,.chart-title-left .dropdown:hover{box-shadow:none;border:0}.chart-title-left .dropdown.open>div:last-child{min-width:100px}.chart-title-left .dropdown .selected{margin-left:0}.chart-title-left .dropdown .selected::after{box-shadow:none}.statistics-chart-div .chart_title .chart-title-left{margin-left:0}.chart-title-left .dropdown .carat{right:-12px;top:16px}.title-bar-action{right:0;top:0;position:absolute;margin-right:10px}.title-bar-action a{font-size:12px;font-weight:lighter;color:#468eb2}.analytic_chart_FullWidth,.analytic_chart_FullWidth .chart_title{width:100%}.analytic_chart_Middle,.analytic_chart_Middle .chart_title,.analytic_chart_Large,.analytic_chart_Large .chart_title{width:440px}.analytic_chart_Small,.analytic_chart_Small .chart_title{width:213px}.analytic_chart .chart_act{float:right}.analytic_chart .chart_str{font-size:18px;font-weight:bold}.analytic_chart_Middle .chart_contdiv,.analytic_chart_Small .chart_contdiv{height:109px;padding-top:20px;padding-left:10px;padding-right:10px}.analytic_chart_Large .chart_contdiv{height:281px;padding-top:20px;padding-left:10px;padding-right:10px}.analytic_chart_FullWidth .chart_contdiv{height:290px;padding-top:20px;padding-left:10px;padding-right:10px;background:white}.chart_contdiv>a,.chart_contdiv>a:hover,.chart_contdiv>a:visited{color:#468eb2}.analytic_chart_Middle .chart_cont,.analytic_chart_Small .chart_cont{height:62px;margin-bottom:5px}.analytic_chart_Large .chart_cont,.analytic_chart_FullWidth .chart_cont{height:230px;margin-bottom:5px;margin-left:12px}.analytic_chart .chart_title,.top-50-quickview h2{border-bottom:1px solid #29abe2;height:28px;background:#e6e6e6;color:#468eb2;font-weight:bold;font-size:15px;line-height:28px}.analytic_chart .chart_title span{margin-left:10px}.admin-tool-footer{bottom:0;width:100%}#admin_home_title{margin:50px;font-size:18px;text-align:center}.admin_home_element{margin-bottom:10px}#admin_home_content h2{margin-bottom:20px}#comment-management{width:1600px}#comment-management #selection{float:left}#comment-management #searchBar{float:right}#comment-management .section{width:100%;margin:0 10px}#comment-management{margin-bottom:540px}#comment-management a{color:#1a52ad;text-decoration:none}#comment-management select,#comment-management #query-term{margin-top:10px}#comment-management #checkbox-th{text-align:center}#comment-management .title-comment{float:left;width:400px;height:auto;text-overflow:ellipsis;text-align:left;overflow-y:hidden}#comment-management .title-area{width:400px;height:18px;margin:0;font-weight:bold;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}#comment-management .comment-area{width:400px;word-wrap:break-word}#comment-management .comment-area-more{height:auto}#comment-management .comment-area-hide{overflow:hidden;max-height:40px}#comment-management .appname-area{text-align:left;width:200px;word-wrap:break-word}#comment-management .review-author-area{width:130px;word-wrap:break-word}#comment-management .publisher-area{width:130px;word-wrap:break-word}#comment-management .title-comment-td{height:auto;width:400px;padding:5px;text-align:left}#comment-management #actions{margin-bottom:10px}#comment-management td{text-align:center}#comment-management .description{color:Gray;font-size:12px}#comment-management #number-area{margin-bottom:5px}.hidden-element{visibility:hidden}#comment-management .my-modal-note{width:500px;height:300px}#comment-management .action-td{text-align:left}#comment-management .comments-table{font-size:12px}.comment-mangement-hightlight{background-color:lightcoral}#comment-management .tooltip{border:0;background-color:transparent;background:0;box-shadow:none;-moz-box-shadow:none;-webkit-box-shadow:none}#comment-management .note-textarea{height:40px;width:130px;word-wrap:break-word;text-align:left;overflow:hidden;resize:none;margin-bottom:0;border:0;background-color:transparent;box-shadow:none;cursor:default}#comment-management .note{overflow:hidden;height:40px;line-height:20px}#comment-management .note:before{content:"";float:left;width:5px;height:40px}#comment-management .note>*:first-child{float:right;width:100%;margin-left:-5px}#comment-management .note:after{content:"\02026";float:right;position:relative;top:-25px;left:100%;width:3em;margin-left:-3em;padding-right:5px;text-align:right}#comment-management .note-area{text-align:left}#download-entitlement-management{width:1205px;min-height:800px;margin:0 auto}#download-entitlement-management #base h1{font-size:18px;margin:10px 0}#download-entitlement-management #app-name{margin-bottom:20px}#download-entitlement-management #add-new-entitlement{float:left}#download-entitlement-management #add-new-entitlement input{width:100px}#download-entitlement-management #search-form{float:right}#download-entitlement-management #action-search-wrapper{margin-bottom:20px}#add-download-entitlement-input{width:424px;margin:20px 0 10px 0}#add-download-entitlement-form .error-email{color:red}.entitlement-table .notes .display-block{display:block}.entitlement-table .notes .display-none{display:none}.entitlement-table .notes .notes-edit-button,.entitlement-table .notes .notes-cancel,.entitlement-table .notes .notes-save{float:right}#footerloglink{width:120px;height:38px;float:right}.dropdown{font-size:12px;border-radius:0}.search-brief-component .dropdown{width:65px;float:right}#store-management .dropdown{float:left}.detail-page .dropdown{float:left;width:150px;margin-right:5px;padding:0}.dropdown ul{margin:0;padding:0}.dropdown li.focus{background:#29abe1;color:#fff}.dropdown .carat,.dropdown.open .carat{border-width:5px}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:2px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.drawer{background:#f2f2f2;overflow:hidden}.drawer .drawercontent{border:1px solid #ccc;padding:15px;display:none}.drawer.open .drawercontent{display:block}.drawer .normal-text{font:12px/24px arial,sans-serif;color:#000}.drawer .bold-text{font:bold 15px/24px arial,sans-serif;color:#000}.drawer .description-text{font:11px arial,sans-serif;color:#666}.qty-purchased-limit>.qty-limit,.qty-purchased-limit>.qty-purchased{float:left;line-height:15px}.qty-purchased-limit>.qty-limit{padding-top:1px;margin-left:15px}.qty-purchased-limit>.qty-limit-roof{color:red}.purchase-roof{display:none}.drawer .purchase-grid:not(:first-child){margin-left:30px}.drawer.open .drawercontent .subscrib-list{font-style:italic}.waiting-layer{width:398px;height:113px;background:#fff;border:1px solid #4675a8;-moz-box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px;-ms-box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px;-webkit-box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px;box-shadow:rgba(0,0,0,0.25) 1px 1px 8px 3px}.waiting-layer #wrapper{width:370px;margin:auto}.waiting-layer #wrapper p{font-size:14px;color:#666;text-align:left;margin-top:25px}.waiting-layer #loader-wrapper{text-align:center;margin-top:15px}.waiting-layer #loader{width:24px;height:24px}#error-board{width:604px;margin:0 auto 0 auto;min-height:230px;background-color:white;padding:20px;background-image:url("../images/layout/error_board_bg.png");background-repeat:no-repeat;background-position:right top;-moz-box-shadow:1px 1px 3px rgba(0,0,0,0.25);-ms-box-shadow:1px 1px 3px rgba(0,0,0,0.25);-webkit-box-shadow:1px 1px 3px rgba(0,0,0,0.25);box-shadow:1px 1px 3px rgba(0,0,0,0.25)}#error-board-title,#main .opening-soon span{margin-bottom:30px;font-size:48px;color:#033333;line-height:100%}#main .opening-soon span{font-size:42px}#error-board-desc,#main .opening-soon p{font-size:16px;color:#666;line-height:180%}.whats-verified-download-main .headline{font-size:20px;color:#f90}#bluesnap-promotion-landing{display:none;text-align:center}#bluesnap-promotion-landing-text{font-family:'Myriad Pro';font-weight:400;font-size:24px}#bluesnap-promotion-landing-text2{font-family:'Arial Italic','Arial';font-weight:400;font-style:italic;font-size:18px;color:#666}#bluesnap-promotion-landing-banner{width:660px;padding:10px 10px 10px 10px}#bluesnap-promotion-detail{display:inline-block}#bluesnap-promotion-detail-logo-container{height:15px;vertical-align:middle}#bluesnap-promotion-detail-logo-container img{margin-top:15px}#bluesnap-promotion-detail img{height:inherit}#bluesnap-promotion-detail-text{font-family:'Arial Italic','Arial';font-weight:400;font-style:italic;font-size:10px;color:#369;float:right;height:24px}#process-payment-dialog{text-align:center;width:400px;padding:10px 10px 10px 10px}#process-payment-dialog div{margin-top:15px}#process-payment-dialog button{width:180px;height:28px;vertical-align:middle;margin-top:15px;margin-bottom:10px}.top-50-container{width:1200px}.top-50-container>*{width:100%;width:inherit;padding:10px}.horizontal-container{width:100%;display:-ms-flexbox;-ms-flex-pack:center;display:-moz-box;-moz-box-pack:center;-moz-box-align:center;display:-webkit-box;-webkit-box-pack:center;-webkit-box-align:center;display:box;box-pack:center;box-align:center}.top-50-quickview{margin:10px;width:33%}.top-50-quickview h2{padding-left:10px}.top-50-quickview ul{margin:0;padding:0}.top-50-quickview li:first-of-type{font-size:18px}.top-50-quickview li{background:white;padding:5px}.analytic-report-table-container>*{padding:8px}.analytic-report-table-container h1{font-size:18px}.analytic-report-table-container table{margin:10px}.analytic-report-table-container col{width:10%}.analytic-report-table-container td{text-align:left;vertical-align:middle}.analytic-report-table-container th{text-align:left}.analytic-report-table-container tr:nth-child(even){background:#f2f2f2}.analytic-report-table-container table *{padding:5px}.analytic-report-table-container thead{background:#f0f0f0}.statistics-chart-div.full-width{width:100%;position:relative}.file-list td{vertical-align:middle}.file-list label{margin:3px 3px}#featured-apps #result-list li{padding:10px;height:80px;overflow:visible}#featured-apps #result-list li:nth-child(odd){background:#ededed}#result-list{margin:0;padding:0;background:white;border:1px solid #CCC;border-top:0;width:100%}.admin-table table td,.master-table table td{border:1px solid #e6e6e6;height:40px;vertical-align:middle}#analytics-report a.admin-favorite{display:inline-block;height:7px;width:8px;background:url(../images/icons/star_big.png) no-repeat 2px 1px}#analytics-report a.admin-favorite.added{background:url(../images/icons/star_big.png) no-repeat 2px -16px}.search-type-area{height:25px;background:#fff;margin-right:6px;position:relative;display:none}.search-type{font:12px arial;text-align:center;height:25px;line-height:25px;padding-left:15px;padding-right:15px;margin-right:-4px;display:-moz-inline-box;display:inline-block}.search-type:hover{color:#29abe2!important;background:#e6e6e6!important;cursor:pointer}.search-type-unhightlighted{color:#29abe2!important;background:white}.search-type-hightlighted{color:white!important;background:#29abe2!important}.publisher-result-list{margin-left:-20px}.publisher-result-list li{height:130px;background-color:white;margin-right:6px;margin-bottom:6px}.pubsearch-result-row{height:100%;float:left;position:relative}.pubsearch-result-row-left{width:15%}.pubsearch-result-row-middle{margin-left:5px;width:70%}.pubsearch-result-row-right{width:13.5%}.pubsearch-result-image-link{height:98%;width:98%;background-color:white;display:inline-block;text-align:center;margin-right:2px}.pubsearch-result-image-helper{display:inline-block;height:100%;vertical-align:middle}.pubsearch-result-image{vertical-align:middle;display:inline-block;max-height:96%;max-width:96%;overflow:hidden}.pubsearch-result-name{margin-top:3px;font-size:14px;color:#29abe2;width:100%;overflow:hidden}.pubsearch-result-desc{margin-top:3px;font-size:12px;height:56px;width:100%;overflow:hidden}.publisher-consulting-services-region{position:absolute;bottom:-5px}.publisher-consulting-services-label{margin-bottom:3px;font-size:12px;width:100%}.pubsearch-consulting-service{margin-right:2px;float:left;width:auto;font-size:12px;vertical-align:bottom;margin-bottom:5px}.pubsearch-consulting-service-text{background-color:white;color:#29abe2}.pubsearch-result-row-right button{position:absolute!important;color:white;bottom:0;right:0;margin-bottom:6px;padding:5px}.pubsearch-apps-count{font-size:14px;color:#29abe2;font-weight:bold;position:relative;float:right;margin-top:5px;margin-right:2px}.pubsearch-apps-count-label{margin-top:5px;margin-right:5px;font-size:14px;position:relative;float:right}.ad-hide{display:none}.box-ad-hide{margin-left:189px}
\ No newline at end of file
diff --git a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/linux64.png b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/linux64.png
new file mode 100644
index 0000000..9e7f5bf
Binary files /dev/null and b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/linux64.png differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/macos64.png b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/macos64.png
new file mode 100644
index 0000000..8053b36
Binary files /dev/null and b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/macos64.png differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/original_89910fa8-2c30-4376-a905-12c8a003d16b_.png b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/original_89910fa8-2c30-4376-a905-12c8a003d16b_.png
new file mode 100644
index 0000000..65887c5
Binary files /dev/null and b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/original_89910fa8-2c30-4376-a905-12c8a003d16b_.png differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/resized_5ca803cc-8cd1-4cbe-8825-98efaeef156e_.png b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/resized_5ca803cc-8cd1-4cbe-8825-98efaeef156e_.png
new file mode 100644
index 0000000..412ca74
Binary files /dev/null and b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/resized_5ca803cc-8cd1-4cbe-8825-98efaeef156e_.png differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/docs/Resources/win64.png b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/win64.png
new file mode 100644
index 0000000..3f3ee90
Binary files /dev/null and b/2023/scripts/rigging_tools/ngskintools2/docs/Resources/win64.png differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/docs/index.html b/2023/scripts/rigging_tools/ngskintools2/docs/index.html
new file mode 100644
index 0000000..a89a39a
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/docs/index.html
@@ -0,0 +1,353 @@
+
+
+
+
+
+
+ Autodesk App Store - help file
+
+
+
+
+
+
+
ngSkinTools 2
+
+
+
+
Viktoras Makauskas
+
ngSkinTools is a skinning plugin for Autodesk® Maya®, introducing new concepts to character skinning such as layers, any-pose-mirroring, enhanced paint brushes, true smoothing, and more.
Skinning
+layers are a central feature of ngSkinTools. With them, you break your rig down
+into easier manageable parts and edit them separately, then blend everything
+together through layer transparency.
+
They’re
+not just a simple way to make your work more organized - they also physically
+isolate groups of influences from the rest of the rig, so paint and edit
+operations won’t mix-in influences you were not expecting. This also allows you
+to do things that were impossible before: per-layer mirroring, adjusting
+influence weight up/down through layer transparency, blend transferred weights
+with previous weights, to name a few.
+
+
Viewport
+tools
+
Just
+like in the previous version, ngSkinTools brings its own weight painting tools.
+Improving viewport experience is the main focus of V2, and it's complete revamp
+over the previous implementation.
+
+
Selecting
+ influences on screen, a #1 requested feature from users, is nowhere. Just hold
+ “S” and drag over the surface to select dominant influence from that part of
+ the mesh, or hover over a joint pivot to select precisely the joints you
+ want;
+
In
+ addition to the usual surface projection mode for the brush, the new “screen”
+ brush projection mode is useful when you want to quickly set weights for both
+ sides of the mesh;
+
Custom
+ shortcuts while in paint mode allow for quick access to intensity
+presets;
+
Color
+ feedback is now provided through VP2 APIs, greatly improving the performance
+ of displayed meshes.
+
+
Smoothing
+
Keeping
+weights in harmony with each other is not easy. ngSkinTools help you smooth
+weights with the control you need, allowing you to control the intensity, number
+of iterations and effective radius. For very dense meshes, added “iterations”
+argument now allows for the quicker spread of smoothness over larger areas of
+the mesh.
+
The
+“relax” tool from V1 is gone. With major performance rework, you’ll notice that
+simple flood-smoothing is now much faster and should be a near-instant operation
+even with large meshes.
+
The
+opposite “brother” of smooth brush, “sharpen”, is also there - for cases where
+you want to just bring out the dominant influences
+
+
Mirroring
+
Mirroring
+is one of the most frequent automated tasks you might want from your skinning
+tool. With ngSkinTools, you’ll be able to:
+
+
Mirror
+ rigs in any pose; no need to switch to T-pose;
+
Have
+ granular control over left/right/center influences mapping, matching
+ left/right joints by naming convention, joint labels, etc;
+
Easily
+ mirror parts of your rig by leveraging layers;
+
Automatic
+ mirroring of weights to the opposite side as you paint so that you don’t need
+ to get distracted from painting while working on symmetrical layers.
+
+
Layer
+effects
+
With
+the “mirror as a layer effect” feature, ngSkinTools introduce a new concept to
+ngSkinTools - layer effects. This differs from automatic mirroring of weights as
+it’s not directly modifying your layer weights; instead, it’s a post-effect that
+happens in the background buffer. This has multiple benefits, like a much
+cleaner seamline of left/right sides, the ability to tweak mirroring settings
+AFTER weights are painted, etc.
+
+
Compatibility
+
As
+it's predecessor, ngSkinTools2 operates on standard Maya skinCluster (also known
+as “smooth skin”), so no custom nodes will be required to use your rig. The
+plugin has a couple of custom nodes, but they’re only required while you work on
+setting up your skin weights and can be deleted after, so your work should stay
+compatible with most pipelines out there.
+
+
Performance
+
A
+lot of speed improvements have been made since V2, like improving the
+utilization of modern multi-core processors, or eliminating bottlenecks through
+much heavier use of performance profiling. Having a responsive, snappy tool is
+always a pleasure to work with.
+
+
+
+
+
General Usage Instructions
+
The installer from Autodesk App Store loads the application under the Custom shelf.
The installer that ran when you downloaded this plug-in from Autodesk App Store has already installed the plug-in. Windows only: To uninstall this plug-in, simply rerun the installer downloaded, and select the 'Uninstall' button, or you can uninstall it from 'Control Panel\Programs\Programs and Features', just as you would uninstall any other application from your system. The panel on the Plug-ins tab will not be removed until Maya is restarted.
+
+
+
Linux and OSX: To uninstall this plug-in, simply delete the module directory from your system. The panel on the Plug-ins tab will not be removed until Maya is restarted.
+
+
+
Download .msi and run it on your computer. The installation will place files in C:\ProgramData\Autodesk\ApplicationPlugins\ngskintools2 (unless your %ProgramData% the environment variable is different).
+
+
+
Using an autoloader system, nothing needs to be configured additionally. Maya scans autoloader locations for plugins at startup and configures each discovered plugin automatically. The autoloader will create a “ngSkinTools2” shelf with a button to open UI.
+
Now, restart Maya and a new tab ngSkinTools2 should appear on your shelf.
2.0.23 (2021-Mar-12)
+* Fixed: stylus pressure is not updated during the stroke;
+* Fixed: Maya crashes when smoothing an empty layer with "adjust existing influences only";
+* Fixed: (regression) UI is not opening on macOS;
+
+
+
+
+
+ 2.0.23
+
+
+
2.0.23 (2021-Mar-10)
+* Added: adjustable brush size: don't reset to zero when changing brush size in the viewport.
+* Added: randomize influence colors in paint/display settings;
+* Added: layers on/off "eye" button in layers tree UI;
+* Fixed: ngSkinTools will not modify skinCluster's `normalizeWeights` value anymore; for performance boost, you still
+ can disable skinCluster's normalization by setting `normalizeWeights=None`. In "normalizeWeights:interactive"
+ skinCluster mode, Maya will no longer complain that "The weight total would have exceeded 1.0". ngSkinTools will try
+ extra hard to normalize each vertex to a perfect 1.0;
+* Fixed: UI is not displayed correctly on high DPI displays when UI scaling is enabled in Maya;
+
+
+
+
+
+ 2.0.22
+
+
+
2.0.22 (2021-Feb-06)
+ Added: convenience tool for adding influences to existing skin clusters. Select influences, target mesh and select “Tools | Add Influence”;
+ Fixed: weights will now display properly when viewport option “use default material” is turned on;
+ Added: (v1 feature) Limit max influences per vertex before writing to skin cluster;
+ Added: (v1 feature) Prune small weights before writing to skin cluster.
+
+2.0.21 (2021-Jan-11)
+ Added: copy/paste vertex weights between different selections (tab “tools” - “copy component weights/paste average component weights”);
+ Added: tool “fill transparency” - for all empty vertices in a layer, assign weights from closest non-empty vertex;
+ Added: “duplicate layer” operation;
+ Added: “Merge layers” operation: combine selected layers into one.
+
+2.0.20 (2020-Dec-02)
+ Fixed: Linux: crashing on startup
+
+2.0.19 (2020-Nov-28)
+ Added: influences mapping in mirror screen will now allow matching joints by DG connections; if symmetrical joints are linked between themselves with message connections, ngSkinTools will be able to leverage that information when mirroring weights;
+ Added: symmetry mesh: an option to provide an alternative mesh for calculating vertex mapping for mirroring;
+ Fixed: deleting visibility node can crash Maya sometimes, e.g. switching to component mode (F8) while paint tool is active
+
+2.0.18 (2020-Nov-20)
+ Added: “use all joints” option for “weights from closest joint” tool; few internal optimizations to speedup operation;
+ Added: “weights from closest joint” option: create a new layer
+ Fixed: “weights from closest joint”: the tool is only using joints as spots, but not as segments;
+ Fixed: after “weights from closest joint” operation influences list is not refreshed;
+ Fixed: “weights from closest joint”: “assign” button sometimes disabled;
+
+2.0.17 (2020-Nov-19)
+ Fixed: “resume in workspace” error while opening UI
+
+2.0.16 (2020-Nov-15)
+ Added: skin data will be compressed for ngSkinTools data nodes, which should substantially reduce file size for scenes with lots of skinning layers;
+ Added: paint mode intensity sliders are now exponential: “smooth”, “add” and “sharpen” sliders will now be more precise for lower values, and “scale” mode will allow for more precision when setting high values.
+
+2.0.15 (2020-Nov-10)
+ Added: new “Set Weights” tab contains tools to apply weights to vertex/edge/polygon selection instead of painting.
+ Added: a new option for smooth tool - “only adjust existing vertex influences”; when this is turned on, the smooth tool will prevent influences weights spreading across the surface
+ Fixed: layer mirror effects correctly saved/loaded in files;
+ Fixed: mask mirror effect was not correctly used by layer blending engine
+
+2.0.14 (2020-Oct-04)
+ Fixed: occasional crashes when using mirror effect on layers;
+ Additional stability fixes.
+
+2.0.13 (2020-Oct-04)
+ Fixed: minor bug in 2.0.12 blocks UI from opening;
+
+2.0.12 (2020-Oct-03)
+ Added: option to view used influences in influences list;
+ Added: hide “DQ weights” channel in influences list if skin cluster skinning method is not set to “Weight Blended”;
+
+2.0.11 (2020-Oct-01)
+ Fixed: broken Linux builds
+
+2.0.10 (2020-Sep-26)
+ Added: pressing “f” while painting focuses viewport camera to current paint target; for joints and other influences, the current joint pivot is used as camera interest point; when current paint target is a mask, viewport centers around painted values;
+ Fixed: influence mapping UI error if some influences are no joints;
+
+2.0.9 (2020-Sep-11)
+ Fixed: undo paint crashing Maya;
+ Fixed: incorrect brush behavior with multiple viewports open;
+ Fixed: incorrect mesh display / VP2 transparency setting sensitive;
+ Fixed: clearing selection while painting does not update the display of current mesh;
+
+
+
+
+
+
+
+
diff --git a/2023/scripts/rigging_tools/ngskintools2/launcher.py b/2023/scripts/rigging_tools/ngskintools2/launcher.py
new file mode 100644
index 0000000..2199236
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/launcher.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ngSkinTools2 启动器
+用于从工具架快速启动 ngSkinTools2
+"""
+
+import sys
+import os
+
+def LaunchNgSkinTools():
+ """
+ 启动 ngSkinTools2 主界面
+ """
+ try:
+ from maya import cmds, mel
+
+ # 将当前目录添加到 Python 路径,并使用别名
+ # 这样 ngSkinTools2 内部的 "from ngSkinTools2.ui" 就能找到模块
+ current_dir = os.path.dirname(os.path.abspath(__file__))
+ parent_dir = os.path.dirname(current_dir)
+
+ # 添加父目录到路径
+ if parent_dir not in sys.path:
+ sys.path.insert(0, parent_dir)
+
+ # 添加当前目录到路径,作为 ngSkinTools2 模块
+ if current_dir not in sys.path:
+ sys.path.insert(0, current_dir)
+
+ # 在 sys.modules 中创建别名,让 ngSkinTools2 指向 ngskintools2
+ import rigging_tools.ngskintools2 as ngskintools2_module
+ sys.modules['ngSkinTools2'] = ngskintools2_module
+
+ # 查找并添加插件路径
+ # ngSkinTools2 插件在 ngskintools2/plug-ins/2023/ 下
+ plugin_dir = os.path.join(current_dir, 'plug-ins', '2023')
+
+ if os.path.exists(plugin_dir):
+ # 添加插件路径
+ current_plugin_path = os.environ.get('MAYA_PLUG_IN_PATH', '')
+ if plugin_dir not in current_plugin_path:
+ os.environ['MAYA_PLUG_IN_PATH'] = plugin_dir + os.pathsep + current_plugin_path
+
+ # 加载插件
+ if not cmds.pluginInfo('ngSkinTools2', query=True, loaded=True):
+ try:
+ cmds.loadPlugin(os.path.join(plugin_dir, 'ngSkinTools2.mll'))
+ print("ngSkinTools2 plugin loaded successfully")
+ except Exception as plugin_error:
+ print(f"Warning: Could not load ngSkinTools2 plugin: {plugin_error}")
+ else:
+ print(f"Warning: Plugin directory not found: {plugin_dir}")
+
+ # 现在可以导入并打开 UI
+ from rigging_tools.ngskintools2 import open_ui
+ open_ui()
+ print("ngSkinTools2 UI opened successfully")
+ except Exception as e:
+ print(f"Failed to open ngSkinTools2: {e}")
+ import traceback
+ traceback.print_exc()
+
+
+if __name__ == "__main__":
+ LaunchNgSkinTools()
diff --git a/2023/scripts/rigging_tools/ngskintools2/license.txt b/2023/scripts/rigging_tools/ngskintools2/license.txt
new file mode 100644
index 0000000..69c070d
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/license.txt
@@ -0,0 +1,32 @@
+ngSkinTools Software License Agreement.
+
+
+This is a legal agreement between you and ngSkinTools author (Viktoras Makauskas) covering your use of
+ngSkinTools (the "Software").
+
+1) ngSkinTools is provided as freeware.
+
+2) ngSkinTools Software is owned by Viktoras Makauskas and is protected by copyright laws and international
+treaty provisions. Therefore, you must treat the Software like any other copyrighted material.
+
+3) You may not distribute, rent, sub-license or otherwise make available to others the Software or
+documentation or copies thereof, except as expressly permitted in this License without prior written consent
+from ngSkinTools author (Viktoras Makauskas). In the case of an authorized transfer, the transferee must agree
+to be bound by the terms and conditions of this License Agreement.
+
+4) You may not remove any proprietary notices, labels, trademarks on the Software or documentation. You may not
+modify, de-compile, disassemble or reverse engineer the Software.
+
+5) Limited warranty: ngSkinTools software and documentation are "as is" without any warranty as to their
+performance, merchantability or fitness for any particular purpose. The licensee assumes the entire risk as to
+the quality and performance of the software. In no event shall ngSkinTools author or anyone else who has been
+involved in the creation, development, production, or delivery of this software be liable for any direct,
+incidental or consequential damages, such as, but not limited to, loss of anticipated profits, benefits, use,
+or data resulting from the use of this software, or arising out of any breach of warranty.
+
+Copyright (C) 2009-2020 Viktoras Makauskas
+
+http://www.ngskintools.com
+support@ngskintools.com
+
+All rights reserved.
diff --git a/2023/scripts/rigging_tools/ngskintools2/maya_version.py b/2023/scripts/rigging_tools/ngskintools2/maya_version.py
new file mode 100644
index 0000000..d2ff2da
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/maya_version.py
@@ -0,0 +1,10 @@
+MAYA_2018 = 20180000
+MAYA_2019 = 20190000
+MAYA_2020 = 20200000
+MAYA_2021 = 20210000
+
+
+def at_least(version):
+ from maya import cmds
+
+ return cmds.about(api=True) >= version
diff --git a/2023/scripts/rigging_tools/ngskintools2/observableValue.py b/2023/scripts/rigging_tools/ngskintools2/observableValue.py
new file mode 100644
index 0000000..f01c198
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/observableValue.py
@@ -0,0 +1,25 @@
+from ngSkinTools2.api.python_compatibility import Object
+from ngSkinTools2.signal import Signal
+
+
+class Undefined(Object):
+ pass
+
+
+class ObservableValue(Object):
+ def __init__(self, default_value=Undefined):
+ self.value = default_value
+ self.changed = Signal("observable value")
+
+ def set(self, value):
+ self.value = value
+ self.changed.emit()
+
+ def __call__(self, default=Undefined, *args, **kwargs):
+ if self.value != Undefined:
+ return self.value
+
+ if default != Undefined:
+ return default
+
+ raise Exception("using observable value before setting it")
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/__init__.py b/2023/scripts/rigging_tools/ngskintools2/operations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/copy_paste_actions.py b/2023/scripts/rigging_tools/ngskintools2/operations/copy_paste_actions.py
new file mode 100644
index 0000000..916b25b
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/copy_paste_actions.py
@@ -0,0 +1,64 @@
+from ngSkinTools2 import api, signal
+from ngSkinTools2.api import Layer, PasteOperation
+from ngSkinTools2.api.session import Session
+
+
+def action_copy_cut(session, parent, cut):
+ """
+ :type session: Session
+ :type parent: PySide2.QtWidgets.QWidget
+ :type cut: bool
+ """
+ from ngSkinTools2.ui import actions
+
+ def cut_copy_callback():
+ if session.state.selectedSkinCluster is None:
+ return
+ if session.state.currentLayer.layer is None:
+ return
+ influences = session.state.currentLayer.layer.paint_targets
+ operation = api.copy_weights # type: Callable[[Layer, list], None]
+ if cut:
+ operation = api.cut_weights
+
+ operation(session.state.currentLayer.layer, influences)
+
+ operation_name = "Cut" if cut else "Copy"
+ result = actions.define_action(parent, operation_name + " weights to clipboard", callback=cut_copy_callback)
+
+ @signal.on(session.events.currentLayerChanged, session.events.currentInfluenceChanged, qtParent=parent)
+ def on_selection_changed():
+ layer = session.state.currentLayer.layer
+ result.setEnabled(layer is not None and len(layer.paint_targets) > 0)
+
+ return result
+
+
+def action_paste(session, parent, operation):
+ """
+ :type session: Session
+ :type parent: PySide2.QtWidgets.QWidget
+ :type cut: bool
+ """
+ from ngSkinTools2.ui import actions
+
+ def paste_callback():
+ if session.state.currentLayer.layer is None:
+ return
+ influences = session.state.currentLayer.layer.paint_targets
+ api.paste_weights(session.state.currentLayer.layer, operation, influences=influences)
+
+ labels = {
+ PasteOperation.add: 'Paste weights (add to existing)',
+ PasteOperation.subtract: 'Paste weight (subtract from existing)',
+ PasteOperation.replace: 'Paste weights (replace existing)',
+ }
+
+ result = actions.define_action(parent, labels[operation], callback=paste_callback)
+ result.setToolTip("Paste previously copied weights from clipboard")
+
+ @signal.on(session.events.currentLayerChanged)
+ def on_selection_changed():
+ result.setEnabled(session.state.currentLayer.layer is not None)
+
+ return result
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/import_export_actions.py b/2023/scripts/rigging_tools/ngskintools2/operations/import_export_actions.py
new file mode 100644
index 0000000..2a64020
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/import_export_actions.py
@@ -0,0 +1,90 @@
+from ngSkinTools2 import api, signal
+from ngSkinTools2.api.pyside import QtWidgets
+from ngSkinTools2.ui.options import PersistentValue
+
+filter_normal_json = 'JSON files(*.json)'
+filter_compressed = 'Compressed JSON(*.json.gz)'
+file_dialog_filters = ";;".join([filter_normal_json, filter_compressed])
+
+format_map = {
+ filter_normal_json: api.FileFormat.JSON,
+ filter_compressed: api.FileFormat.CompressedJSON,
+}
+
+default_filter = PersistentValue("default_import_filter", default_value=api.FileFormat.JSON)
+
+
+def buildAction_export(session, parent):
+ from ngSkinTools2.ui import actions
+
+ def export_callback():
+ file_name, selected_filter = QtWidgets.QFileDialog.getSaveFileName(
+ parent, "Export to Json", filter=file_dialog_filters, selectedFilter=default_filter.get()
+ )
+ if not file_name:
+ return
+
+ default_filter.set(selected_filter)
+
+ if session.state.layersAvailable:
+ api.export_json(session.state.selectedSkinCluster, file_name, format=format_map[selected_filter])
+
+ result = actions.define_action(
+ parent,
+ "Export Layers to Json...",
+ callback=export_callback,
+ tooltip="Save layer info to external file, suitable for importing weights to different scene/mesh",
+ )
+
+ @signal.on(session.events.targetChanged, qtParent=parent)
+ def update_to_target():
+ result.setEnabled(session.state.layersAvailable)
+
+ update_to_target()
+
+ return result
+
+
+def buildAction_import(session, parent, file_dialog_func=None):
+ from ngSkinTools2.ui import actions
+ from ngSkinTools2.ui.transferDialog import LayersTransfer, UiModel, open
+
+ def default_file_dialog_func():
+ file_name, selected_filter = QtWidgets.QFileDialog.getOpenFileName(
+ parent, "Import from Json", filter=file_dialog_filters, selectedFilter=default_filter.get()
+ )
+ if file_name:
+ default_filter.set(selected_filter)
+ return file_name, selected_filter
+
+ if file_dialog_func is None:
+ file_dialog_func = default_file_dialog_func
+
+ def transfer_dialog(transfer):
+ model = UiModel()
+ model.transfer = transfer
+ open(parent, model)
+
+ def import_callback():
+ if session.state.selectedSkinCluster is None:
+ return
+
+ file_name, selected_format = file_dialog_func()
+ if not file_name:
+ return
+
+ t = LayersTransfer()
+ t.load_source_from_file(file_name, format=format_map[selected_format])
+ t.target = session.state.selectedSkinCluster
+ t.customize_callback = transfer_dialog
+ t.execute()
+
+ result = actions.define_action(parent, "Import Layers from Json...", callback=import_callback, tooltip="Load previously exported weights")
+
+ @signal.on(session.events.targetChanged, qtParent=parent)
+ def update():
+ result.setEnabled(session.state.selectedSkinCluster is not None)
+
+ update()
+
+ return result
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/import_v1_actions.py b/2023/scripts/rigging_tools/ngskintools2/operations/import_v1_actions.py
new file mode 100644
index 0000000..2b19f45
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/import_v1_actions.py
@@ -0,0 +1,40 @@
+from ngSkinTools2 import api, signal
+
+
+def can_import(session):
+ """
+ :type session: ngSkinTools2.api.session.Session
+ """
+
+ if not session.state.selection:
+ return False
+
+ if session.state.layersAvailable:
+ return False
+
+ return api.import_v1.can_import(session.state.selection[-1])
+
+
+def build_action_import_v1(session, parent):
+ """
+ :type parent: PySide2.QtWidgets.QWidget
+ :type session: ngSkinTools2.api.session.Session
+ """
+ from ngSkinTools2.ui import actions
+
+ def do_convert():
+ api.import_v1.import_layers(session.state.selection[-1])
+ api.import_v1.cleanup(session.state.selection[-1:])
+ update_state()
+ session.events.targetChanged.emitIfChanged()
+
+ result = actions.define_action(parent, "Convert From v1.0 Layers", callback=do_convert)
+ result.setToolTip("Convert skinning layers from previous version of ngSkinTools; after completing this action, v1 nodes will be deleted.")
+
+ @signal.on(session.events.targetChanged)
+ def update_state():
+ result.setVisible(can_import(session))
+
+ update_state()
+
+ return result
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/layers.py b/2023/scripts/rigging_tools/ngskintools2/operations/layers.py
new file mode 100644
index 0000000..028eb96
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/layers.py
@@ -0,0 +1,229 @@
+import random
+
+from maya import cmds
+
+import ngSkinTools2.api
+from ngSkinTools2 import signal
+from ngSkinTools2.api import Mirror
+from ngSkinTools2.api.layers import generate_layer_name
+from ngSkinTools2.api.log import getLogger
+from ngSkinTools2.api.pyside import QAction, QtCore
+from ngSkinTools2.api.session import session, withSession
+from ngSkinTools2.decorators import undoable
+from ngSkinTools2.ui import dialogs, qt
+from ngSkinTools2.ui.action import Action
+from ngSkinTools2.ui.options import config
+
+logger = getLogger("layer operations")
+
+
+@withSession
+@undoable
+def initializeLayers(createFirstLayer=True):
+ if session.state.layersAvailable:
+ return # ignore
+
+ target = session.state.selectedSkinCluster
+
+ layers = ngSkinTools2.api.init_layers(target)
+ with ngSkinTools2.api.suspend_updates(target):
+ if createFirstLayer:
+ layer = layers.add("Base weights")
+ layer.set_current()
+ Mirror(target).set_mirror_config(config.mirrorInfluencesDefaults)
+
+ session.events.targetChanged.emitIfChanged()
+
+ if ngSkinTools2.api.is_slow_mode_skin_cluster(target):
+ dialogs.info(
+ "ngSkinTools switched to slow maya API for setting skin cluster weights for this skinCluster, to workaround a Maya bug when skinCluster uses dg nodes as inputs"
+ )
+
+
+@undoable
+def addLayer():
+ layers = ngSkinTools2.api.Layers(session.state.selectedSkinCluster)
+
+ def guessParent():
+ currentLayer = layers.current_layer()
+ if currentLayer is None:
+ return None
+
+ # current layer is a parent?
+ if currentLayer.num_children > 0:
+ return currentLayer
+
+ return currentLayer.parent
+
+ with ngSkinTools2.api.suspend_updates(layers.mesh):
+ new_layer = layers.add(generate_layer_name(session.state.all_layers, "New Layer"))
+ new_layer.parent = guessParent()
+
+ session.events.layerListChanged.emitIfChanged()
+ setCurrentLayer(new_layer)
+
+ return new_layer
+
+
+def build_action_initialize_layers(session, parent):
+ from ngSkinTools2.ui import actions
+
+ from . import import_v1_actions
+
+ def do_initialize():
+ if import_v1_actions.can_import(session):
+ q = (
+ "Skinning layers from previous version of ngSkinTools are present on this mesh. This operation will initialize "
+ "skinning layers from scratch, discarding previous layers information. Do you want to continue?"
+ )
+ if not dialogs.yesNo(q):
+ return
+
+ initializeLayers()
+
+ result = actions.define_action(parent, "Initialize Skinning Layers", callback=do_initialize)
+
+ @signal.on(session.events.nodeSelectionChanged)
+ def update():
+ result.setEnabled(session.state.selectedSkinCluster is not None)
+
+ update()
+
+ return result
+
+
+def buildAction_createLayer(session, parent):
+ from ngSkinTools2.ui import actions
+
+ result = actions.define_action(parent, "Create Layer", callback=addLayer, icon=":/newLayerEmpty.png", shortcut=QtCore.Qt.Key_Insert)
+
+ @signal.on(session.events.targetChanged)
+ def update_to_target():
+ result.setEnabled(session.state.layersAvailable)
+
+ update_to_target()
+
+ return result
+
+
+def buildAction_deleteLayer(session, parent):
+ from ngSkinTools2.ui import actions
+
+ result = actions.define_action(parent, "Delete Layer", callback=deleteSelectedLayers, shortcut=QtCore.Qt.Key_Delete)
+
+ @signal.on(session.context.selected_layers.changed, session.events.targetChanged, qtParent=parent)
+ def update_to_target():
+ result.setEnabled(session.state.layersAvailable and bool(session.context.selected_layers(default=[])))
+
+ update_to_target()
+
+ return result
+
+
+@undoable
+def setCurrentLayer(layer):
+ """
+ :type layer: ngSkinTools2.api.layers.Layer
+ """
+ if not session.active():
+ logger.info("didn't set current layer: no session")
+
+ if not session.state.layersAvailable:
+ logger.info("didn't set current layer: layers not enabled")
+
+ logger.info("setting current layer to %r on %r", layer, session.state.selectedSkinCluster)
+ layer.set_current()
+ session.events.currentLayerChanged.emitIfChanged()
+
+
+def getCurrentLayer():
+ layers = ngSkinTools2.api.Layers(session.state.selectedSkinCluster)
+ return layers.current_layer()
+
+
+@undoable
+def renameLayer(layer, newName):
+ layer.name = newName
+ cmds.evalDeferred(session.events.layerListChanged.emitIfChanged)
+
+
+@undoable
+def deleteSelectedLayers():
+ layers = ngSkinTools2.api.Layers(session.state.selectedSkinCluster)
+ for i in session.context.selected_layers(default=[]):
+ layers.delete(i)
+
+ session.events.layerListChanged.emitIfChanged()
+ session.events.currentLayerChanged.emitIfChanged()
+
+
+class ToggleEnabledAction(Action):
+ name = "Enabled"
+ checkable = True
+
+ def __init__(self, session):
+ Action.__init__(self, session)
+
+ def checked(self):
+ """
+ return true if most of selected layers are enabled
+ :return:
+ """
+ layers = session.context.selected_layers(default=[])
+ if not layers:
+ return True
+
+ enabled_disabled_balance = 0
+ for layer in layers:
+ try:
+ # eat up the exception if layer id is invalid
+ enabled_disabled_balance += 1 if layer.enabled else -1
+ except:
+ pass
+
+ return enabled_disabled_balance >= 0
+
+ def run(self):
+ enabled = not self.checked()
+ selected_layers = session.context.selected_layers()
+ if not selected_layers:
+ return
+
+ for i in selected_layers:
+ i.enabled = enabled
+
+ logger.info("layers toggled: %r", selected_layers)
+
+ session.events.layerListChanged.emitIfChanged()
+
+ def enabled(self):
+ return session.state.layersAvailable and bool(session.context.selected_layers(default=[]))
+
+ def update_on_signals(self):
+ return [session.context.selected_layers.changed, session.events.layerListChanged, session.events.targetChanged]
+
+
+def build_action_randomize_influences_colors(session, parent):
+ """
+ builds a UI action for randomly choosing new colors for influences
+ :type session: ngSkinTools2.api.session.Session
+ """
+
+ result = QAction("Randomize colors", parent)
+ result.setToolTip("Choose random colors for each influence, selecting from Maya's pallete of indexed colors")
+
+ def color_filter(c):
+ brightness = c[0] * c[0] + c[1] * c[1] + c[2] * c[2]
+ return brightness > 0.001 and brightness < 0.99 # just a fancy way to skip white and black
+
+ colors = set([tuple(cmds.colorIndex(i, q=True)) for i in range(1, 30)])
+ colors = [c for c in colors if color_filter(c)]
+
+ @qt.on(result.triggered)
+ def triggered():
+ if session.state.selectedSkinCluster is None:
+ return
+ layers = ngSkinTools2.api.Layers(session.state.selectedSkinCluster)
+ layers.config.influence_colors = {i.logicalIndex: random.choice(colors) for i in layers.list_influences()}
+
+ return result
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/paint.py b/2023/scripts/rigging_tools/ngskintools2/operations/paint.py
new file mode 100644
index 0000000..41d46d3
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/paint.py
@@ -0,0 +1,45 @@
+from maya import cmds
+
+from ngSkinTools2.api import PaintTool
+from ngSkinTools2.api.log import getLogger
+from ngSkinTools2.api.session import session
+from ngSkinTools2.ui.action import Action
+
+log = getLogger("operations/paint")
+
+
+class FloodAction(Action):
+ name = "Flood"
+ tooltip = "Apply current brush to whole selection"
+
+ def run(self):
+ session.paint_tool.flood(self.session.state.currentLayer.layer, influences=self.session.state.currentLayer.layer.paint_targets)
+
+ def enabled(self):
+ return PaintTool.is_painting() and self.session.state.selectedSkinCluster is not None and self.session.state.currentLayer.layer is not None
+
+ def update_on_signals(self):
+ return [
+ self.session.events.toolChanged,
+ self.session.events.currentLayerChanged,
+ self.session.events.currentInfluenceChanged,
+ self.session.events.targetChanged,
+ ]
+
+
+class PaintAction(Action):
+ name = "Paint"
+ tooltip = "Toggle paint tool"
+ checkable = True
+
+ def run(self):
+ if self.checked():
+ cmds.setToolTo("moveSuperContext")
+ else:
+ self.session.paint_tool.start()
+
+ def update_on_signals(self):
+ return [self.session.events.toolChanged]
+
+ def checked(self):
+ return PaintTool.is_painting()
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/removeLayerData.py b/2023/scripts/rigging_tools/ngskintools2/operations/removeLayerData.py
new file mode 100644
index 0000000..d8e91b7
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/removeLayerData.py
@@ -0,0 +1,101 @@
+import itertools
+
+from maya import cmds
+
+from ngSkinTools2.api import PaintTool, target_info
+from ngSkinTools2.api.session import Session
+from ngSkinTools2.decorators import undoable
+
+
+def as_list(arg):
+ return [] if arg is None else arg
+
+
+customNodeTypes = ['ngst2MeshDisplay', 'ngst2SkinLayerData']
+
+
+def list_custom_nodes():
+ """
+ list all custom nodes in the scene
+ """
+
+ result = []
+ for nodeType in customNodeTypes:
+ result.extend(as_list(cmds.ls(type=nodeType)))
+ return result
+
+
+def list_custom_nodes_for_mesh(mesh=None):
+ """
+ list custom nodes only related to provided mesh. None means current selection
+ """
+
+ skin_cluster = target_info.get_related_skin_cluster(mesh)
+ if skin_cluster is None:
+ return []
+
+ # delete any ngSkinTools deformers from the history, and find upstream stuff from given skinCluster.
+ hist = as_list(cmds.listHistory(skin_cluster, future=True, levels=1))
+ return [i for i in hist if cmds.nodeType(i) in customNodeTypes]
+
+
+def list_custom_nodes_for_meshes(meshes):
+ return list(itertools.chain.from_iterable([list_custom_nodes_for_mesh(i) for i in meshes]))
+
+
+message_scene_noCustomNodes = 'Scene does not contain any custom ngSkinTools nodes.'
+message_selection_noCustomNodes = 'Selection does not contain any custom ngSkinTools nodes.'
+message_scene_warning = (
+ 'This command deletes all custom ngSkinTools nodes. Skin weights ' 'will be preserved, but all layer data will be lost. Do you want to continue?'
+)
+message_selection_warning = (
+ 'This command deletes custom ngSkinTools nodes for selection. Skin weights '
+ 'will be preserved, but all layer data will be lost. Do you want to continue?'
+)
+
+
+@undoable
+def remove_custom_nodes(interactive=False, session=None, meshes=None):
+ """
+ Removes custom ngSkinTools2 nodes from the scene or selection.
+
+ :type meshes: list[str]
+ :param meshes: list of node names; if empty, operation will be scene-wide.
+ :type session: Session
+ :param session: optional; if specified, will fire events for current session about changed status of selected mesh
+ :type interactive: bool
+ :param interactive: if True, user warnings will be emited
+ """
+ from ngSkinTools2.ui import dialogs
+
+ if meshes is None:
+ meshes = []
+
+ is_selection_mode = len(meshes) > 0
+
+ custom_nodes = list_custom_nodes() if not is_selection_mode else list_custom_nodes_for_meshes(meshes)
+
+ if not custom_nodes:
+ if interactive:
+ dialogs.info(message_selection_noCustomNodes if is_selection_mode else message_scene_noCustomNodes)
+ return
+
+ delete_confirmed = True
+ if interactive:
+ delete_confirmed = dialogs.yesNo(message_selection_warning if is_selection_mode else message_scene_warning)
+
+ if delete_confirmed:
+ cmds.delete(custom_nodes)
+
+ if PaintTool.is_painting():
+ # make sure that painting is canceled to restore mesh display etc
+ cmds.setToolTo("Move")
+
+ if session is not None:
+ session.events.targetChanged.emitIfChanged()
+
+
+@undoable
+def remove_custom_nodes_from_selection(interactive=False, session=None):
+ selection = cmds.ls(sl=True)
+ remove_custom_nodes(interactive=interactive, session=session, meshes=as_list(selection))
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/tools.py b/2023/scripts/rigging_tools/ngskintools2/operations/tools.py
new file mode 100644
index 0000000..27e8169
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/tools.py
@@ -0,0 +1,295 @@
+from maya import cmds
+
+from ngSkinTools2 import api, signal
+from ngSkinTools2.api.log import getLogger
+from ngSkinTools2.api.python_compatibility import Object
+from ngSkinTools2.api.session import Session
+from ngSkinTools2.decorators import undoable
+from ngSkinTools2.observableValue import ObservableValue
+from ngSkinTools2.operations import layers
+from ngSkinTools2.ui import dialogs
+
+logger = getLogger("operation/tools")
+
+
+def __create_tool_action__(parent, session, action_name, action_tooltip, exec_handler, enabled_handler=None):
+ """
+ :type session: Session
+ """
+
+ from ngSkinTools2.ui import actions
+
+ def execute():
+ if not session.active():
+ return
+
+ exec_handler()
+
+ result = actions.define_action(parent, action_name, callback=execute, tooltip=action_tooltip)
+
+ @signal.on(session.events.targetChanged, session.events.currentLayerChanged)
+ def update_state():
+ enabled = session.state.layersAvailable and session.state.currentLayer.layer is not None
+ if enabled and enabled_handler is not None:
+ enabled = enabled_handler(session.state.currentLayer.layer)
+ result.setEnabled(enabled)
+
+ update_state()
+
+ return result
+
+
+class ClosestJointOptions(Object):
+ def __init__(self):
+ self.create_new_layer = ObservableValue(False)
+ self.all_influences = ObservableValue(True)
+
+
+def create_action__from_closest_joint(parent, session):
+ options = ClosestJointOptions()
+
+ def exec_handler():
+ layer = session.state.currentLayer.layer
+ influences = None
+ if not options.all_influences():
+ influences = layer.paint_targets
+ if not influences:
+ dialogs.info("Select one or more influences in Influences list")
+ return
+
+ if options.create_new_layer():
+ layer = layers.addLayer()
+
+ api.assign_from_closest_joint(
+ session.state.selectedSkinCluster,
+ layer,
+ influences=influences,
+ )
+ session.events.currentLayerChanged.emitIfChanged()
+ session.events.influencesListUpdated.emit()
+
+ if layer.paint_target is None:
+ used_influences = layer.get_used_influences()
+ if used_influences:
+ layer.paint_target = min(used_influences)
+
+ return (
+ __create_tool_action__(
+ parent,
+ session,
+ action_name=u"Assign From Closest Joint",
+ action_tooltip="Assign 1.0 weight for closest influence per each vertex in selected layer",
+ exec_handler=exec_handler,
+ ),
+ options,
+ )
+
+
+class UnifyWeightsOptions(Object):
+ overall_effect = ObservableValue(1.0)
+ single_cluster_mode = ObservableValue(False)
+
+
+def create_action__unify_weights(parent, session):
+ options = UnifyWeightsOptions()
+
+ def exec_handler():
+ api.unify_weights(
+ session.state.selectedSkinCluster,
+ session.state.currentLayer.layer,
+ overall_effect=options.overall_effect(),
+ single_cluster_mode=options.single_cluster_mode(),
+ )
+
+ return (
+ __create_tool_action__(
+ parent,
+ session,
+ action_name=u"Unify Weights",
+ action_tooltip="For selected vertices, make verts the same for all verts",
+ exec_handler=exec_handler,
+ ),
+ options,
+ )
+
+
+def create_action__merge_layers(parent, session):
+ """
+ :param parent: UI parent for this action
+ :type session: Session
+ """
+
+ def exec_handler():
+ api.merge_layers(layers=session.context.selected_layers(default=[]))
+ session.events.layerListChanged.emitIfChanged()
+ session.events.currentLayerChanged.emitIfChanged()
+
+ def enabled_handler(layer):
+ return layer is not None and layer.index > 0
+
+ return __create_tool_action__(
+ parent,
+ session,
+ action_name=u"Merge",
+ action_tooltip="Merge contents of this layer into underlying layer. Pre-effects weights will be used for this",
+ exec_handler=exec_handler,
+ enabled_handler=enabled_handler,
+ )
+
+
+def create_action__duplicate_layer(parent, session):
+ """
+ :param parent: UI parent for this action
+ :type session: Session
+ """
+
+ @undoable
+ def exec_handler():
+ with api.suspend_updates(session.state.selectedSkinCluster):
+ for source in session.context.selected_layers(default=[]):
+ api.duplicate_layer(layer=source)
+
+ session.events.layerListChanged.emitIfChanged()
+ session.events.currentLayerChanged.emitIfChanged()
+
+ return __create_tool_action__(
+ parent,
+ session,
+ action_name=u"Duplicate",
+ action_tooltip="Duplicate selected layer(s)",
+ exec_handler=exec_handler,
+ )
+
+
+def create_action__fill_transparency(parent, session):
+ """
+ :param parent: UI parent for this action
+ :type session: Session
+ """
+
+ @undoable
+ def exec_handler():
+ with api.suspend_updates(session.state.selectedSkinCluster):
+ for source in session.context.selected_layers(default=[]):
+ api.fill_transparency(layer=source)
+
+ return __create_tool_action__(
+ parent,
+ session,
+ action_name=u"Fill Transparency",
+ action_tooltip="All transparent vertices in the selected layer(s) receive weights from their closest non-empty neighbour vertex",
+ exec_handler=exec_handler,
+ )
+
+
+def create_action__copy_component_weights(parent, session):
+ """
+ :param parent: UI parent for this action
+ :type session: Session
+ """
+
+ def exec_handler():
+ for source in session.context.selected_layers(default=[]):
+ api.copy_component_weights(layer=source)
+
+ return __create_tool_action__(
+ parent,
+ session,
+ action_name=u"Copy Component Weights",
+ action_tooltip="Store components weights in memory for further component-based paste actions",
+ exec_handler=exec_handler,
+ )
+
+
+def create_action__paste_average_component_weight(parent, session):
+ """
+ :param parent: UI parent for this action
+ :type session: Session
+ """
+
+ def exec_handler():
+ for l in session.context.selected_layers(default=[]):
+ api.paste_average_component_weights(layer=l)
+
+ return __create_tool_action__(
+ parent,
+ session,
+ action_name=u"Paste Average Component Weight",
+ action_tooltip="Compute average of copied component weights and set that value to currently selected components",
+ exec_handler=exec_handler,
+ )
+
+
+def create_action__add_influences(parent, session):
+ """
+ :param parent: UI parent for this action
+ :type session: Session
+ """
+
+ def exec_handler():
+ selection = cmds.ls(sl=True, l=True)
+ if len(selection) < 2:
+ logger.info("invalid selection: %s", selection)
+ return
+ api.add_influences(selection[:-1], selection[-1])
+ cmds.select(selection[-1])
+ session.events.influencesListUpdated.emit()
+
+ return __create_tool_action__(
+ parent,
+ session,
+ action_name=u"Add Influences",
+ action_tooltip="Add selected influences to current skin cluster.",
+ exec_handler=exec_handler,
+ )
+
+
+def create_action__select_affected_vertices(parent, session):
+ """
+ :param parent: UI parent for this action
+ :type session: Session
+ """
+
+ def exec_handler():
+ selected_layers = session.context.selected_layers(default=[])
+ if not selected_layers:
+ return
+
+ if not session.state.currentLayer.layer:
+ return
+
+ influences = session.state.currentLayer.layer.paint_targets
+ if not influences:
+ return
+
+ non_zero_weights = []
+ for layer in selected_layers:
+ for i in influences:
+ weights = layer.get_weights(i)
+ if weights:
+ non_zero_weights.append(weights)
+
+ if not non_zero_weights:
+ return
+
+ current_selection = cmds.ls(sl=True, o=True, l=True)
+ if len(current_selection) != 1:
+ return
+
+ # we're not sure - this won't work if skin cluster is selected directly
+ selected_mesh_probably = current_selection[0]
+
+ combined_weights = [sum(i) for i in zip(*non_zero_weights)]
+ indexes = [selected_mesh_probably + ".vtx[%d]" % index for index, i in enumerate(combined_weights) if i > 0.00001]
+ try:
+ cmds.select(indexes)
+ except:
+ pass
+
+ return __create_tool_action__(
+ parent,
+ session,
+ action_name=u"Select Affected Vertices",
+ action_tooltip="Select vertices that have non-zero weight for current influence.",
+ exec_handler=exec_handler,
+ )
diff --git a/2023/scripts/rigging_tools/ngskintools2/operations/website_links.py b/2023/scripts/rigging_tools/ngskintools2/operations/website_links.py
new file mode 100644
index 0000000..3a36476
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/operations/website_links.py
@@ -0,0 +1,31 @@
+from ngSkinTools2.api.python_compatibility import Object
+
+
+def website_base_url():
+ import ngSkinTools2
+
+ if ngSkinTools2.DEBUG_MODE:
+ return "http://localhost:1313"
+
+ return "https://www.ngskintools.com"
+
+
+class WebsiteLinksActions(Object):
+ def __init__(self, parent):
+ self.api_root = make_documentation_action(parent, "API Documentation", "/v2/api")
+ self.user_guide = make_documentation_action(parent, "User Guide", "/v2/")
+ self.changelog = make_documentation_action(parent, "Change Log", "/v2/changelog", icon=None)
+ self.contact = make_documentation_action(parent, "Contact", "/contact/", icon=None)
+
+
+def make_documentation_action(parent, title, url, icon=":/help.png"):
+ from ngSkinTools2.ui import actions
+
+ def handler():
+ import webbrowser
+
+ webbrowser.open_new(website_base_url() + url)
+
+ result = actions.define_action(parent, title, callback=handler, icon=icon)
+ result.setToolTip("opens {0} in a browser".format(url))
+ return result
diff --git a/2023/scripts/rigging_tools/ngskintools2/plug-ins/2018/ngSkinTools2.mll b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2018/ngSkinTools2.mll
new file mode 100644
index 0000000..634a35a
Binary files /dev/null and b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2018/ngSkinTools2.mll differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/plug-ins/2019/ngSkinTools2.mll b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2019/ngSkinTools2.mll
new file mode 100644
index 0000000..b8cbe8b
Binary files /dev/null and b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2019/ngSkinTools2.mll differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/plug-ins/2020/ngSkinTools2.mll b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2020/ngSkinTools2.mll
new file mode 100644
index 0000000..123d3a8
Binary files /dev/null and b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2020/ngSkinTools2.mll differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/plug-ins/2022/ngSkinTools2.mll b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2022/ngSkinTools2.mll
new file mode 100644
index 0000000..eb68a34
Binary files /dev/null and b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2022/ngSkinTools2.mll differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/plug-ins/2023/ngSkinTools2.mll b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2023/ngSkinTools2.mll
new file mode 100644
index 0000000..4244b24
Binary files /dev/null and b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2023/ngSkinTools2.mll differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/plug-ins/2024/ngSkinTools2.mll b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2024/ngSkinTools2.mll
new file mode 100644
index 0000000..ae603bf
Binary files /dev/null and b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2024/ngSkinTools2.mll differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/plug-ins/2025/ngSkinTools2.mll b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2025/ngSkinTools2.mll
new file mode 100644
index 0000000..1329173
Binary files /dev/null and b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2025/ngSkinTools2.mll differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/plug-ins/2026/ngSkinTools2.mll b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2026/ngSkinTools2.mll
new file mode 100644
index 0000000..0b42e1b
Binary files /dev/null and b/2023/scripts/rigging_tools/ngskintools2/plug-ins/2026/ngSkinTools2.mll differ
diff --git a/2023/scripts/rigging_tools/ngskintools2/pluginCallbacks.py b/2023/scripts/rigging_tools/ngskintools2/pluginCallbacks.py
new file mode 100644
index 0000000..675fb43
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/pluginCallbacks.py
@@ -0,0 +1,63 @@
+"""
+these are methods that are called by plugin when corresponding events happen
+"""
+from ngSkinTools2 import api
+from ngSkinTools2.api import eventtypes as et
+from ngSkinTools2.api.log import getLogger
+from ngSkinTools2.api.session import session
+from ngSkinTools2.ui import hotkeys_setup
+
+log = getLogger("plugin callbacks")
+
+
+def current_paint_target_changed():
+ # log.info("current paint target changed")
+ if session.active():
+ if session.state.currentLayer.layer is not None:
+ session.state.currentLayer.layer.reload()
+ session.events.currentInfluenceChanged.emitIfChanged()
+
+
+def tool_settings_changed():
+ et.tool_settings_changed.emit()
+
+
+def paint_tool_started():
+ api.paint.tabletEventFilter.install()
+ hotkeys_setup.toggle_paint_hotkey_set(enabled=True)
+
+
+def paint_tool_stopped():
+ api.paint.tabletEventFilter.uninstall()
+ hotkeys_setup.toggle_paint_hotkey_set(enabled=False)
+
+
+def get_stylus_intensity():
+ return api.paint.tabletEventFilter.pressure
+
+
+def initialize_influences_mirror_mapping(mesh):
+ """
+ gets called by plugin when influences mirror mapping is not set yet
+ :return:
+ """
+ from ngSkinTools2.api.mirror import Mirror
+
+ Mirror(mesh).recalculate_influences_mapping()
+
+
+def display_node_created(display_node):
+ """
+ gets called when display node is created
+
+ :param display_node:
+ :return:
+ """
+
+ from maya import cmds
+
+ # add node to isolated objects if we're currently in isolated mode
+ current_view = cmds.paneLayout('viewPanes', q=True, pane1=True)
+ is_isolated = cmds.isolateSelect(current_view, q=True, state=True)
+ if is_isolated:
+ cmds.isolateSelect(current_view, addDagObject=display_node)
diff --git a/2023/scripts/rigging_tools/ngskintools2/signal.py b/2023/scripts/rigging_tools/ngskintools2/signal.py
new file mode 100644
index 0000000..7961484
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/signal.py
@@ -0,0 +1,253 @@
+"""
+Signal is the previous method of emiting/subscribing to signals.
+* Subscribers are dependant on emiter's instances
+* There's only one global queue
+
+New system is changing to allow decoupling subscribers and receivers, and allowing the code to work even when there's no need to process signals
+* Subscribers need to be able to subsribe prior to instantiation of emitters
+
+
+"""
+from functools import partial
+
+from ngSkinTools2 import cleanup
+from ngSkinTools2.api.log import getLogger
+from ngSkinTools2.api.python_compatibility import Object
+
+log = getLogger("signal")
+
+
+class SignalQueue(Object):
+ def __init__(self):
+ self.max_length = 100
+ self.queue = []
+
+ def emit(self, handler):
+ if len(self.queue) > self.max_length:
+ log.error("queue max length reached: emitting too many events?")
+ raise Exception("queue max length reached: emitting too many events?")
+
+ should_start = len(self.queue) == 0
+
+ self.queue.append(handler)
+ if should_start:
+ self.process()
+
+ def process(self):
+ current_handler = 0
+ queue = self.queue
+
+ while current_handler < len(queue):
+ # noinspection PyBroadException
+ try:
+ queue[current_handler]()
+ except Exception:
+ import ngSkinTools2
+
+ if ngSkinTools2.DEBUG_MODE:
+ import sys
+ import traceback
+
+ traceback.print_exc(file=sys.__stderr__)
+
+ current_handler += 1
+
+ if len(self.queue) > 50:
+ log.info("handler queue finished with %d items", len(self.queue))
+ self.queue = []
+
+
+# noinspection PyBroadException
+class Signal(Object):
+ """
+ Signal class collects observers, interested in some particular event,and handles
+ signaling them all when some event occurs. Both handling and signaling happens outside
+ of signal's own code
+
+
+ Handlers are processed breath first, in a queue based system.
+ 1. root signal fires, adds all it's handlers to the queue;
+ 2. queue starts being processed
+ 3. handlers fire more signals, in turn adding more handlers to the end of the queue.
+ """
+
+ all = []
+
+ queue = SignalQueue()
+
+ def __init__(self, name):
+ if name is None:
+ raise Exception("need name for debug purposes later")
+ self.name = name
+ self.handlers = []
+ self.executing = False
+ self.enabled = True
+
+ self.reset()
+ Signal.all.append(self)
+ cleanup.registerCleanupHandler(self.reset)
+
+ def reset(self):
+ self.handlers = []
+ self.executing = False
+
+ def emit_deferred(self, *args):
+ import maya.utils as mu
+
+ mu.executeDeferred(self.emit, *args)
+
+ def emit(self, *args):
+ """
+ emit mostly just adds handlers to the processing queue,
+ but if nobody is processing handlers at the emit time,
+ it is started here as well.
+ """
+ if not self.enabled:
+ return
+
+ # log.info("emit: %s", self.name)
+ if self.executing:
+ raise Exception('Nested emit on %s detected' % self.name)
+
+ for i in self.handlers[:]:
+ Signal.queue.emit(partial(i, *args))
+
+ def addHandler(self, handler, qtParent=None):
+ if hasattr(handler, 'emit'):
+ handler = handler.emit
+
+ self.handlers.append(handler)
+
+ def remove():
+ return self.removeHandler(handler)
+
+ if qtParent is not None:
+ qtParent.destroyed.connect(remove)
+
+ return remove
+
+ def removeHandler(self, handler):
+ try:
+ self.handlers.remove(handler)
+ except ValueError:
+ # not found in list? no biggie.
+ pass
+
+
+def on(*signals, **kwargs):
+ """
+ decorator for function: list signals that should fire for this function.
+
+ @signal.on(signalReference)
+ def something():
+ ...
+ """
+
+ def decorator(fn):
+ for i in signals:
+ i.addHandler(fn, **kwargs)
+ return fn
+
+ return decorator
+
+
+# --------------------------------------
+# rework:
+# * decoupled emitters and subscribers
+# * subscribers are resolved only at the time of event
+# * can emit events even when there's no active sessions (acts as no-op)
+
+
+class Event(Object):
+ def __init__(self, name):
+ self.name = name
+
+ def __or__(self, other):
+ return EventList() | self | other
+
+ def __iter__(self):
+ yield self
+
+ def emit(self, *args, **kwargs):
+ for hub in SignalHub.active_hubs:
+ hub.emit(self, *args, **kwargs)
+
+
+class EventList(Object):
+ """
+ helper to build and iterate over a list of "or"-ed events
+ """
+
+ def __init__(self):
+ self.items = []
+
+ def __or__(self, other):
+ self.items.append(other)
+ return self
+
+ def __iter__(self):
+ return iter(self.items)
+
+
+class SignalHub(Object):
+ active_hubs = set()
+
+ def __init__(self):
+ self.handlers = {}
+ self.queue = SignalQueue()
+
+ def activate(self):
+ self.active_hubs.add(self)
+
+ def deactivate(self):
+ self.active_hubs.remove(self)
+
+ def subscribe(self, event, handler):
+ """
+ :param Event event: event to subscribe to
+ :param Callable handler: callback which will be called when event is emitted
+ :return: unsubscribe function: call it to terminate this subscription
+ """
+ self.handlers.setdefault(event, []).append(handler)
+
+ def unsubscribe():
+ try:
+ self.handlers[event].remove(handler)
+ except ValueError:
+ # not found in list? no biggie.
+ pass
+
+ return unsubscribe
+
+ def emit(self, event):
+ if not event in self.handlers:
+ return
+
+ for i in self.handlers[event]:
+ self.queue.emit(i)
+
+ def on(self, events, scope=None):
+ """
+ decorator for function: bind function to signals
+
+ @hub.on(event1 | event2, scope=qt_object)
+ def something():
+ ...
+ """
+
+ def decorator(fn):
+ unsubscribe_handlers = []
+ try:
+ unsubscribe_handlers.append(scope.destroyed.connect)
+ except:
+ pass
+
+ for e in events:
+ unsub = self.subscribe(e, fn)
+ if unsubscribe_handlers:
+ for i in unsubscribe_handlers:
+ i(unsub)
+
+ return fn
+
+ return decorator
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/__init__.py b/2023/scripts/rigging_tools/ngskintools2/ui/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/2023/scripts/rigging_tools/ngskintools2/ui/aboutwindow.py b/2023/scripts/rigging_tools/ngskintools2/ui/aboutwindow.py
new file mode 100644
index 0000000..e96ffd2
--- /dev/null
+++ b/2023/scripts/rigging_tools/ngskintools2/ui/aboutwindow.py
@@ -0,0 +1,91 @@
+import os
+from xml.sax.saxutils import escape as escape
+
+from ngSkinTools2 import cleanup, version
+from ngSkinTools2.api.pyside import Qt, QtWidgets
+from ngSkinTools2.api.session import session
+from ngSkinTools2.ui import qt
+from ngSkinTools2.ui.layout import scale_multiplier
+
+
+def show(parent):
+ """
+ :type parent: QWidget
+ """
+
+ def header():
+ # noinspection PyShadowingNames
+ def leftSide():
+ layout = QtWidgets.QVBoxLayout()
+ layout.addStretch()
+ layout.addWidget(QtWidgets.QLabel("