packages feed

git-annex 5.20131130 → 5.20131213

raw patch · 141 files changed

+9116/−7516 lines, 141 filesdep +Win32dep +Win32-extrasdep +network-conduitbinary-added

Dependencies added: Win32, Win32-extras, network-conduit

Files

Annex/Branch.hs view
@@ -95,7 +95,7 @@ 		fromMaybe (error $ "failed to create " ++ show name) 			<$> branchsha 	go False = withIndex' True $-		inRepo $ Git.Branch.commit "branch created" fullname []+		inRepo $ Git.Branch.commitAlways "branch created" fullname [] 	use sha = do 		setIndexSha sha 		return sha@@ -249,7 +249,7 @@ commitIndex' :: JournalLocked -> Git.Ref -> String -> [Git.Ref] -> Annex () commitIndex' jl branchref message parents = do 	updateIndex jl branchref-	committedref <- inRepo $ Git.Branch.commit message fullname parents+	committedref <- inRepo $ Git.Branch.commitAlways message fullname parents 	setIndexSha committedref 	parentrefs <- commitparents <$> catObject committedref 	when (racedetected branchref parentrefs) $ do@@ -486,7 +486,7 @@ 		Annex.Queue.flush 		if neednewlocalbranch 			then do-				committedref <- inRepo $ Git.Branch.commit message fullname transitionedrefs+				committedref <- inRepo $ Git.Branch.commitAlways message fullname transitionedrefs 				setIndexSha committedref 			else do 				ref <- getBranch
Annex/Direct.hs view
@@ -1,6 +1,6 @@ {- git-annex direct mode  -- - Copyright 2012 Joey Hess <joey@kitenet.net>+ - Copyright 2012, 2013 Joey Hess <joey@kitenet.net>  -  - Licensed under the GNU GPL version 3 or higher.  -}@@ -88,8 +88,28 @@  	addgit file = Annex.Queue.addCommand "add" [Param "-f"] [file] -	deletegit file = Annex.Queue.addCommand "rm" [Param "-f"] [file]+	deletegit file = Annex.Queue.addCommand "rm" [Param "-qf"] [file] +{- Run before a commit to update direct mode bookeeping to reflect the+ - staged changes being committed. -}+preCommitDirect :: Annex Bool+preCommitDirect = do+	(diffs, clean) <- inRepo $ DiffTree.diffIndex Git.Ref.headRef+	makeabs <- flip fromTopFilePath <$> gitRepo+	forM_ diffs (go makeabs)+	liftIO clean+  where+	go makeabs diff = do+		withkey (DiffTree.srcsha diff) (DiffTree.srcmode diff) removeAssociatedFile+		withkey (DiffTree.dstsha diff) (DiffTree.dstmode diff) addAssociatedFile+	  where+		withkey sha mode a = when (sha /= nullSha) $ do+			k <- catKey sha mode+			case k of+				Nothing -> noop+				Just key -> void $ a key $+					makeabs $ DiffTree.file diff+ {- Adds a file to the annex in direct mode. Can fail, if the file is  - modified or deleted while it's being added. -} addDirect :: FilePath -> InodeCache -> Annex Bool@@ -142,9 +162,9 @@  - There are really only two types of changes: An old item can be deleted,  - or a new item added. Two passes are made, first deleting and then  - adding. This is to handle cases where eg, a file is deleted and a- - directory is added. The diff-tree output may list these in the opposite- - order, but we cannot really add the directory until the file with the- - same name is remvoed.+ - directory is added. (The diff-tree output may list these in the opposite+ - order, but we cannot add the directory until the file with the+ - same name is removed.)  -} mergeDirectCleanup :: FilePath -> Git.Ref -> Git.Ref -> Annex () mergeDirectCleanup d oldsha newsha = do@@ -161,14 +181,14 @@ 	go getsha getmode a araw (f, item) 		| getsha item == nullSha = noop 		| otherwise = void $-			tryAnnex . maybe (araw f) (\k -> void $ a k f)+			tryAnnex . maybe (araw f item) (\k -> void $ a k f) 				=<< catKey (getsha item) (getmode item)  	moveout k f = removeDirect k f  	{- Files deleted by the merge are removed from the work tree. 	 - Empty work tree directories are removed, per git behavior. -}-	moveout_raw f = liftIO $ do+	moveout_raw f _item = liftIO $ do 		nukeFile f 		void $ tryIO $ removeDirectory $ parentDir f 	@@ -182,9 +202,9 @@ 	 	{- Any new, modified, or renamed files were written to the temp 	 - directory by the merge, and are moved to the real work tree. -}-	movein_raw f = liftIO $ do+	movein_raw f item = liftIO $ do 		createDirectoryIfMissing True $ parentDir f-		void $ tryIO $ rename (d </> f) f+		void $ tryIO $ rename (d </> getTopFilePath (DiffTree.file item)) f  {- If possible, converts a symlink in the working tree into a direct  - mode file. If the content is not available, leaves the symlink
Assistant/Repair.hs view
@@ -10,7 +10,7 @@ module Assistant.Repair where  import Assistant.Common-import Command.Repair (repairAnnexBranch)+import Command.Repair (repairAnnexBranch, trackingOrSyncBranch) import Git.Fsck (FsckResults, foundBroken) import Git.Repair (runRepairOf) import qualified Git@@ -98,10 +98,10 @@ 			liftIO $ catchBoolIO a  	repair fsckresults referencerepo = do-		(ok, stillmissing, modifiedbranches) <- inRepo $-			runRepairOf fsckresults destructiverepair referencerepo+		(ok, modifiedbranches) <- inRepo $+			runRepairOf fsckresults trackingOrSyncBranch destructiverepair referencerepo 		when destructiverepair $-			repairAnnexBranch stillmissing modifiedbranches+			repairAnnexBranch modifiedbranches 		return ok 	 	backgroundfsck params = liftIO $ void $ async $ do
Assistant/Restart.hs view
@@ -5,6 +5,8 @@  - Licensed under the GNU AGPL version 3 or higher.  -} +{-# LANGUAGE CPP #-}+ module Assistant.Restart where  import Assistant.Common@@ -21,8 +23,13 @@ import qualified Git  import Control.Concurrent-import System.Posix (getProcessID, signalProcess, sigTERM) import System.Process (cwd)+#ifndef mingw32_HOST_OS+import System.Posix (getProcessID, signalProcess, sigTERM)+#else+import System.Win32.Process.Current (getCurrentProcessId)+import System.Win32.Console (generateConsoleCtrlEvent, cTRL_C_EVENT)+#endif  {- Before the assistant can be restarted, have to remove our   - gitAnnexUrlFile and our gitAnnexPidFile. Pausing the watcher is also@@ -45,7 +52,11 @@ 	liftIO . sendNotification . globalRedirNotifier =<< getDaemonStatus 	void $ liftIO $ forkIO $ do 		threadDelaySeconds (Seconds 120)+#ifndef mingw32_HOST_OS 		signalProcess sigTERM =<< getProcessID+#else+		generateConsoleCtrlEvent cTRL_C_EVENT =<< getCurrentProcessId+#endif  runRestart :: Assistant URLString runRestart = liftIO . newAssistantUrl
Assistant/Threads/Committer.hs view
@@ -20,9 +20,7 @@ import Logs.Transfer import Logs.Location import qualified Annex.Queue-import qualified Git.Command import qualified Git.LsFiles-import qualified Git.BuildVersion import qualified Command.Add import Utility.ThreadScheduler import qualified Utility.Lsof as Lsof@@ -36,6 +34,7 @@ import qualified Annex import Utility.InodeCache import Annex.Content.Direct+import qualified Command.Sync  import Data.Time.Clock import Data.Tuple.Utils@@ -47,11 +46,12 @@ {- This thread makes git commits at appropriate times. -} commitThread :: NamedThread commitThread = namedThread "Committer" $ do+	havelsof <- liftIO $ inPath "lsof" 	delayadd <- liftAnnex $ 		maybe delayaddDefault (return . Just . Seconds) 			=<< annexDelayAdd <$> Annex.getGitConfig 	waitChangeTime $ \(changes, time) -> do-		readychanges <- handleAdds delayadd changes+		readychanges <- handleAdds havelsof delayadd changes 		if shouldCommit time (length readychanges) readychanges 			then do 				debug@@ -217,31 +217,7 @@ 	v <- tryAnnex Annex.Queue.flush 	case v of 		Left _ -> return False-		Right _ -> do-			{- Empty commits may be made if tree changes cancel-			 - each other out, etc. Git returns nonzero on those,-			 - so don't propigate out commit failures. -}-			void $ inRepo $ catchMaybeIO . -				Git.Command.runQuiet-					(Param "commit" : nomessage params)-			return True-  where-	params =-		[ Param "--quiet"-		{- Avoid running the usual pre-commit hook;-		 - the Watcher does the same symlink fixing,-		 - and direct mode bookkeeping updating. -}-		, Param "--no-verify"-		]-	nomessage ps-		| Git.BuildVersion.older "1.7.2" =-			Param "-m" : Param "autocommit" : ps-		| Git.BuildVersion.older "1.7.8" =-			Param "--allow-empty-message" :-			Param "-m" : Param "" : ps-		| otherwise =-			Param "--allow-empty-message" :-			Param "--no-edit" : Param "-m" : Param "" : ps+		Right _ -> Command.Sync.commitStaged ""  {- OSX needs a short delay after a file is added before locking it down,  - when using a non-direct mode repository, as pasting a file seems to@@ -277,14 +253,14 @@  - Any pending adds that are not ready yet are put back into the ChangeChan,  - where they will be retried later.  -}-handleAdds :: Maybe Seconds -> [Change] -> Assistant [Change]-handleAdds delayadd cs = returnWhen (null incomplete) $ do+handleAdds :: Bool -> Maybe Seconds -> [Change] -> Assistant [Change]+handleAdds havelsof delayadd cs = returnWhen (null incomplete) $ do 	let (pending, inprocess) = partition isPendingAddChange incomplete 	direct <- liftAnnex isDirect 	(pending', cleanup) <- if direct 		then return (pending, noop) 		else findnew pending-	(postponed, toadd) <- partitionEithers <$> safeToAdd delayadd pending' inprocess+	(postponed, toadd) <- partitionEithers <$> safeToAdd havelsof delayadd pending' inprocess 	cleanup  	unless (null postponed) $@@ -298,7 +274,7 @@ 		if DirWatcher.eventsCoalesce || null added || direct 			then return $ added ++ otherchanges 			else do-				r <- handleAdds delayadd =<< getChanges+				r <- handleAdds havelsof delayadd =<< getChanges 				return $ r ++ added ++ otherchanges   where 	(incomplete, otherchanges) = partition (\c -> isPendingAddChange c || isInProcessAddChange c) cs@@ -411,15 +387,17 @@  -  - Check by running lsof on the repository.  -}-safeToAdd :: Maybe Seconds -> [Change] -> [Change] -> Assistant [Either Change Change]-safeToAdd _ [] [] = return []-safeToAdd delayadd pending inprocess = do+safeToAdd :: Bool -> Maybe Seconds -> [Change] -> [Change] -> Assistant [Either Change Change]+safeToAdd _ _ [] [] = return []+safeToAdd havelsof delayadd pending inprocess = do 	maybe noop (liftIO . threadDelaySeconds) delayadd 	liftAnnex $ do 		keysources <- forM pending $ Command.Add.lockDown . changeFile 		let inprocess' = inprocess ++ mapMaybe mkinprocess (zip pending keysources)-		openfiles <- S.fromList . map fst3 . filter openwrite <$>-			findopenfiles (map keySource inprocess')+		openfiles <- if havelsof+			then S.fromList . map fst3 . filter openwrite <$>+				findopenfiles (map keySource inprocess')+			else pure S.empty 		let checked = map (check openfiles) inprocess'  		{- If new events are received when files are closed,
Assistant/Threads/SanityChecker.hs view
@@ -29,7 +29,6 @@ import Git.Index  import Data.Time.Clock.POSIX-import qualified Data.Set as S  {- This thread runs once at startup, and most other threads wait for it  - to finish. (However, the webapp thread does not, to prevent the UI@@ -41,7 +40,7 @@  	{- A corrupt index file can prevent the assistant from working at 	 - all, so detect and repair. -}-	ifM (not <$> liftAnnex (inRepo (checkIndex S.empty)))+	ifM (not <$> liftAnnex (inRepo checkIndexFast)) 		( do 			notice ["corrupt index file found at startup; removing and restaging"] 			liftAnnex $ inRepo $ nukeFile . indexFile
Assistant/Threads/Transferrer.hs view
@@ -12,12 +12,14 @@ import Assistant.TransferSlots import Logs.Transfer import Config.Files+import Utility.Batch  {- Dispatches transfers from the queue. -} transfererThread :: NamedThread transfererThread = namedThread "Transferrer" $ do 	program <- liftIO readProgramFile-	forever $ inTransferSlot program $+	batchmaker <- liftIO getBatchCommandMaker+	forever $ inTransferSlot program batchmaker $ 		maybe (return Nothing) (uncurry genTransfer) 			=<< getNextTransfer notrunning   where
Assistant/Threads/Watcher.hs view
@@ -50,9 +50,13 @@ checkCanWatch :: Annex () checkCanWatch 	| canWatch = do+#ifndef mingw32_HOST_OS 		liftIO Lsof.setup 		unlessM (liftIO (inPath "lsof") <||> Annex.getState Annex.force) 			needLsof+#else+		noop+#endif 	| otherwise = error "watch mode is not available on this system"  needLsof :: Annex ()
Assistant/Threads/WebApp.hs view
@@ -80,7 +80,8 @@ 		, return app 		) 	runWebApp listenhost app' $ \addr -> if noannex-		then withTmpFile "webapp.html" $ \tmpfile _ ->+		then withTmpFile "webapp.html" $ \tmpfile h -> do+			hClose h 			go addr webapp tmpfile Nothing 		else do 			let st = threadState assistantdata
Assistant/TransferSlots.hs view
@@ -29,6 +29,7 @@ import Annex.Content import Annex.Wanted import Config.Files+import Utility.Batch  import qualified Data.Map as M  import qualified Control.Exception as E@@ -37,6 +38,8 @@ #ifndef mingw32_HOST_OS import System.Posix.Process (getProcessGroupIDOf) import System.Posix.Signals (signalProcessGroup, sigTERM, sigKILL)+#else+import System.Win32.Console (generateConsoleCtrlEvent, cTRL_C_EVENT, cTRL_BREAK_EVENT) #endif  type TransferGenerator = Assistant (Maybe (Transfer, TransferInfo, Transferrer -> Assistant ()))@@ -44,17 +47,17 @@ {- Waits until a transfer slot becomes available, then runs a  - TransferGenerator, and then runs the transfer action in its own thread.   -}-inTransferSlot :: FilePath -> TransferGenerator -> Assistant ()-inTransferSlot program gen = do+inTransferSlot :: FilePath -> BatchCommandMaker -> TransferGenerator -> Assistant ()+inTransferSlot program batchmaker gen = do 	flip MSemN.wait 1 <<~ transferSlots-	runTransferThread program =<< gen+	runTransferThread program batchmaker =<< gen  {- Runs a TransferGenerator, and its transfer action,  - without waiting for a slot to become available. -}-inImmediateTransferSlot :: FilePath -> TransferGenerator -> Assistant ()-inImmediateTransferSlot program gen = do+inImmediateTransferSlot :: FilePath -> BatchCommandMaker -> TransferGenerator -> Assistant ()+inImmediateTransferSlot program batchmaker gen = do 	flip MSemN.signal (-1) <<~ transferSlots-	runTransferThread program =<< gen+	runTransferThread program batchmaker =<< gen  {- Runs a transfer action, in an already allocated transfer slot.  - Once it finishes, frees the transfer slot.@@ -66,19 +69,19 @@  - then pausing the thread until a ResumeTransfer exception is raised,  - then rerunning the action.  -}-runTransferThread :: FilePath -> Maybe (Transfer, TransferInfo, Transferrer -> Assistant ()) -> Assistant ()-runTransferThread _ Nothing = flip MSemN.signal 1 <<~ transferSlots-runTransferThread program (Just (t, info, a)) = do+runTransferThread :: FilePath -> BatchCommandMaker -> Maybe (Transfer, TransferInfo, Transferrer -> Assistant ()) -> Assistant ()+runTransferThread _ _ Nothing = flip MSemN.signal 1 <<~ transferSlots+runTransferThread program batchmaker (Just (t, info, a)) = do 	d <- getAssistant id 	aio <- asIO1 a-	tid <- liftIO $ forkIO $ runTransferThread' program d aio+	tid <- liftIO $ forkIO $ runTransferThread' program batchmaker d aio 	updateTransferInfo t $ info { transferTid = Just tid } -runTransferThread' :: FilePath -> AssistantData -> (Transferrer -> IO ()) -> IO ()-runTransferThread' program d run = go+runTransferThread' :: FilePath -> BatchCommandMaker -> AssistantData -> (Transferrer -> IO ()) -> IO ()+runTransferThread' program batchmaker d run = go   where 	go = catchPauseResume $-		withTransferrer program (transferrerPool d)+		withTransferrer program batchmaker (transferrerPool d) 			run 	pause = catchPauseResume $ 		runEvery (Seconds 86400) noop@@ -251,18 +254,23 @@ 	signalthread tid 		| pause = throwTo tid PauseTransfer 		| otherwise = killThread tid+	{- In order to stop helper processes like rsync,+	 - kill the whole process group of the process+	 - running the transfer. -} 	killproc pid = void $ tryIO $ do #ifndef mingw32_HOST_OS-		{- In order to stop helper processes like rsync,-		 - kill the whole process group of the process-		 - running the transfer. -} 		g <- getProcessGroupIDOf pid-		void $ tryIO $ signalProcessGroup sigTERM g-		threadDelay 50000 -- 0.05 second grace period-		void $ tryIO $ signalProcessGroup sigKILL g+		let signal sig = void $ tryIO $ signalProcessGroup sig g+		signal sigTERM+		graceperiod+		signal sigKILL #else-		error "TODO: cancelTransfer not implemented on Windows"+		let signal sig = void $ tryIO $ generateConsoleCtrlEvent sig pid+		signal cTRL_C_EVENT+		graceperiod+		signal cTRL_BREAK_EVENT #endif+	graceperiod = threadDelay 50000 -- 0.05 second  {- Start or resume a transfer. -} startTransfer :: Transfer -> Assistant ()@@ -279,7 +287,8 @@ 		liftIO $ throwTo tid ResumeTransfer 	start info = do 		program <- liftIO readProgramFile-		inImmediateTransferSlot program $+		batchmaker <- liftIO getBatchCommandMaker+		inImmediateTransferSlot program batchmaker $ 			genTransfer t info  getCurrentTransfers :: Assistant TransferMap
Assistant/TransferrerPool.hs view
@@ -5,27 +5,24 @@  - Licensed under the GNU GPL version 3 or higher.  -} -{-# LANGUAGE CPP #-}- module Assistant.TransferrerPool where  import Assistant.Common import Assistant.Types.TransferrerPool import Logs.Transfer+import Utility.Batch -#ifndef mingw32_HOST_OS import qualified Command.TransferKeys as T-#endif  import Control.Concurrent.STM-import System.Process (create_group)+import System.Process (create_group, std_in, std_out) import Control.Exception (throw) import Control.Concurrent  {- Runs an action with a Transferrer from the pool. -}-withTransferrer :: FilePath -> TransferrerPool -> (Transferrer -> IO a) -> IO a-withTransferrer program pool a = do-	t <- maybe (mkTransferrer program) (checkTransferrer program)+withTransferrer :: FilePath -> BatchCommandMaker -> TransferrerPool -> (Transferrer -> IO a) -> IO a+withTransferrer program batchmaker pool a = do+	t <- maybe (mkTransferrer program batchmaker) (checkTransferrer program batchmaker) 		=<< atomically (tryReadTChan pool) 	v <- tryNonAsync $ a t 	unlessM (putback t) $@@ -43,49 +40,36 @@  - finish. -} performTransfer :: Transferrer -> Transfer -> AssociatedFile -> IO Bool performTransfer transferrer t f = catchBoolIO $ do-#ifndef mingw32_HOST_OS 	T.sendRequest t f (transferrerWrite transferrer) 	T.readResponse (transferrerRead transferrer)-#else-	error "TODO performTransfer not implemented on Windows"-#endif -{- Starts a new git-annex transferkeys process, setting up a pipe+{- Starts a new git-annex transferkeys process, setting up handles  - that will be used to communicate with it. -}-mkTransferrer :: FilePath -> IO Transferrer-mkTransferrer program = do-#ifndef mingw32_HOST_OS-	(myread, twrite) <- createPipe-	(tread, mywrite) <- createPipe-	mapM_ (\fd -> setFdOption fd CloseOnExec True) [myread, mywrite]-	let params =-		[ Param "transferkeys"-		, Param "--readfd", Param $ show tread-		, Param "--writefd", Param $ show twrite-		]+mkTransferrer :: FilePath -> BatchCommandMaker -> IO Transferrer+mkTransferrer program batchmaker = do+	{- It runs as a batch job. -}+	let (program', params') = batchmaker (program, [Param "transferkeys"]) 	{- It's put into its own group so that the whole group can be 	 - killed to stop a transfer. -}-	(_, _, _, pid) <- createProcess (proc program $ toCommand params)-		{ create_group = True }-	closeFd twrite-	closeFd tread-	myreadh <- fdToHandle myread-	mywriteh <- fdToHandle mywrite-	fileEncoding myreadh-	fileEncoding mywriteh+	(Just writeh, Just readh, _, pid) <- createProcess+		(proc program' $ toCommand params')+		{ create_group = True+		, std_in = CreatePipe+		, std_out = CreatePipe+		}+	fileEncoding readh+	fileEncoding writeh 	return $ Transferrer-		{ transferrerRead = myreadh-		, transferrerWrite = mywriteh+		{ transferrerRead = readh+		, transferrerWrite = writeh 		, transferrerHandle = pid 		}-#else-	error "TODO mkTransferrer not implemented on Windows"-#endif  {- Checks if a Transferrer is still running. If not, makes a new one. -}-checkTransferrer :: FilePath -> Transferrer -> IO Transferrer-checkTransferrer program t = maybe (return t) (const $ mkTransferrer program)-	=<< getProcessExitCode (transferrerHandle t)+checkTransferrer :: FilePath -> BatchCommandMaker -> Transferrer -> IO Transferrer+checkTransferrer program batchmaker t =+	maybe (return t) (const $ mkTransferrer program batchmaker)+		=<< getProcessExitCode (transferrerHandle t)  {- Closing the fds will stop the transferrer. -} stopTransferrer :: Transferrer -> IO ()
Assistant/WebApp/Configurators/Local.hs view
@@ -22,9 +22,9 @@ import qualified Annex import Config.Files import Utility.FreeDesktop+import Utility.DiskFree #ifdef WITH_CLIBS import Utility.Mounts-import Utility.DiskFree #endif import Utility.DataUnits import Utility.Network@@ -116,12 +116,18 @@ defaultRepositoryPath firstrun = do 	cwd <- liftIO getCurrentDirectory 	home <- myHomeDir+#ifndef mingw32_HOST_OS 	if home == cwd && firstrun 		then inhome 		else ifM (legit cwd <&&> canWrite cwd) 			( return cwd 			, inhome 			)+#else+	-- Windows user can probably write anywhere, so always default+	-- to ~/Desktop/annex.+	inhome+#endif   where 	inhome = do 		desktop <- userDesktopDir@@ -207,7 +213,7 @@ selectDriveForm :: [RemovableDrive] -> Hamlet.Html -> MkMForm RemovableDrive selectDriveForm drives = renderBootstrap $ RemovableDrive 	<$> pure Nothing-	<*> areq (selectFieldList pairs) "Select drive:" Nothing+	<*> areq (selectFieldList pairs `withNote` onlywritable) "Select drive:" Nothing 	<*> areq textField "Use this directory on the drive:" 		(Just $ T.pack gitAnnexAssistantDefaultDir)   where@@ -221,6 +227,7 @@ 				, T.concat ["(", T.pack sz] 				, "free)" 				]+	onlywritable = [whamlet|This list only includes drives you can write to.|]  removableDriveRepository :: RemovableDrive -> FilePath removableDriveRepository drive =@@ -342,13 +349,14 @@  {- List of removable drives. -} driveList :: IO [RemovableDrive]+#ifdef mingw32_HOST_OS+-- Just enumerate all likely drive letters for Windows.+-- Could use wmic, but it only works for administrators.+driveList = mapM (\d -> genRemovableDrive $ d:":\\") ['A'..'Z']+#else #ifdef WITH_CLIBS-driveList = mapM (gen . mnt_dir) =<< filter sane <$> getMounts+driveList = mapM (genRemovableDrive . mnt_dir) =<< filter sane <$> getMounts   where-	gen dir = RemovableDrive-		<$> getDiskFree dir-		<*> pure (T.pack dir)-		<*> pure (T.pack gitAnnexAssistantDefaultDir) 	-- filter out some things that are surely not removable drives 	sane Mntent { mnt_dir = dir, mnt_fsname = dev } 		{- We want real disks like /dev/foo, not@@ -369,6 +377,13 @@ #else driveList = return [] #endif+#endif++genRemovableDrive :: FilePath -> IO RemovableDrive+genRemovableDrive dir = RemovableDrive+	<$> getDiskFree dir+	<*> pure (T.pack dir)+	<*> pure (T.pack gitAnnexAssistantDefaultDir)  {- Bootstraps from first run mode to a fully running assistant in a  - repository, by running the postFirstRun callback, which returns the
Assistant/WebApp/Configurators/WebDAV.hs view
@@ -73,7 +73,7 @@ 				[ configureEncryption $ enableEncryption input 				, ("embedcreds", if embedCreds input then "yes" else "no") 				, ("type", "webdav")-				, ("url", "https://www.box.com/dav/" ++ T.unpack (directory input))+				, ("url", "https://dav.box.com/dav/" ++ T.unpack (directory input)) 				-- Box.com has a max file size of 100 mb, but 				-- using smaller chunks has better memory 				-- performance.
Assistant/WebApp/Control.hs view
@@ -18,9 +18,14 @@ import Utility.NotificationBroadcaster  import Control.Concurrent-import System.Posix (getProcessID, signalProcess, sigTERM) import qualified Data.Map as M import qualified Data.Text as T+#ifndef mingw32_HOST_OS+import System.Posix (getProcessID, signalProcess, sigTERM)+#else+import System.Win32.Process.Current (getCurrentProcessId)+import System.Win32.Console (generateConsoleCtrlEvent, cTRL_C_EVENT)+#endif  getShutdownR :: Handler Html getShutdownR = page "Shutdown" Nothing $@@ -48,7 +53,11 @@ 	 - page time to load in the browser. -} 	void $ liftIO $ forkIO $ do 		threadDelay 2000000+#ifndef mingw32_HOST_OS 		signalProcess sigTERM =<< getProcessID+#else+		generateConsoleCtrlEvent cTRL_C_EVENT =<< getCurrentProcessId+#endif 	redirect NotRunningR  {- Use a custom page to avoid putting long polling elements on it that will 
Assistant/WebApp/DashBoard.hs view
@@ -118,21 +118,27 @@ openFileBrowser :: Handler Bool openFileBrowser = do 	path <- liftAnnex $ fromRepo Git.repoPath-	ifM (liftIO $ inPath cmd <&&> inPath cmd)+#ifdef darwin_HOST_OS+	let cmd = "open"+	let params = [Param path]+#else+#ifdef mingw32_HOST_OS+	let cmd = "cmd"+	let params = [Param $ "/c start " ++ path]+#else+	let cmd = "xdg-open"+	let params = [Param path]+#endif+#endif+	ifM (liftIO $ inPath cmd) 		( do 			void $ liftIO $ forkIO $ void $-				boolSystem cmd [Param path]+				boolSystem cmd params 			return True 		, do 			void $ redirect $ "file://" ++ path 			return False 		)-  where-#ifdef darwin_HOST_OS-	cmd = "open"-#else-	cmd = "xdg-open"-#endif  {- Transfer controls. The GET is done in noscript mode and redirects back  - to the referring page. The POST is called by javascript. -}
Assistant/WebApp/Page.hs view
@@ -5,7 +5,7 @@  - Licensed under the GNU AGPL version 3 or higher.  -} -{-# LANGUAGE TypeFamilies, QuasiQuotes, MultiParamTypeClasses, TemplateHaskell, OverloadedStrings, RankNTypes #-}+{-# LANGUAGE TypeFamilies, QuasiQuotes, MultiParamTypeClasses, TemplateHaskell, OverloadedStrings, RankNTypes, CPP #-}  module Assistant.WebApp.Page where @@ -59,12 +59,12 @@ 		Nothing -> do 			navbar <- map navdetails <$> selectNavBar 			pageinfo <- widgetToPageContent $ do-				addStylesheet $ StaticR css_bootstrap_css-				addStylesheet $ StaticR css_bootstrap_responsive_css+				addStylesheet $ StaticR bootstrap_css+				addStylesheet $ StaticR bootstrap_responsive_css 				addScript $ StaticR jquery_full_js-				addScript $ StaticR js_bootstrap_dropdown_js-				addScript $ StaticR js_bootstrap_modal_js-				addScript $ StaticR js_bootstrap_collapse_js+				addScript $ StaticR bootstrap_dropdown_js+				addScript $ StaticR bootstrap_modal_js+				addScript $ StaticR bootstrap_collapse_js 				when with_longpolling $ 					addScript $ StaticR longpolling_js 				$(widgetFile "page")@@ -72,6 +72,13 @@ 		Just msg -> error msg   where 	navdetails i = (navBarName i, navBarRoute i, Just i == navbaritem)++hasFileBrowser :: Bool+#ifdef ANDROID_SPLICES+hasFileBrowser = False+#else+hasFileBrowser = True+#endif  controlMenu :: Widget controlMenu = $(widgetFile "controlmenu")
Assistant/WebApp/Types.hs view
@@ -73,8 +73,8 @@ 	defaultLayout content = do 		webapp <- getYesod 		pageinfo <- widgetToPageContent $ do-			addStylesheet $ StaticR css_bootstrap_css-			addStylesheet $ StaticR css_bootstrap_responsive_css+			addStylesheet $ StaticR bootstrap_css+			addStylesheet $ StaticR bootstrap_responsive_css 			$(widgetFile "error") 		giveUrlRenderer $(hamletFile $ hamletTemplate "bootstrap") 
Backend/Hash.hs view
@@ -129,9 +129,7 @@ 	any (not . validExtension) (takeExtensions $ keyName key)  hashFile :: Hash -> FilePath -> Integer -> Annex String-hashFile hash file filesize = do-	showAction "checksum"-	liftIO $ go hash+hashFile hash file filesize = liftIO $ go hash   where   	go (SHAHash hashsize) = case shaHasher hashsize filesize of 		Left sha -> sha <$> L.readFile file
Build/BundledPrograms.hs view
@@ -29,8 +29,12 @@ 	, Just "xargs" #endif 	, Just "rsync"+#ifndef darwin_HOST_OS+	-- OS X has ssh installed by default.+	-- (Linux probably, but not guaranteed.) 	, Just "ssh" 	, Just "ssh-keygen"+#endif #ifndef mingw32_HOST_OS 	, Just "sh" #endif@@ -50,8 +54,9 @@ 	, Just "gunzip" 	, Just "tar" #endif-	-- nice and ionice are not included in the bundle; we rely on the-	-- system's own version, which may better match its kernel+	-- nice, ionice, and nocache are not included in the bundle;+	-- we rely on the system's own version, which may better match+	-- its kernel, and avoid using them if not available. 	]   where 	ifset True s = Just s
Build/Configure.hs view
@@ -38,6 +38,7 @@ 	, TestCase "newquvi" $ testCmd "newquvi" "quvi info >/dev/null" 	, TestCase "nice" $ testCmd "nice" "nice true >/dev/null" 	, TestCase "ionice" $ testCmd "ionice" "ionice -c3 true >/dev/null"+	, TestCase "nocache" $ testCmd "nocache" "nocache true >/dev/null" 	, TestCase "gpg" $ maybeSelectCmd "gpg" 		[ ("gpg", "--version >/dev/null") 		, ("gpg2", "--version >/dev/null") ]
+ Build/EvilLinker.hs view
@@ -0,0 +1,158 @@+{- Allows linking haskell programs too big for all the files to fit in a+ - command line.+ -+ - See https://ghc.haskell.org/trac/ghc/ticket/8596+ -+ - Copyright 2013 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++module Main where++import Data.List.Utils+import Text.Parsec+import Text.Parsec.String+import Control.Applicative ((<$>))+import Control.Monad+import System.Directory+import Data.Maybe++import Utility.Monad+import Utility.Process+import Utility.Env++data CmdParams = CmdParams+	{ cmd :: String+	, opts :: String+	, env :: Maybe [(String, String)]+	} deriving (Show)++{- Find where ghc calls gcc to link the executable. -}+parseGhcLink :: Parser CmdParams+parseGhcLink = do+	void $ many prelinkline+	void linkheaderline+	void $ char '"'+	gcccmd <- many1 (noneOf "\"")+	void $ string "\" "+	gccparams <- restOfLine+	return $ CmdParams gcccmd (manglepaths gccparams) Nothing+  where+	linkheaderline = do+		void $ string "*** Linker"+		restOfLine+	prelinkline = do+		void $ notFollowedBy linkheaderline+		restOfLine+	manglepaths = replace "\\" "/"++{- Find where gcc calls collect2. -}+parseGccLink :: Parser CmdParams+parseGccLink = do+	cenv <- collectenv+	void $ try $ char ' '+	path <- manyTill anyChar (try $ string collectcmd)+	void $ char ' '+	collect2params <- restOfLine+	return $ CmdParams (path ++ collectcmd) (escapeDosPaths collect2params) cenv+  where+  	collectcmd = "collect2.exe"+  	collectgccenv = "COLLECT_GCC"+	collectltoenv = "COLLECT_LTO_WRAPPER"+	pathenv = "COMPILER_PATH"+	libpathenv = "LIBRARY_PATH"+  	optenv = "COLLECT_GCC_OPTIONS"+  	collectenv = do+		void $ many1 $ do+			notFollowedBy $ string collectgccenv+			restOfLine+		void $ string collectgccenv+		void $ char '='+		g <- restOfLine+		void $ string collectltoenv+		void $ char '='+		lt <- restOfLine+		void $ many1 $ do+			notFollowedBy $ string pathenv+			restOfLine+		void $ string pathenv+		void $ char '='+		p <- restOfLine+		void $ string libpathenv+		void $ char '='+		lp <- restOfLine+		void $ string optenv+		void $ char '='+		o <- restOfLine+		return $ Just [(collectgccenv, g), (collectltoenv, lt), (pathenv, p), (libpathenv, lp), (optenv, o)]++{- Find where collect2 calls ld. -}+parseCollect2 :: Parser CmdParams+parseCollect2 = do+	void $ manyTill restOfLine (try versionline)+	path <- manyTill anyChar (try $ string ldcmd)+	void $ char ' '+	params <- restOfLine+	return $ CmdParams (path ++ ldcmd) (escapeDosPaths params) Nothing+  where+	ldcmd = "ld.exe"+	versionline = do+		void $ string "collect2 version"+		restOfLine+	+{- Input contains something like + - c:/program files/haskell platform/foo -LC:/Program Files/Haskell Platform/ -L...+ - and the *right* spaces must be escaped with \+ -+ - Argh.+ -}+escapeDosPaths :: String -> String+escapeDosPaths = replace "Program Files" "Program\\ Files"+	. replace "program files" "program\\ files"+	. replace "Haskell Platform" "Haskell\\ Platform"+	. replace "haskell platform" "haskell\\ platform"+	. replace "Application Data" "Application\\ Data"+	. replace "Documents and Settings" "Documents\\ and\\ Settings"+	. replace "Files (x86)" "Files\\ (x86)"+	. replace "files (x86)" "files\\ (x86)"++restOfLine :: Parser String+restOfLine = newline `after` many (noneOf "\n")++getOutput :: String -> [String] -> Maybe [(String, String)] -> IO (String, Bool)+getOutput c ps environ = do+	putStrLn $ unwords [c, show ps]+	systemenviron <- getEnvironment+	let environ' = fromMaybe [] environ ++ systemenviron+	out@(s, ok) <- processTranscript' c ps (Just environ') Nothing+	putStrLn $ unwords [c, "finished", show ok, "output size:", show (length s)]+	return out++atFile :: FilePath -> String+atFile f = '@':f++runAtFile :: Parser CmdParams -> String -> FilePath -> [String] -> IO (String, Bool)+runAtFile p s f extraparams = do+	when (null $ opts c) $+		error $ "failed to find any options for " ++ f ++ " in >>>" ++ s ++ "<<<"+	writeFile f (opts c)+	out <- getOutput (cmd c) (atFile f:extraparams) (env c)+	removeFile f+	return out+  where+ 	c = case parse p "" s of+		Left e -> error $+			(show e) ++ +			"\n<<<\n" ++ s ++ "\n>>>"+		Right r -> r++main :: IO ()+main = do+	ghcout <- fst <$> getOutput "cabal"+		["build", "--ghc-options=-v -keep-tmp-files"] Nothing+	gccout <- fst <$> runAtFile parseGhcLink ghcout "gcc.opt" ["-v"]+	collect2out <- fst <$> runAtFile parseGccLink gccout "collect2.opt" ["-v"]+	(out, ok) <- runAtFile parseCollect2 collect2out "ld.opt" []+	unless ok $+		error $ "ld failed:\n" ++ out
Build/NullSoftInstaller.hs view
@@ -69,6 +69,9 @@ gitInstallDir :: Exp FilePath
 gitInstallDir = fromString "$PROGRAMFILES\\Git\\cmd"
 
+startMenuItem :: Exp FilePath
+startMenuItem = "$SMPROGRAMS/git-annex.lnk"
+
 needGit :: Exp String
 needGit = strConcat
 	[ fromString "You need git installed to use git-annex. Looking at "
@@ -85,7 +88,7 @@ 	{- Installing into the same directory as git avoids needing to modify
  	 - path myself, since the git installer already does it. -}
 	installDir gitInstallDir
-	requestExecutionLevel User
+	requestExecutionLevel Admin
 
 	iff (fileExists gitInstallDir)
 		(return ())
@@ -95,6 +98,17 @@ 	page Directory                   -- Pick where to install
 	page (License license)
 	page InstFiles                   -- Give a progress bar while installing
+	-- Start menu shortcut
+	Development.NSIS.createDirectory "$SMPROGRAMS"
+	createShortcut startMenuItem
+		[ Target "$INSTDIR/git-annex.exe"
+		, Parameters "webapp"
+		, IconFile "$INSTDIR/git-annex.exe"
+		, IconIndex 2
+		, StartOptions "SW_SHOWMINIMIZED"
+		, KeyboardShortcut "ALT|CONTROL|a"
+		, Description "git-annex webapp"
+		]
 	-- Groups of files to install
 	section "main" [] $ do
 		setOutPath "$INSTDIR"
@@ -102,7 +116,8 @@ 		addfile license
 		mapM_ addfile extrafiles
 		writeUninstaller $ str uninstaller
-	uninstall $
+	uninstall $ do
+		delete [RebootOK] $ startMenuItem
 		mapM_ (\f -> delete [RebootOK] $ fromString $ "$INSTDIR/" ++ f) $
 			[ gitannexprogram
 			, licensefile
@@ -115,6 +130,8 @@ cygwinPrograms = map (\p -> p ++ ".exe") bundledPrograms
 
 -- These are the dlls needed by Cygwin's rsync, ssh, etc.
+-- TODO: Use ldd (available in cygwin) to automatically find all
+-- needed libs.
 cygwinDlls :: [FilePath]
 cygwinDlls =
 	[ "cygwin1.dll"
@@ -136,4 +153,14 @@ 	, "cyggssapi-3.dll"
 	, "cygkrb5-26.dll"
 	, "cygz.dll"
+	, "cygidn-11.dll"
+	, "libcurl-4.dll"
+	, "cyggnutls-26.dll"
+	, "libcrypto.dll"
+	, "libssl.dll"
+	, "cyggcrypt-11.dll"
+	, "cyggpg-error-0.dll"
+	, "cygp11-kit-0.dll"
+	, "cygtasn1-3.dll"
+	, "cygffi-6.dll"
 	]
CHANGELOG view
@@ -1,3 +1,38 @@+git-annex (5.20131213) unstable; urgency=low++  * Avoid using git commit in direct mode, since in some situations+    it will read the full contents of files in the tree.+  * assistant: Batch jobs are now run with ionice and nocache, when+    those commands are available.+  * assistant: Run transferkeys as batch jobs.+  * Automatically fix up bad bare repositories created by+    versions 5.20131118 through 5.20131127.+  * rsync special remote: Fix fallback mode for rsync remotes that+    use hashDirMixed. Closes: #731142+  * copy --from, get --from: When --force is used, ignore the+    location log and always try to get the file from the remote.+  * Deal with box.com changing the url of their webdav endpoint.+  * Android: Fix SRV record lookups for XMPP to use android getprop+    command to find DNS server, since there is no resolv.conf.+  * import: Add --skip-duplicates option.+  * lock: Require --force. Closes: #731606+  * import: better handling of overwriting an existing file/directory/broken+    link when importing+  * Windows: assistant and webapp work! (very experimental)+  * Windows: Support annex.diskreserve.+  * Fix bad behavior in Firefox, which was caused by an earlier fix to+    bad behavior in Chromium.+  * repair: Improve repair of git-annex index file.+  * repair: Remove damaged git-annex sync branches.+  * status: Ignore new files that are gitignored.+  * Fix direct mode's handling when modifications to non-annexed files+    are pulled from a remote. A bug prevented the files from being updated+    in the work tree, and this caused the modification to be reverted.+  * OSX: Remove ssh and ssh-keygen from dmg as they're included in OSX by+    default.++ -- Joey Hess <joeyh@debian.org>  Fri, 13 Dec 2013 14:20:32 -0400+ git-annex (5.20131130) unstable; urgency=low    * init: Fix a bug that caused git annex init, when run in a bare
@@ -88,7 +88,7 @@  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Files: static/*/bootstrap* static/img/glyphicons-halflings*+Files: static/bootstrap* static/glyphicons-halflings* Copyright: 2012 Twitter, Inc. License: Apache-2.0  Licensed under the Apache License, Version 2.0 (the "License");
Command/Fsck.hs view
@@ -38,7 +38,7 @@ #ifndef mingw32_HOST_OS import System.Posix.Process (getProcessID) #else-import System.Random (getStdRandom, random)+import System.Win32.Process.Current (getCurrentProcessId) #endif import Data.Time.Clock.POSIX import Data.Time@@ -154,7 +154,7 @@ #ifndef mingw32_HOST_OS 		v <- liftIO getProcessID #else-		v <- liftIO (getStdRandom random :: IO Int)+		v <- liftIO getCurrentProcessId #endif 		t <- fromRepo gitAnnexTmpDir 		createAnnexDirectory t@@ -236,7 +236,7 @@ 		(Remote.logStatus remote key)  verifyLocationLog' :: Key -> String -> Bool -> UUID -> (LogStatus -> Annex ()) -> Annex Bool-verifyLocationLog' key desc present u bad = do+verifyLocationLog' key desc present u updatestatus = do 	uuids <- Remote.keyLocations key 	case (present, u `elem` uuids) of 		(True, False) -> do@@ -254,7 +254,7 @@   where 	fix s = do 		showNote "fixing location log"-		bad s+		updatestatus s  {- Ensures the direct mode mapping file is consistent. Each file  - it lists for the key should exist, and the specified file should be
Command/Import.hs view
@@ -28,18 +28,22 @@ 	[ duplicateOption 	, deduplicateOption 	, cleanDuplicatesOption+	, skipDuplicatesOption 	]  duplicateOption :: Option-duplicateOption = Option.flag [] "duplicate" "do not delete outside files"+duplicateOption = Option.flag [] "duplicate" "do not delete source files"  deduplicateOption :: Option-deduplicateOption = Option.flag [] "deduplicate" "do not add files whose content has been seen"+deduplicateOption = Option.flag [] "deduplicate" "delete source files whose content was imported before"  cleanDuplicatesOption :: Option-cleanDuplicatesOption = Option.flag [] "clean-duplicates" "delete outside duplicate files (import nothing)"+cleanDuplicatesOption = Option.flag [] "clean-duplicates" "delete duplicate source files (import nothing)" -data DuplicateMode = Default | Duplicate | DeDuplicate | CleanDuplicates+skipDuplicatesOption :: Option+skipDuplicatesOption = Option.flag [] "skip-duplicates" "import only new files"++data DuplicateMode = Default | Duplicate | DeDuplicate | CleanDuplicates | SkipDuplicates 	deriving (Eq)  getDuplicateMode :: Annex DuplicateMode@@ -47,13 +51,15 @@ 	<$> getflag duplicateOption 	<*> getflag deduplicateOption 	<*> getflag cleanDuplicatesOption+	<*> getflag skipDuplicatesOption   where   	getflag = Annex.getFlag . Option.name-  	gen False False False = Default-	gen True False False = Duplicate-	gen False True False = DeDuplicate-	gen False False True = CleanDuplicates-	gen _ _ _ = error "bad combination of --duplicate, --deduplicate, --clean-duplicates"+  	gen False False False False = Default+	gen True False False False = Duplicate+	gen False True False False = DeDuplicate+	gen False False True False = CleanDuplicates+	gen False False False True = SkipDuplicates+	gen _ _ _ _ = error "bad combination of --duplicate, --deduplicate, --clean-duplicates, --skip-duplicates"  seek :: [CommandSeek] seek = [withValue getDuplicateMode $ \mode -> withPathContents $ start mode]@@ -62,43 +68,49 @@ start mode (srcfile, destfile) = 	ifM (liftIO $ isRegularFile <$> getSymbolicLinkStatus srcfile) 		( do-			showStart "import" destfile-			next $ perform mode srcfile destfile+			isdup <- do+				backend <- chooseBackend destfile+				let ks = KeySource srcfile srcfile Nothing+				v <- genKey ks backend+				case v of+					Just (k, _) -> not . null <$> keyLocations k+					_ -> return False+			case pickaction isdup of+				Nothing -> stop+				Just a -> do+					showStart "import" destfile+					next a 		, stop 		)--perform :: DuplicateMode -> FilePath -> FilePath -> CommandPerform-perform mode srcfile destfile =-	case mode of-		DeDuplicate -> ifM isdup-			( deletedup-			, go-			)-		CleanDuplicates -> ifM isdup-			( deletedup-			, next $ return True-			)-		_ -> go   where-	isdup = do-		backend <- chooseBackend destfile-		let ks = KeySource srcfile srcfile Nothing-		v <- genKey ks backend-		case v of-			Just (k, _) -> not . null <$> keyLocations k-			_ -> return False 	deletedup = do 		showNote "duplicate" 		liftIO $ removeFile srcfile 		next $ return True-	go = do-		whenM (liftIO $ doesFileExist destfile) $-			unlessM (Annex.getState Annex.force) $-				error $ "not overwriting existing " ++ destfile ++-					" (use --force to override)"-	+	importfile = do+		handleexisting =<< liftIO (catchMaybeIO $ getSymbolicLinkStatus destfile) 		liftIO $ createDirectoryIfMissing True (parentDir destfile)-		liftIO $ if mode == Duplicate+		liftIO $ if mode == Duplicate || mode == SkipDuplicates 			then void $ copyFileExternal srcfile destfile 			else moveFile srcfile destfile 		Command.Add.perform destfile+	handleexisting Nothing = noop+	handleexisting (Just s)+		| isDirectory s = notoverwriting "(is a directory)"+		| otherwise = ifM (Annex.getState Annex.force) $+			( liftIO $ nukeFile destfile+			, notoverwriting "(use --force to override)"+			)+	notoverwriting why = error $ "not overwriting existing " ++ destfile ++ " " ++ why+	pickaction isdup = case mode of+		DeDuplicate+			| isdup -> Just deletedup+			| otherwise -> Just importfile+		CleanDuplicates+			| isdup -> Just deletedup+			| otherwise -> Nothing+		SkipDuplicates+			| isdup -> Nothing+			| otherwise -> Just importfile+		_ -> Just importfile+
Command/Lock.hs view
@@ -10,6 +10,7 @@ import Common.Annex import Command import qualified Annex.Queue+import qualified Annex 	 def :: [Command] def = [notDirect $ command "lock" paramPaths seek SectionCommon@@ -21,6 +22,8 @@ start :: FilePath -> CommandStart start file = do 	showStart "lock" file+	unlessM (Annex.getState Annex.force) $+		error "Locking this file would discard any changes you have made to it. Use 'git annex add' to stage your changes. (Or, use --force to override)" 	next $ perform file  perform :: FilePath -> CommandPerform
Command/Move.hs view
@@ -133,11 +133,14 @@ 		next $ fromPerform src move key afile  fromOk :: Remote -> Key -> Annex Bool-fromOk src key-	| Remote.hasKeyCheap src =-		either (const expensive) return =<< Remote.hasKey src key-	| otherwise = expensive+fromOk src key = go =<< Annex.getState Annex.force   where+	go True = either (const $ return True) return =<< haskey+	go False+		| Remote.hasKeyCheap src =+			either (const expensive) return =<< haskey+		| otherwise = expensive+	haskey = Remote.hasKey src key 	expensive = do 		u <- getUUID 		remotes <- Remote.keyPossibilities key
Command/PreCommit.hs view
@@ -11,12 +11,7 @@ import Command import qualified Command.Add import qualified Command.Fix-import qualified Git.DiffTree-import qualified Git.Ref-import Annex.CatFile-import Annex.Content.Direct-import Git.Sha-import Git.FilePath+import Annex.Direct  def :: [Command] def = [command "pre-commit" paramPaths seek SectionPlumbing@@ -39,19 +34,4 @@ 	next $ return True  startDirect :: [String] -> CommandStart-startDirect _ = next $ do-	(diffs, clean) <- inRepo $ Git.DiffTree.diffIndex Git.Ref.headRef-	makeabs <- flip fromTopFilePath <$> gitRepo-	forM_ diffs (go makeabs)-	next $ liftIO clean-  where-	go makeabs diff = do-		withkey (Git.DiffTree.srcsha diff) (Git.DiffTree.srcmode diff) removeAssociatedFile-		withkey (Git.DiffTree.dstsha diff) (Git.DiffTree.dstmode diff) addAssociatedFile-	  where-		withkey sha mode a = when (sha /= nullSha) $ do-			k <- catKey sha mode-			case k of-				Nothing -> noop-				Just key -> void $ a key $-					makeabs $ Git.DiffTree.file diff+startDirect _ = next $ next $ preCommitDirect
Command/Repair.hs view
@@ -12,7 +12,6 @@ import qualified Annex import qualified Git.Repair import qualified Annex.Branch-import Git.Fsck (MissingObjects) import Git.Types import Annex.Version @@ -28,12 +27,12 @@  runRepair :: Bool -> Annex Bool runRepair forced = do-	(ok, stillmissing, modifiedbranches) <- inRepo $-		Git.Repair.runRepair forced+	(ok, modifiedbranches) <- inRepo $+		Git.Repair.runRepair isAnnexSyncBranch forced 	-- This command can be run in git repos not using git-annex, 	-- so avoid git annex branch stuff in that case. 	whenM (isJust <$> getVersion) $-		repairAnnexBranch stillmissing modifiedbranches+		repairAnnexBranch modifiedbranches 	return ok  {- After git repository repair, the .git/annex/index file could@@ -50,8 +49,8 @@  - yet reflected in the index, this does properly merge those into the  - index before committing.  -}-repairAnnexBranch :: MissingObjects -> [Branch] -> Annex ()-repairAnnexBranch missing modifiedbranches+repairAnnexBranch :: [Branch] -> Annex ()+repairAnnexBranch modifiedbranches 	| Annex.Branch.fullname `elem` modifiedbranches = ifM okindex 		( commitindex 		, do@@ -63,9 +62,14 @@ 		, nukeindex 		)   where-	okindex = Annex.Branch.withIndex $-		inRepo $ Git.Repair.checkIndex missing+	okindex = Annex.Branch.withIndex $ inRepo $ Git.Repair.checkIndex 	commitindex = do 		Annex.Branch.forceCommit "committing index after git repository repair" 		liftIO $ putStrLn "Successfully recovered the git-annex branch using .git/annex/index" 	nukeindex = inRepo $ nukeFile . gitAnnexIndex++trackingOrSyncBranch :: Ref -> Bool+trackingOrSyncBranch b = Git.Repair.isTrackingBranch b || isAnnexSyncBranch b++isAnnexSyncBranch :: Ref -> Bool+isAnnexSyncBranch b = "refs/synced/" `isPrefixOf` show b
Command/Sync.hs view
@@ -103,19 +103,33 @@ commit :: CommandStart commit = next $ next $ ifM isDirect 	( do+		showStart "commit" "" 		void stageDirect-		runcommit []-	, runcommit [Param "-a"]-	)-  where-	runcommit ps = do+		void preCommitDirect+		commitStaged commitmessage+	, do 		showStart "commit" ""-		showOutput 		Annex.Branch.commit "update" 		-- Commit will fail when the tree is clean, so ignore failure.-		let params = Param "commit" : ps ++-			[Param "-m", Param "git-annex automatic sync"]-		_ <- inRepo $ tryIO . Git.Command.runQuiet params+		_ <- inRepo $ tryIO . Git.Command.runQuiet+			[ Param "commit"+			, Param "-a"+			, Param "-m"+			, Param commitmessage+			]+		return True+	)+  where+	commitmessage = "git-annex automatic sync"++commitStaged :: String -> Annex Bool+commitStaged commitmessage = go =<< inRepo Git.Branch.currentUnsafe+  where+	go Nothing = return False+	go (Just branch) = do+		parent <- inRepo $ Git.Ref.sha branch+		void $ inRepo $ Git.Branch.commit False commitmessage branch+			(maybe [] (:[]) parent) 		return True  mergeLocal :: Maybe Git.Ref -> CommandStart
Command/TransferKeys.hs view
@@ -16,39 +16,21 @@ import Logs.Transfer import qualified Remote import Types.Key-import qualified Option +import GHC.IO.Handle+ data TransferRequest = TransferRequest Direction Remote Key AssociatedFile  def :: [Command]-def = [withOptions options $-	command "transferkeys" paramNothing seek+def = [command "transferkeys" paramNothing seek 	SectionPlumbing "transfers keys"] -options :: [Option]-options = [readFdOption, writeFdOption]--readFdOption :: Option-readFdOption = Option.field [] "readfd" paramNumber "read from this fd"--writeFdOption :: Option-writeFdOption = Option.field [] "writefd" paramNumber "write to this fd"- seek :: [CommandSeek]-seek = [withField readFdOption convertFd $ \readh ->-	withField writeFdOption convertFd $ \writeh ->-	withNothing $ start readh writeh]--convertFd :: Maybe String -> Annex (Maybe Handle)-convertFd Nothing = return Nothing-convertFd (Just s) = liftIO $ -	case readish s of-		Nothing -> error "bad fd"-		Just fd -> Just <$> fdToHandle fd+seek = [withNothing start] -start :: Maybe Handle -> Maybe Handle -> CommandStart-start readh writeh = do-	runRequests (fromMaybe stdin readh) (fromMaybe stdout writeh) runner+start :: CommandStart+start = withHandles $ \(readh, writeh) -> do+	runRequests readh writeh runner 	stop   where 	runner (TransferRequest direction remote key file)@@ -60,6 +42,21 @@ 				return ok 		| otherwise = download (Remote.uuid remote) key file forwardRetry $ \p -> 			getViaTmp key $ \t -> Remote.retrieveKeyFile remote key file t p++{- stdin and stdout are connected with the caller, to be used for+ - communication with it. But doing a transfer might involve something+ - that tries to read from stdin, or write to stdout. To avoid that, close+ - stdin, and duplicate stderr to stdout. Return two new handles+ - that are duplicates of the original (stdin, stdout). -}+withHandles :: ((Handle, Handle) -> Annex a) -> Annex a+withHandles a = do+	readh <- liftIO $ hDuplicate stdin+	writeh <- liftIO $ hDuplicate stdout+	liftIO $ do+		nullh <- openFile devNull ReadMode+		nullh `hDuplicateTo` stdin+		stderr `hDuplicateTo` stdout+	a (readh, writeh)  runRequests 	:: Handle
Git/Branch.hs view
@@ -89,18 +89,38 @@ 			(False, False) -> findbest c rs -- same  {- Commits the index into the specified branch (or other ref), - - with the specified parent refs, and returns the committed sha -}-commit :: String -> Branch -> [Ref] -> Repo -> IO Sha-commit message branch parentrefs repo = do+ - with the specified parent refs, and returns the committed sha.+ -+ - Without allowempy set, avoids making a commit if there is exactly+ - one parent, and it has the same tree that would be committed.+ -+ - Unlike git-commit, does not run any hooks, or examine the work tree+ - in any way.+ -}+commit :: Bool -> String -> Branch -> [Ref] -> Repo -> IO (Maybe Sha)+commit allowempty message branch parentrefs repo = do 	tree <- getSha "write-tree" $ 		pipeReadStrict [Param "write-tree"] repo-	sha <- getSha "commit-tree" $ pipeWriteRead-		(map Param $ ["commit-tree", show tree] ++ ps)-		(Just $ flip hPutStr message) repo-	update branch sha repo-	return sha+	ifM (cancommit tree)+		( do+			sha <- getSha "commit-tree" $ pipeWriteRead+				(map Param $ ["commit-tree", show tree] ++ ps)+				(Just $ flip hPutStr message) repo+			update branch sha repo+			return $ Just sha+		, return Nothing+		)   where 	ps = concatMap (\r -> ["-p", show r]) parentrefs+	cancommit tree+		| allowempty = return True+		| otherwise = case parentrefs of+			[p] -> maybe False (tree /=) <$> Git.Ref.tree p repo+			_ -> return True++commitAlways :: String -> Branch -> [Ref] -> Repo -> IO Sha+commitAlways message branch parentrefs repo = fromJust+	<$> commit True message branch parentrefs repo  {- A leading + makes git-push force pushing a branch. -} forcePush :: String -> String
Git/FilePath.hs view
@@ -45,15 +45,24 @@ asTopFilePath file = TopFilePath file  {- Git may use a different representation of a path when storing- - it internally. For example, on Windows, git uses '/' to separate paths- - stored in the repository, despite Windows using '\' -}+ - it internally. + -+ - On Windows, git uses '/' to separate paths stored in the repository,+ - despite Windows using '\'. Also, git on windows dislikes paths starting+ - with "./" or ".\".+ -+ -} type InternalGitPath = String  toInternalGitPath :: FilePath -> InternalGitPath #ifndef mingw32_HOST_OS toInternalGitPath = id #else-toInternalGitPath = replace "\\" "/"+toInternalGitPath p =+	let p' = replace "\\" "/" p+	in if "./" `isPrefixOf` p'+		then dropWhile (== '/') (drop 1 p')+		else p' #endif  fromInternalGitPath :: InternalGitPath -> FilePath
Git/Fsck.hs view
@@ -11,6 +11,7 @@ 	findBroken, 	foundBroken, 	findMissing,+	isMissing, 	knownMissing, ) where @@ -25,6 +26,7 @@ type MissingObjects = S.Set Sha  data FsckResults = FsckFoundMissing MissingObjects | FsckFailed+	deriving (Show)  {- Runs fsck to find some of the broken objects in the repository.  - May not find all broken objects, if fsck fails on bad data in some of@@ -37,17 +39,16 @@  -} findBroken :: Bool -> Repo -> IO FsckResults findBroken batchmode r = do+	let (command, params) = ("git", fsckParams r)+	(command', params') <- if batchmode+		then toBatchCommand (command, params)+		else return (command, params) 	(output, fsckok) <- processTranscript command' (toCommand params') Nothing 	let objs = findShas output 	badobjs <- findMissing objs r 	if S.null badobjs && not fsckok 		then return FsckFailed 		else return $ FsckFoundMissing badobjs-  where-	(command, params) = ("git", fsckParams r)-	(command', params')-		| batchmode = toBatchCommand (command, params)-		| otherwise = (command, params)  foundBroken :: FsckResults -> Bool foundBroken FsckFailed = True@@ -60,15 +61,17 @@ {- Finds objects that are missing from the git repsitory, or are corrupt.  -  - This does not use git cat-file --batch, because catting a corrupt- - object can cause it to crash, or to report incorrect size information.a+ - object can cause it to crash, or to report incorrect size information.  -} findMissing :: [Sha] -> Repo -> IO MissingObjects-findMissing objs r = S.fromList <$> filterM (not <$$> present) objs+findMissing objs r = S.fromList <$> filterM (`isMissing` r) objs++isMissing :: Sha -> Repo -> IO Bool+isMissing s r = either (const True) (const False) <$> tryIO dump   where-	present o = either (const False) (const True) <$> tryIO (dump o)-	dump o = runQuiet+	dump = runQuiet 		[ Param "show"-		, Param (show o)+		, Param (show s) 		] r  findShas :: String -> [Sha]
Git/LsFiles.hs view
@@ -66,11 +66,12 @@   where 	params = [Params "ls-files --modified -z --"] ++ map File l -{- Files that have been modified or are not checked into git. -}+{- Files that have been modified or are not checked into git (and are not+ - ignored). -} modifiedOthers :: [FilePath] -> Repo -> IO ([FilePath], IO Bool) modifiedOthers l repo = pipeNullSplit params repo   where-	params = [Params "ls-files --modified --others -z --"] ++ map File l+	params = [Params "ls-files --modified --others --exclude-standard -z --"] ++ map File l  {- Returns a list of all files that are staged for commit. -} staged :: [FilePath] -> Repo -> IO ([FilePath], IO Bool)
Git/Ref.hs view
@@ -10,6 +10,7 @@ import Common import Git import Git.Command+import Git.Sha  import Data.Char (chr) @@ -104,6 +105,11 @@ matchingUniq refs repo = nubBy uniqref <$> matching refs repo   where 	uniqref (a, _) (b, _) = a == b++{- Gets the sha of the tree a ref uses. -}+tree :: Ref -> Repo -> IO (Maybe Sha)+tree ref = extractSha <$$> pipeReadStrict+	[ Param "rev-parse", Param (show ref ++ ":") ]  {- Checks if a String is a legal git ref name.  -
Git/Repair.hs view
@@ -1,4 +1,5 @@ {- git repository recovery+import qualified Data.Set as S  -  - Copyright 2013 Joey Hess <joey@kitenet.net>  -@@ -12,10 +13,11 @@ 	cleanCorruptObjects, 	retrieveMissingObjects, 	resetLocalBranches,-	removeTrackingBranches, 	checkIndex,+	checkIndexFast, 	missingIndex, 	emptyGoodCommits,+	isTrackingBranch, ) where  import Common@@ -187,15 +189,17 @@ 			, Param (show c) 			] r +isTrackingBranch :: Ref -> Bool+isTrackingBranch b = "refs/remotes/" `isPrefixOf` show b+ {- To deal with missing objects that cannot be recovered, removes- - any remote tracking branches that reference them. Returns a list of- - all removed branches.+ - any branches (filtered by a predicate) that reference them+ - Returns a list of all removed branches.  -}-removeTrackingBranches :: MissingObjects -> GoodCommits -> Repo -> IO ([Branch], GoodCommits)-removeTrackingBranches missing goodcommits r =-	go [] goodcommits =<< filter istrackingbranch <$> getAllRefs r+removeBadBranches :: (Ref -> Bool) -> MissingObjects -> GoodCommits -> Repo -> IO ([Branch], GoodCommits)+removeBadBranches removablebranch missing goodcommits r =+	go [] goodcommits =<< filter removablebranch <$> getAllRefs r   where-  	istrackingbranch b = "refs/remotes/" `isPrefixOf` show b 	go removed gcs [] = return (removed, gcs) 	go removed gcs (b:bs) = do 		(ok, gcs') <- verifyCommit missing gcs b r@@ -335,35 +339,42 @@ {- Checks that the index file only refers to objects that are not missing,  - and is not itself corrupt. Note that a missing index file is not  - considered a problem (repo may be new). -}-checkIndex :: MissingObjects -> Repo -> IO Bool-checkIndex missing r = do-	(bad, _good, cleanup) <- partitionIndex missing r+checkIndex :: Repo -> IO Bool+checkIndex r = do+	(bad, _good, cleanup) <- partitionIndex r 	if null bad 		then cleanup 		else do 			void cleanup 			return False +{- Does not check every object the index refers to, but only that the index+ - itself is not corrupt. -}+checkIndexFast :: Repo -> IO Bool+checkIndexFast r = do+	(indexcontents, cleanup) <- LsFiles.stagedDetails [repoPath r] r+	length indexcontents `seq` cleanup+ missingIndex :: Repo -> IO Bool missingIndex r = not <$> doesFileExist (localGitDir r </> "index") -partitionIndex :: MissingObjects -> Repo -> IO ([LsFiles.StagedDetails], [LsFiles.StagedDetails], IO Bool)-partitionIndex missing r = do+{- Finds missing and ok files staged in the index. -}+partitionIndex :: Repo -> IO ([LsFiles.StagedDetails], [LsFiles.StagedDetails], IO Bool)+partitionIndex r = do 	(indexcontents, cleanup) <- LsFiles.stagedDetails [repoPath r] r-	let (bad, good) = partition ismissing indexcontents-	return (bad, good, cleanup)-  where-	getblob (_file, Just sha, Just _mode) = Just sha-	getblob _ = Nothing-	ismissing = maybe False (`S.member` missing) . getblob+	l <- forM indexcontents $ \i -> case i of+		(_file, Just sha, Just _mode) -> (,) <$> isMissing sha r <*> pure i+		_ -> pure (False, i)+	let (bad, good) = partition fst l+	return (map snd bad, map snd good, cleanup)  {- Rewrites the index file, removing from it any files whose blobs are  - missing. Returns the list of affected files. -}-rewriteIndex :: MissingObjects -> Repo -> IO [FilePath]-rewriteIndex missing r+rewriteIndex :: Repo -> IO [FilePath]+rewriteIndex r 	| repoIsLocalBare r = return [] 	| otherwise = do-		(bad, good, cleanup) <- partitionIndex missing r+		(bad, good, cleanup) <- partitionIndex r 		unless (null bad) $ do 			nukeFile (indexFile r) 			UpdateIndex.streamUpdateIndex r@@ -425,40 +436,40 @@ 	validhead s = "ref: refs/" `isPrefixOf` s || isJust (extractSha s)  {- Put it all together. -}-runRepair :: Bool -> Repo -> IO (Bool, MissingObjects, [Branch])-runRepair forced g = do+runRepair :: (Ref -> Bool) -> Bool -> Repo -> IO (Bool, [Branch])+runRepair removablebranch forced g = do 	preRepair g 	putStrLn "Running git fsck ..." 	fsckresult <- findBroken False g 	if foundBroken fsckresult-		then runRepair' fsckresult forced Nothing g+		then runRepair' removablebranch fsckresult forced Nothing g 		else do 			putStrLn "No problems found."-			return (True, S.empty, [])+			return (True, []) -runRepairOf :: FsckResults -> Bool -> Maybe FilePath -> Repo -> IO (Bool, MissingObjects, [Branch])-runRepairOf fsckresult forced referencerepo g = do+runRepairOf :: FsckResults -> (Ref -> Bool) -> Bool -> Maybe FilePath -> Repo -> IO (Bool, [Branch])+runRepairOf fsckresult removablebranch forced referencerepo g = do 	preRepair g-	runRepair' fsckresult forced referencerepo g+	runRepair' removablebranch fsckresult forced referencerepo g -runRepair' :: FsckResults -> Bool -> Maybe FilePath -> Repo -> IO (Bool, MissingObjects, [Branch])-runRepair' fsckresult forced referencerepo g = do+runRepair' :: (Ref -> Bool) -> FsckResults -> Bool -> Maybe FilePath -> Repo -> IO (Bool, [Branch])+runRepair' removablebranch fsckresult forced referencerepo g = do 	missing <- cleanCorruptObjects fsckresult g 	stillmissing <- retrieveMissingObjects missing referencerepo g 	case stillmissing of 		FsckFoundMissing s 			| S.null s -> if repoIsLocalBare g-				then successfulfinish S.empty []-				else ifM (checkIndex S.empty g)-					( successfulfinish s []+				then successfulfinish []+				else ifM (checkIndex g)+					( successfulfinish [] 					, do 						putStrLn "No missing objects found, but the index file is corrupt!" 						if forced 							then corruptedindex-							else needforce S.empty+							else needforce 					) 			| otherwise -> if forced-				then ifM (checkIndex s g)+				then ifM (checkIndex g) 					( continuerepairs s 					, corruptedindex 					)@@ -467,20 +478,22 @@ 						[ show (S.size s) 						, "missing objects could not be recovered!" 						]-					unsuccessfulfinish s+					unsuccessfulfinish 		FsckFailed-			| forced -> ifM (pure (repoIsLocalBare g) <||> checkIndex S.empty g)+			| forced -> ifM (pure (repoIsLocalBare g) <||> checkIndex g) 				( do 					missing' <- cleanCorruptObjects FsckFailed g 					case missing' of-						FsckFailed -> return (False, S.empty, [])-						FsckFoundMissing stillmissing' -> continuerepairs stillmissing'+						FsckFailed -> return (False, [])+						FsckFoundMissing stillmissing' ->+							continuerepairs stillmissing' 				, corruptedindex 				)-			| otherwise -> unsuccessfulfinish S.empty+			| otherwise -> unsuccessfulfinish   where 	continuerepairs stillmissing = do-		(remotebranches, goodcommits) <- removeTrackingBranches stillmissing emptyGoodCommits g+		(removedbranches, goodcommits) <- removeBadBranches removablebranch stillmissing emptyGoodCommits g+		let remotebranches = filter isTrackingBranch removedbranches 		unless (null remotebranches) $ 			putStrLn $ unwords 				[ "Removed"@@ -492,12 +505,12 @@ 			"Reset these local branches to old versions before the missing objects were committed:" 		displayList (map show deletedbranches) 			"Deleted these local branches, which could not be recovered due to missing objects:"-		deindexedfiles <- rewriteIndex stillmissing g+		deindexedfiles <- rewriteIndex g 		displayList deindexedfiles 			"Removed these missing files from the index. You should look at what files are present in your working tree and git add them back to the index when appropriate." 		let modifiedbranches = resetbranches ++ deletedbranches 		if null resetbranches && null deletedbranches-			then successfulfinish stillmissing modifiedbranches+			then successfulfinish modifiedbranches 			else do 				unless (repoIsLocalBare g) $ do 					mcurr <- Branch.currentUnsafe g@@ -511,36 +524,36 @@ 								] 				putStrLn "Successfully recovered repository!" 				putStrLn "Please carefully check that the changes mentioned above are ok.."-				return (True, stillmissing, modifiedbranches)+				return (True, modifiedbranches) 	 	corruptedindex = do 		nukeFile (indexFile g) 		-- The corrupted index can prevent fsck from finding other 		-- problems, so re-run repair. 		fsckresult' <- findBroken False g-		result <- runRepairOf fsckresult' forced referencerepo g+		result <- runRepairOf fsckresult' removablebranch forced referencerepo g 		putStrLn "Removed the corrupted index file. You should look at what files are present in your working tree and git add them back to the index when appropriate." 		return result -	successfulfinish stillmissing modifiedbranches = do+	successfulfinish modifiedbranches = do 		mapM_ putStrLn 			[ "Successfully recovered repository!" 			, "You should run \"git fsck\" to make sure, but it looks like everything was recovered ok." 			]-		return (True, stillmissing, modifiedbranches)-	unsuccessfulfinish stillmissing = do+		return (True, modifiedbranches)+	unsuccessfulfinish = do 		if repoIsLocalBare g 			then do 				putStrLn "If you have a clone of this bare repository, you should add it as a remote of this repository, and retry." 				putStrLn "If there are no clones of this repository, you can instead retry with the --force parameter to force recovery to a possibly usable state."-				return (False, stillmissing, [])-			else needforce stillmissing-	needforce stillmissing = do+				return (False, [])+			else needforce+	needforce = do 		putStrLn "To force a recovery to a usable state, retry with the --force parameter."-		return (False, stillmissing, [])+		return (False, []) -successfulRepair :: (Bool, MissingObjects, [Branch]) -> Bool-successfulRepair = fst3+successfulRepair :: (Bool, [Branch]) -> Bool+successfulRepair = fst  safeReadFile :: FilePath -> IO String safeReadFile f = do
GitAnnex.hs view
@@ -1,6 +1,6 @@ {- git-annex main program  -- - Copyright 2010 Joey Hess <joey@kitenet.net>+ - Copyright 2010-2013 Joey Hess <joey@kitenet.net>  -  - Licensed under the GNU GPL version 3 or higher.  -}@@ -23,9 +23,7 @@ import qualified Command.FromKey import qualified Command.DropKey import qualified Command.TransferKey-#ifndef mingw32_HOST_OS import qualified Command.TransferKeys-#endif import qualified Command.ReKey import qualified Command.Reinject import qualified Command.Fix@@ -129,9 +127,7 @@ 	, Command.FromKey.def 	, Command.DropKey.def 	, Command.TransferKey.def-#ifndef mingw32_HOST_OS 	, Command.TransferKeys.def-#endif 	, Command.ReKey.def 	, Command.Fix.def 	, Command.Fsck.def
Init.hs view
@@ -21,6 +21,8 @@ import qualified Git import qualified Git.LsFiles import qualified Git.Config+import qualified Git.Construct+import qualified Git.Types as Git import qualified Annex.Branch import Logs.UUID import Annex.Version@@ -36,8 +38,13 @@ import Utility.FileMode #endif import Annex.Hook+import Git.Hook (hookFile) import Upgrade+import Annex.Content+import Logs.Location +import System.Log.Logger+ genDescription :: Maybe String -> Annex String genDescription (Just d) = return d genDescription Nothing = do@@ -92,7 +99,9 @@  - Checks repository version and handles upgrades too.  -} ensureInitialized :: Annex ()-ensureInitialized = getVersion >>= maybe needsinit checkUpgrade+ensureInitialized = do+	getVersion >>= maybe needsinit checkUpgrade+	fixBadBare   where 	needsinit = ifM Annex.Branch.hasSibling 			( initialize Nothing@@ -176,3 +185,57 @@ 	forM_ l $ \f -> 		maybe noop (`toDirect` f) =<< isAnnexLink f 	void $ liftIO clean++{- Work around for git-annex version 5.20131118 - 5.20131127, which+ - had a bug that unset core.bare when initializing a bare repository.+ - + - This resulted in objects sent to the repository being stored in + - repo/.git/annex/objects, so move them to repo/annex/objects.+ -+ - This check slows down every git-annex run somewhat (by one file stat),+ - so should be removed after a suitable period of time has passed.+ - Since the bare repository may be on an offline USB drive, best to+ - keep it for a while. However, git-annex was only buggy for a few+ - weeks, so not too long.+ -}+fixBadBare :: Annex ()+fixBadBare = whenM checkBadBare $ do+	ks <- getKeysPresent+	liftIO $ debugM "Init" $ unwords+		[ "Detected bad bare repository with"+		, show (length ks)+		, "objects; fixing"+		]+	g <- Annex.gitRepo+	gc <- Annex.getGitConfig+	d <- Git.repoPath <$> Annex.gitRepo+	void $ liftIO $ boolSystem "git"+		[ Param $ "--git-dir=" ++ d+		, Param "config"+		, Param Git.Config.coreBare+		, Param $ Git.Config.boolConfig True+		]+	g' <- liftIO $ Git.Construct.fromPath d+	s' <- liftIO $ Annex.new $ g' { Git.location = Git.Local { Git.gitdir = d, Git.worktree = Nothing } }+	Annex.changeState $ \s -> s+		{ Annex.repo = Annex.repo s'+		, Annex.gitconfig = Annex.gitconfig s'+		}+	forM_ ks $ \k -> do+		oldloc <- liftIO $ gitAnnexLocation k g gc+		thawContentDir oldloc+		moveAnnex k oldloc+		logStatus k InfoPresent+	let dotgit = d </> ".git"+	liftIO $ removeDirectoryRecursive dotgit+		`catchIO` (const $ renameDirectory dotgit (d </> "removeme"))++{- A repostory with the problem won't know it's a bare repository, but will+ - have no pre-commit hook (which is not set up in a bare repository),+ - and will not have a HEAD file in its .git directory. -}+checkBadBare :: Annex Bool+checkBadBare = allM (not <$>)+	[isBare, hasPreCommitHook, hasDotGitHEAD]+  where+	hasPreCommitHook = inRepo $ doesFileExist . hookFile preCommitHook+	hasDotGitHEAD = inRepo $ \r -> doesFileExist $ Git.localGitDir r </> "HEAD"
Logs/Transfer.hs view
@@ -18,13 +18,25 @@ import Utility.Percentage import Utility.QuickCheck -import System.Posix.Types import Data.Time.Clock import Data.Time.Clock.POSIX import Data.Time import System.Locale import Control.Concurrent +#ifndef mingw32_HOST_OS+import System.Posix.Types (ProcessID)+#else+import System.Win32.Process (ProcessId)+import System.Win32.Process.Current (getCurrentProcessId)+#endif++#ifndef mingw32_HOST_OS+type PID = ProcessID+#else+type PID = ProcessId+#endif+ {- Enough information to uniquely identify a transfer, used as the filename  - of the transfer information file. -} data Transfer = Transfer@@ -42,7 +54,7 @@  -} data TransferInfo = TransferInfo 	{ startedTime :: Maybe POSIXTime-	, transferPid :: Maybe ProcessID+	, transferPid :: Maybe PID 	, transferTid :: Maybe ThreadId 	, transferRemote :: Maybe Remote 	, bytesComplete :: Maybe Integer@@ -204,7 +216,11 @@ startTransferInfo :: Maybe FilePath -> IO TransferInfo startTransferInfo file = TransferInfo 	<$> (Just . utcTimeToPOSIXSeconds <$> getCurrentTime)+#ifndef mingw32_HOST_OS 	<*> pure Nothing -- pid not stored in file, so omitted for speed+#else+	<*> (Just <$> getCurrentProcessId)+#endif 	<*> pure Nothing -- tid ditto 	<*> pure Nothing -- not 0; transfer may be resuming 	<*> pure Nothing@@ -318,33 +334,48 @@ {- File format is a header line containing the startedTime and any  - bytesComplete value. Followed by a newline and the associatedFile.  -- - The transferPid is not included; instead it is obtained by looking- - at the process that locks the file.+ - On unix, the transferPid is not included; instead it is obtained+ - by looking at the process that locks the file.+ -+ - On windows, the transferPid is included, as a second line.  -} writeTransferInfo :: TransferInfo -> String writeTransferInfo info = unlines 	[ (maybe "" show $ startedTime info) ++ 	  (maybe "" (\b -> ' ' : show b) (bytesComplete info))+#ifdef mingw32_HOST_OS+	, maybe "" show (transferPid info)+#endif 	, fromMaybe "" $ associatedFile info -- comes last; arbitrary content 	] -readTransferInfoFile :: Maybe ProcessID -> FilePath -> IO (Maybe TransferInfo)+readTransferInfoFile :: Maybe PID -> FilePath -> IO (Maybe TransferInfo) readTransferInfoFile mpid tfile = catchDefaultIO Nothing $ do 	h <- openFile tfile ReadMode 	fileEncoding h 	hClose h `after` (readTransferInfo mpid <$> hGetContentsStrict h) -readTransferInfo :: Maybe ProcessID -> String -> Maybe TransferInfo+readTransferInfo :: Maybe PID -> String -> Maybe TransferInfo readTransferInfo mpid s = TransferInfo 	<$> time+#ifdef mingw32_HOST_OS+	<*> pure (if isJust mpid then mpid else mpid')+#else 	<*> pure mpid+#endif 	<*> pure Nothing 	<*> pure Nothing 	<*> bytes 	<*> pure (if null filename then Nothing else Just filename) 	<*> pure False   where+#ifdef mingw32_HOST_OS+	(firstline, rem) = separate (== '\n') s+	(secondline, rest) = separate (== '\n') rem+	mpid' = readish secondline+#else 	(firstline, rest) = separate (== '\n') s+#endif 	filename 		| end rest == "\n" = beginning rest 		| otherwise = rest
Remote/Rsync.hs view
@@ -23,7 +23,7 @@ #ifndef mingw32_HOST_OS import System.Posix.Process (getProcessID) #else-import System.Random (getStdRandom, random)+import System.Win32.Process.Current (getCurrentProcessId) #endif  import Common.Annex@@ -243,7 +243,7 @@ #ifndef mingw32_HOST_OS 	v <- liftIO getProcessID #else-	v <- liftIO (getStdRandom random :: IO Int)+	v <- liftIO getCurrentProcessId #endif 	t <- fromRepo gitAnnexTmpDir 	createAnnexDirectory t@@ -257,22 +257,25 @@  rsyncRetrieve :: RsyncOpts -> Key -> FilePath -> Maybe MeterUpdate -> Annex Bool rsyncRetrieve o k dest callback =-	untilTrue (rsyncUrls o k) $ \u -> rsyncRemote o callback+	showResumable $ untilTrue (rsyncUrls o k) $ \u -> rsyncRemote o callback 		-- use inplace when retrieving to support resuming 		[ Param "--inplace" 		, Param u 		, File dest 		] +showResumable :: Annex Bool -> Annex Bool+showResumable a = ifM a+	( return True+	, do+		showLongNote "rsync failed -- run git annex again to resume file transfer"+		return False+	)+ rsyncRemote :: RsyncOpts -> Maybe MeterUpdate -> [CommandParam] -> Annex Bool rsyncRemote o callback params = do 	showOutput -- make way for progress bar-	ifM (liftIO $ (maybe rsync rsyncProgress callback) ps)-		( return True-		, do-			showLongNote "rsync failed -- run git annex again to resume file transfer"-			return False-		)+	liftIO $ (maybe rsync rsyncProgress callback) ps   where 	defaultParams = [Params "--progress"] 	ps = rsyncOptions o ++ defaultParams ++ params@@ -298,7 +301,7 @@ 		else createLinkOrCopy src dest 	ps <- sendParams 	if ok-		then rsyncRemote o (Just callback) $ ps +++		then showResumable $ rsyncRemote o (Just callback) $ ps ++ 			[ Param "--recursive" 			, partialParams 			-- tmp/ to send contents of tmp dir
Remote/WebDAV.hs view
@@ -220,7 +220,10 @@ 		_ -> return unconfigured  configUrl :: Remote -> Maybe DavUrl-configUrl r = M.lookup "url" $ config r+configUrl r = fixup <$> M.lookup "url" (config r)+  where+	-- box.com DAV url changed+	fixup = replace "https://www.box.com/dav/" "https://dav.box.com/dav/"  toDavUser :: String -> DavUser toDavUser = B8.fromString
Utility/Batch.hs view
@@ -10,9 +10,6 @@ module Utility.Batch where  import Common-#ifndef mingw32_HOST_OS-import qualified Build.SysConfig-#endif  #if defined(linux_HOST_OS) || defined(__ANDROID__) import Control.Concurrent.Async@@ -46,36 +43,45 @@ maxNice :: Int maxNice = 19 -{- Converts a command to run niced. -}-toBatchCommand :: (String, [CommandParam]) -> (String, [CommandParam])-toBatchCommand (command, params) = (command', params')-  where+{- Makes a command be run by whichever of nice, ionice, and nocache+ - are available in the path. -}+type BatchCommandMaker = (String, [CommandParam]) -> (String, [CommandParam])++getBatchCommandMaker :: IO BatchCommandMaker+getBatchCommandMaker = do #ifndef mingw32_HOST_OS-	commandline = unwords $ map shellEscape $ command : toCommand params-	nicedcommand-		| Build.SysConfig.nice = "nice " ++ commandline-		| otherwise = commandline-	command' = "sh"-	params' =-		[ Param "-c"-		, Param $ "exec " ++ nicedcommand+	nicers <- filterM (inPath . fst)+		[ ("nice", [])+		, ("ionice", ["-c3"])+		, ("nocache", []) 		]+	return $ \(command, params) ->+		case nicers of+			[] -> (command, params)+			(first:rest) -> (fst first, map Param (snd first ++ concatMap (\p -> fst p : snd p) rest ++ [command]) ++ params) #else-	command' = command-	params' = params+	return id #endif +toBatchCommand :: (String, [CommandParam]) -> IO (String, [CommandParam])+toBatchCommand v = do+	batchmaker <- getBatchCommandMaker+	return $ batchmaker v+ {- Runs a command in a way that's suitable for batch jobs that can be  - interrupted.  -- - The command is run niced. If the calling thread receives an async- - exception, it sends the command a SIGTERM, and after the command- - finishes shuttting down, it re-raises the async exception. -}+ - If the calling thread receives an async exception, it sends the+ - command a SIGTERM, and after the command finishes shuttting down,+ - it re-raises the async exception. -} batchCommand :: String -> [CommandParam] -> IO Bool batchCommand command params = batchCommandEnv command params Nothing  batchCommandEnv :: String -> [CommandParam] -> Maybe [(String, String)] -> IO Bool batchCommandEnv command params environ = do+	batchmaker <- getBatchCommandMaker+	let (command', params') = batchmaker (command, params)+	let p = proc command' $ toCommand params' 	(_, _, _, pid) <- createProcess $ p { env = environ } 	r <- E.try (waitForProcess pid) :: IO (Either E.SomeException ExitCode) 	case r of@@ -85,7 +91,3 @@ 			terminateProcess pid 			void $ waitForProcess pid 			E.throwIO asyncexception-  where-  	(command', params') = toBatchCommand (command, params)-  	p = proc command' $ toCommand params'-
Utility/DirWatcher.hs view
@@ -16,19 +16,19 @@ import Utility.DirWatcher.Types  #if WITH_INOTIFY-import qualified Utility.INotify as INotify+import qualified Utility.DirWatcher.INotify as INotify import qualified System.INotify as INotify #endif #if WITH_KQUEUE-import qualified Utility.Kqueue as Kqueue+import qualified Utility.DirWatcher.Kqueue as Kqueue import Control.Concurrent #endif #if WITH_FSEVENTS-import qualified Utility.FSEvents as FSEvents+import qualified Utility.DirWatcher.FSEvents as FSEvents import qualified System.OSX.FSEvents as FSEvents #endif #if WITH_WIN32NOTIFY-import qualified Utility.Win32Notify as Win32Notify+import qualified Utility.DirWatcher.Win32Notify as Win32Notify import qualified System.Win32.Notify as Win32Notify #endif 
+ Utility/DirWatcher/FSEvents.hs view
@@ -0,0 +1,92 @@+{- FSEvents interface+ -+ - Copyright 2012 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++module Utility.DirWatcher.FSEvents where++import Common hiding (isDirectory)+import Utility.DirWatcher.Types++import System.OSX.FSEvents+import qualified System.Posix.Files as Files+import Data.Bits ((.&.))++watchDir :: FilePath -> (FilePath -> Bool) -> WatchHooks -> IO EventStream+watchDir dir ignored hooks = do+	unlessM fileLevelEventsSupported $+		error "Need at least OSX 10.7.0 for file-level FSEvents"+	scan dir+	eventStreamCreate [dir] 1.0 True True True handle+  where+	handle evt+		| ignoredPath ignored (eventPath evt) = noop+		| otherwise = do+			{- More than one flag may be set, if events occurred+			 - close together. +			 - +			 - Order is important..+			 - If a file is added and then deleted, we'll see it's+			 - not present, and addHook won't run.+			 - OTOH, if a file is deleted and then re-added,+			 - the delHook will run first, followed by the addHook.+			 -}++			when (hasflag eventFlagItemRemoved) $+				if hasflag eventFlagItemIsDir+					then runhook delDirHook Nothing+					else runhook delHook Nothing+			when (hasflag eventFlagItemCreated) $+				maybe noop handleadd =<< getstatus (eventPath evt)+			{- When a file or dir is renamed, a rename event is+			 - received for both its old and its new name. -}+			when (hasflag eventFlagItemRenamed) $+				if hasflag eventFlagItemIsDir+					then ifM (doesDirectoryExist $ eventPath evt)+						( scan $ eventPath evt+						, runhook delDirHook Nothing+						)+					else maybe (runhook delHook Nothing) handleadd+						=<< getstatus (eventPath evt)+			{- Add hooks are run when a file is modified for +			 - compatability with INotify, which calls the add+			 - hook when a file is closed, and so tends to call+			 - both add and modify for file modifications. -}+			when (hasflag eventFlagItemModified && not (hasflag eventFlagItemIsDir)) $ do+				ms <- getstatus $ eventPath evt+				maybe noop handleadd ms+				runhook modifyHook ms+	  where+		hasflag f = eventFlags evt .&. f /= 0+		runhook h s = maybe noop (\a -> a (eventPath evt) s) (h hooks)+		handleadd s+			| Files.isSymbolicLink s = runhook addSymlinkHook $ Just s+			| Files.isRegularFile s = runhook addHook $ Just s+			| otherwise = noop+	+	scan d = unless (ignoredPath ignored d) $+		mapM_ go =<< dirContentsRecursive d+	  where		+		go f+			| ignoredPath ignored f = noop+			| otherwise = do+				ms <- getstatus f+				case ms of+					Nothing -> noop+					Just s+						| Files.isSymbolicLink s ->+							runhook addSymlinkHook ms+						| Files.isRegularFile s ->+							runhook addHook ms+						| otherwise ->+							noop+		  where+			runhook h s = maybe noop (\a -> a f s) (h hooks)+		+	getstatus = catchMaybeIO . getSymbolicLinkStatus++{- Check each component of the path to see if it's ignored. -}+ignoredPath :: (FilePath -> Bool) -> FilePath -> Bool+ignoredPath ignored = any ignored . map dropTrailingPathSeparator . splitPath
+ Utility/DirWatcher/INotify.hs view
@@ -0,0 +1,185 @@+{- higher-level inotify interface+ -+ - Copyright 2012 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++module Utility.DirWatcher.INotify where++import Common hiding (isDirectory)+import Utility.ThreadLock+import Utility.DirWatcher.Types++import System.INotify+import qualified System.Posix.Files as Files+import System.IO.Error+import Control.Exception (throw)++{- Watches for changes to files in a directory, and all its subdirectories+ - that are not ignored, using inotify. This function returns after+ - its initial scan is complete, leaving a thread running. Callbacks are+ - made for different events.+ -+ - Inotify is weak at recursive directory watching; the whole directory+ - tree must be scanned and watches set explicitly for each subdirectory.+ -+ - To notice newly created subdirectories, inotify is used, and+ - watches are registered for those directories. There is a race there;+ - things can be added to a directory before the watch gets registered.+ -+ - To close the inotify race, each time a new directory is found, it also + - recursively scans it, assuming all files in it were just added,+ - and registering each subdirectory.+ -+ - Note: Due to the race amelioration, multiple add events may occur+ - for the same file.+ - + - Note: Moving a file will cause events deleting it from its old location+ - and adding it to the new location. + - + - Note: It's assumed that when a file that was open for write is closed, + - it's finished being written to, and can be added.+ -+ - Note: inotify has a limit to the number of watches allowed,+ - /proc/sys/fs/inotify/max_user_watches (default 8192).+ - So this will fail if there are too many subdirectories. The+ - errHook is called when this happens.+ -}+watchDir :: INotify -> FilePath -> (FilePath -> Bool) -> WatchHooks -> IO ()+watchDir i dir ignored hooks+	| ignored dir = noop+	| otherwise = do+		-- Use a lock to make sure events generated during initial+		-- scan come before real inotify events.+		lock <- newLock+		let handler event = withLock lock (void $ go event)+		flip catchNonAsync failedwatch $ do+			void (addWatch i watchevents dir handler)+				`catchIO` failedaddwatch+			withLock lock $+				mapM_ scan =<< filter (not . dirCruft) <$>+					getDirectoryContents dir+  where+	recurse d = watchDir i d ignored hooks++	-- Select only inotify events required by the enabled+	-- hooks, but always include Create so new directories can+	-- be scanned.+	watchevents = Create : addevents ++ delevents ++ modifyevents+	addevents+		| hashook addHook || hashook addSymlinkHook = [MoveIn, CloseWrite]+		| otherwise = []+	delevents+		| hashook delHook || hashook delDirHook = [MoveOut, Delete]+		| otherwise = []+	modifyevents+		| hashook modifyHook = [Modify]+		| otherwise = []++	scan f = unless (ignored f) $ do+		ms <- getstatus f+		case ms of+			Nothing -> return ()+			Just s+				| Files.isDirectory s ->+					recurse $ indir f+				| Files.isSymbolicLink s ->+					runhook addSymlinkHook f ms+				| Files.isRegularFile s ->+					runhook addHook f ms+				| otherwise ->+					noop++	go (Created { isDirectory = isd, filePath = f })+		| isd = recurse $ indir f+		| otherwise = do+			ms <- getstatus f+			case ms of+				Just s+					| Files.isSymbolicLink s -> +						when (hashook addSymlinkHook) $+							runhook addSymlinkHook f ms+					| Files.isRegularFile s ->+						when (hashook addHook) $+							runhook addHook f ms+				_ -> noop+	-- Closing a file is assumed to mean it's done being written,+	-- so a new add event is sent.+	go (Closed { isDirectory = False, maybeFilePath = Just f }) =+			checkfiletype Files.isRegularFile addHook f+	-- When a file or directory is moved in, scan it to add new+	-- stuff.+	go (MovedIn { filePath = f }) = scan f+	go (MovedOut { isDirectory = isd, filePath = f })+		| isd = runhook delDirHook f Nothing+		| otherwise = runhook delHook f Nothing+	-- Verify that the deleted item really doesn't exist,+	-- since there can be spurious deletion events for items+	-- in a directory that has been moved out, but is still+	-- being watched.+	go (Deleted { isDirectory = isd, filePath = f })+		| isd = guarded $ runhook delDirHook f Nothing+		| otherwise = guarded $ runhook delHook f Nothing+	  where+		guarded = unlessM (filetype (const True) f)+	go (Modified { isDirectory = isd, maybeFilePath = Just f })+		| isd = noop+		| otherwise = runhook modifyHook f Nothing+	go _ = noop++	hashook h = isJust $ h hooks++	runhook h f s+		| ignored f = noop+		| otherwise = maybe noop (\a -> a (indir f) s) (h hooks)++	indir f = dir </> f++	getstatus f = catchMaybeIO $ getSymbolicLinkStatus $ indir f+	checkfiletype check h f = do+		ms <- getstatus f+		case ms of+			Just s+				| check s -> runhook h f ms+			_ -> noop+	filetype t f = catchBoolIO $ t <$> getSymbolicLinkStatus (indir f)++	failedaddwatch e+		-- Inotify fails when there are too many watches with a+		-- disk full error.+		| isFullError e =+			case errHook hooks of+				Nothing -> error $ "failed to add inotify watch on directory " ++ dir ++ " (" ++ show e ++ ")"+				Just hook -> tooManyWatches hook dir+		-- The directory could have been deleted.+		| isDoesNotExistError e = return ()+		| otherwise = throw e++	failedwatch e = hPutStrLn stderr $ "failed to add watch on directory " ++ dir ++ " (" ++ show e ++ ")"++tooManyWatches :: (String -> Maybe FileStatus -> IO ()) -> FilePath -> IO ()+tooManyWatches hook dir = do+	sysctlval <- querySysctl [Param maxwatches] :: IO (Maybe Integer)+	hook (unlines $ basewarning : maybe withoutsysctl withsysctl sysctlval) Nothing+  where+	maxwatches = "fs.inotify.max_user_watches"+	basewarning = "Too many directories to watch! (Not watching " ++ dir ++")"+	withoutsysctl = ["Increase the value in /proc/sys/fs/inotify/max_user_watches"]+	withsysctl n = let new = n * 10 in+		[ "Increase the limit permanently by running:"+		, "  echo " ++ maxwatches ++ "=" ++ show new +++		  " | sudo tee -a /etc/sysctl.conf; sudo sysctl -p"+		, "Or temporarily by running:"+		, "  sudo sysctl -w " ++ maxwatches ++ "=" ++ show new+		]++querySysctl :: Read a => [CommandParam] -> IO (Maybe a)+querySysctl ps = getM go ["sysctl", "/sbin/sysctl", "/usr/sbin/sysctl"]+  where+	go p = do+		v <- catchMaybeIO $ readProcess p (toCommand ps)+		case v of+			Nothing -> return Nothing+			Just s -> return $ parsesysctl s+	parsesysctl s = readish =<< lastMaybe (words s)
+ Utility/DirWatcher/Kqueue.hs view
@@ -0,0 +1,267 @@+{- BSD kqueue file modification notification interface+ -+ - Copyright 2012 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++{-# LANGUAGE ForeignFunctionInterface #-}++module Utility.DirWatcher.Kqueue (+	Kqueue,+	initKqueue,+	stopKqueue,+	waitChange,+	Change(..),+	changedFile,+	runHooks,+) where++import Common+import Utility.DirWatcher.Types++import System.Posix.Types+import Foreign.C.Types+import Foreign.C.Error+import Foreign.Ptr+import Foreign.Marshal+import qualified Data.Map as M+import qualified Data.Set as S+import qualified System.Posix.Files as Files+import Control.Concurrent++data Change+	= Deleted FilePath+	| DeletedDir FilePath+	| Added FilePath+	deriving (Show)++isAdd :: Change -> Bool+isAdd (Added _) = True+isAdd (Deleted _) = False+isAdd (DeletedDir _) = False++changedFile :: Change -> FilePath+changedFile (Added f) = f+changedFile (Deleted f) = f+changedFile (DeletedDir f) = f++data Kqueue = Kqueue +	{ kqueueFd :: Fd+	, kqueueTop :: FilePath+	, kqueueMap :: DirMap+	, _kqueuePruner :: Pruner+	}++type Pruner = FilePath -> Bool++type DirMap = M.Map Fd DirInfo++{- Enough information to uniquely identify a file in a directory,+ - but not too much. -}+data DirEnt = DirEnt+	{ dirEnt :: FilePath -- relative to the parent directory+	, _dirInode :: FileID -- included to notice file replacements+	, isSubDir :: Bool+	}+	deriving (Eq, Ord, Show)++{- A directory, and its last known contents. -}+data DirInfo = DirInfo+	{ dirName :: FilePath+	, dirCache :: S.Set DirEnt+	}+	deriving (Show)++getDirInfo :: FilePath -> IO DirInfo+getDirInfo dir = do+	l <- filter (not . dirCruft) <$> getDirectoryContents dir+	contents <- S.fromList . catMaybes <$> mapM getDirEnt l+	return $ DirInfo dir contents+  where+	getDirEnt f = catchMaybeIO $ do+		s <- getSymbolicLinkStatus (dir </> f)+		return $ DirEnt f (fileID s) (isDirectory s)++{- Difference between the dirCaches of two DirInfos. -}+(//) :: DirInfo -> DirInfo -> [Change]+oldc // newc = deleted ++ added+  where+	deleted = calc gendel oldc newc+	added   = calc genadd newc oldc+	gendel x = (if isSubDir x then DeletedDir else Deleted) $+		dirName oldc </> dirEnt x+	genadd x = Added $ dirName newc </> dirEnt x+	calc a x y = map a $ S.toList $+		S.difference (dirCache x) (dirCache y)++{- Builds a map of directories in a tree, possibly pruning some.+ - Opens each directory in the tree, and records its current contents. -}+scanRecursive :: FilePath -> Pruner -> IO DirMap+scanRecursive topdir prune = M.fromList <$> walk [] [topdir]+  where+	walk c [] = return c+	walk c (dir:rest)+		| prune dir = walk c rest+		| otherwise = do+			minfo <- catchMaybeIO $ getDirInfo dir+			case minfo of+				Nothing -> walk c rest+				Just info -> do+					mfd <- catchMaybeIO $+						openFd dir ReadOnly Nothing defaultFileFlags+					case mfd of+						Nothing -> walk c rest+						Just fd -> do+							let subdirs = map (dir </>) . map dirEnt $+								S.toList $ dirCache info+							walk ((fd, info):c) (subdirs ++ rest)++{- Adds a list of subdirectories (and all their children), unless pruned to a+ - directory map. Adding a subdirectory that's already in the map will+ - cause its contents to be refreshed. -}+addSubDirs :: DirMap -> Pruner -> [FilePath] -> IO DirMap+addSubDirs dirmap prune dirs = do+	newmap <- foldr M.union M.empty <$>+		mapM (\d -> scanRecursive d prune) dirs+	return $ M.union newmap dirmap -- prefer newmap++{- Removes a subdirectory (and all its children) from a directory map. -}+removeSubDir :: DirMap -> FilePath -> IO DirMap+removeSubDir dirmap dir = do+	mapM_ closeFd $ M.keys toremove+	return rest+  where+	(toremove, rest) = M.partition (dirContains dir . dirName) dirmap++findDirContents :: DirMap -> FilePath -> [FilePath]+findDirContents dirmap dir = concatMap absolutecontents $ search+  where+	absolutecontents i = map (dirName i </>)+		(map dirEnt $ S.toList $ dirCache i)+	search = map snd $ M.toList $+		M.filter (\i -> dirName i == dir) dirmap++foreign import ccall safe "libkqueue.h init_kqueue" c_init_kqueue+	:: IO Fd+foreign import ccall safe "libkqueue.h addfds_kqueue" c_addfds_kqueue+	:: Fd -> CInt -> Ptr Fd -> IO ()+foreign import ccall safe "libkqueue.h waitchange_kqueue" c_waitchange_kqueue+	:: Fd -> IO Fd++{- Initializes a Kqueue to watch a directory, and all its subdirectories. -}+initKqueue :: FilePath -> Pruner -> IO Kqueue+initKqueue dir pruned = do+	dirmap <- scanRecursive dir pruned+	h <- c_init_kqueue+	let kq = Kqueue h dir dirmap pruned+	updateKqueue kq+	return kq++{- Updates a Kqueue, adding watches for its map. -}+updateKqueue :: Kqueue -> IO ()+updateKqueue (Kqueue h _ dirmap _) =+	withArrayLen (M.keys dirmap) $ \fdcnt c_fds -> do+		c_addfds_kqueue h (fromIntegral fdcnt) c_fds++{- Stops a Kqueue. Note: Does not directly close the Fds in the dirmap,+ - so it can be reused.  -}+stopKqueue :: Kqueue -> IO ()+stopKqueue = closeFd . kqueueFd++{- Waits for a change on a Kqueue.+ - May update the Kqueue.+ -}+waitChange :: Kqueue -> IO (Kqueue, [Change])+waitChange kq@(Kqueue h _ dirmap _) = do+	changedfd <- c_waitchange_kqueue h+	if changedfd == -1+		then ifM ((==) eINTR <$> getErrno)+			(yield >> waitChange kq, nochange)+		else case M.lookup changedfd dirmap of+			Nothing -> nochange+			Just info -> handleChange kq changedfd info+  where+	nochange = return (kq, [])++{- The kqueue interface does not tell what type of change took place in+ - the directory; it could be an added file, a deleted file, a renamed+ - file, a new subdirectory, or a deleted subdirectory, or a moved+ - subdirectory. + -+ - So to determine this, the contents of the directory are compared+ - with its last cached contents. The Kqueue is updated to watch new+ - directories as necessary.+ -}+handleChange :: Kqueue -> Fd -> DirInfo -> IO (Kqueue, [Change])+handleChange kq@(Kqueue _ _ dirmap pruner) fd olddirinfo =+	go =<< catchMaybeIO (getDirInfo $ dirName olddirinfo)+  where+	go (Just newdirinfo) = do+		let changes = filter (not . pruner . changedFile) $+			 olddirinfo // newdirinfo+		let (added, deleted) = partition isAdd changes++		-- Scan newly added directories to add to the map.+		-- (Newly added files will fail getDirInfo.)+		newdirinfos <- catMaybes <$>+			mapM (catchMaybeIO . getDirInfo . changedFile) added+		newmap <- addSubDirs dirmap pruner $ map dirName newdirinfos++		-- Remove deleted directories from the map.+		newmap' <- foldM removeSubDir newmap (map changedFile deleted)++		-- Update the cached dirinfo just looked up.+		let newmap'' = M.insertWith' const fd newdirinfo newmap'++		-- When new directories were added, need to update+		-- the kqueue to watch them.+		let kq' = kq { kqueueMap = newmap'' }+		unless (null newdirinfos) $+			updateKqueue kq'++		return (kq', changes)+	go Nothing = do+		-- The directory has been moved or deleted, so+		-- remove it from our map.+		newmap <- removeSubDir dirmap (dirName olddirinfo)+		return (kq { kqueueMap = newmap }, [])++{- Processes changes on the Kqueue, calling the hooks as appropriate.+ - Never returns. -}+runHooks :: Kqueue -> WatchHooks -> IO ()+runHooks kq hooks = do+	-- First, synthetic add events for the whole directory tree contents,+	-- to catch any files created beforehand.+	recursiveadd (kqueueMap kq) (Added $ kqueueTop kq)+	loop kq+  where+	loop q = do+		(q', changes) <- waitChange q+		forM_ changes $ dispatch (kqueueMap q')+		loop q'++	dispatch _ change@(Deleted _) = +		callhook delHook Nothing change+	dispatch _ change@(DeletedDir _) =+		callhook delDirHook Nothing change+	dispatch dirmap change@(Added _) =+		withstatus change $ dispatchadd dirmap+		+	dispatchadd dirmap change s+		| Files.isSymbolicLink s = callhook addSymlinkHook (Just s) change+		| Files.isDirectory s = recursiveadd dirmap change+		| Files.isRegularFile s = callhook addHook (Just s) change+		| otherwise = noop++	recursiveadd dirmap change = do+		let contents = findDirContents dirmap $ changedFile change+		forM_ contents $ \f ->+			withstatus (Added f) $ dispatchadd dirmap++	callhook h s change = case h hooks of+		Nothing -> noop+		Just a -> a (changedFile change) s++	withstatus change a = maybe noop (a change) =<<+		(catchMaybeIO (getSymbolicLinkStatus (changedFile change)))
+ Utility/DirWatcher/Win32Notify.hs view
@@ -0,0 +1,65 @@+{- Win32-notify interface+ -+ - Copyright 2013 Joey Hess <joey@kitenet.net>+ -+ - Licensed under the GNU GPL version 3 or higher.+ -}++module Utility.DirWatcher.Win32Notify where++import Common hiding (isDirectory)+import Utility.DirWatcher.Types++import System.Win32.Notify+import qualified System.PosixCompat.Files as Files++watchDir :: FilePath -> (FilePath -> Bool) -> WatchHooks -> IO WatchManager+watchDir dir ignored hooks = do+	scan dir+	wm <- initWatchManager+	void $ watchDirectory wm dir True [Create, Delete, Modify, Move] handle+	return wm+  where+	handle evt+		| ignoredPath ignored (filePath evt) = noop+		| otherwise = case evt of+			(Deleted _ _)+				| isDirectory evt -> runhook delDirHook Nothing+				| otherwise -> runhook delHook Nothing+			(Created _ _)+				| isDirectory evt -> noop+				| otherwise -> runhook addHook Nothing+			(Modified _ _)+				| isDirectory evt -> noop+				{- Add hooks are run when a file is modified for +				 - compatability with INotify, which calls the add+				 - hook when a file is closed, and so tends to call+				 - both add and modify for file modifications. -}+				| otherwise -> do+					runhook addHook Nothing+					runhook modifyHook Nothing+	  where+		runhook h s = maybe noop (\a -> a (filePath evt) s) (h hooks)++	scan d = unless (ignoredPath ignored d) $+		mapM_ go =<< dirContentsRecursive d+	  where		+		go f+			| ignoredPath ignored f = noop+			| otherwise = do+				ms <- getstatus f+				case ms of+					Nothing -> noop+					Just s+						| Files.isRegularFile s ->+							runhook addHook ms+						| otherwise ->+							noop+		  where+			runhook h s = maybe noop (\a -> a f s) (h hooks)+		+	getstatus = catchMaybeIO . getFileStatus++{- Check each component of the path to see if it's ignored. -}+ignoredPath :: (FilePath -> Bool) -> FilePath -> Bool+ignoredPath ignored = any ignored . map dropTrailingPathSeparator . splitPath
Utility/DiskFree.hs view
@@ -31,8 +31,22 @@ 	safeErrno (Errno v) = v == 0  #else+#ifdef mingw32_HOST_OS +import Common++import System.Win32.File+ getDiskFree :: FilePath -> IO (Maybe Integer)+getDiskFree path = catchMaybeIO $ do+	(sectors, bytes, nfree, _ntotal) <- getDiskFreeSpace (Just path)+	return $ toInteger sectors * toInteger bytes * toInteger nfree+#else++#warning Building without disk free space checking support++getDiskFree :: FilePath -> IO (Maybe Integer) getDiskFree _ = return Nothing +#endif #endif
− Utility/FSEvents.hs
@@ -1,92 +0,0 @@-{- FSEvents interface- -- - Copyright 2012 Joey Hess <joey@kitenet.net>- -- - Licensed under the GNU GPL version 3 or higher.- -}--module Utility.FSEvents where--import Common hiding (isDirectory)-import Utility.DirWatcher.Types--import System.OSX.FSEvents-import qualified System.Posix.Files as Files-import Data.Bits ((.&.))--watchDir :: FilePath -> (FilePath -> Bool) -> WatchHooks -> IO EventStream-watchDir dir ignored hooks = do-	unlessM fileLevelEventsSupported $-		error "Need at least OSX 10.7.0 for file-level FSEvents"-	scan dir-	eventStreamCreate [dir] 1.0 True True True handle-  where-	handle evt-		| ignoredPath ignored (eventPath evt) = noop-		| otherwise = do-			{- More than one flag may be set, if events occurred-			 - close together. -			 - -			 - Order is important..-			 - If a file is added and then deleted, we'll see it's-			 - not present, and addHook won't run.-			 - OTOH, if a file is deleted and then re-added,-			 - the delHook will run first, followed by the addHook.-			 -}--			when (hasflag eventFlagItemRemoved) $-				if hasflag eventFlagItemIsDir-					then runhook delDirHook Nothing-					else runhook delHook Nothing-			when (hasflag eventFlagItemCreated) $-				maybe noop handleadd =<< getstatus (eventPath evt)-			{- When a file or dir is renamed, a rename event is-			 - received for both its old and its new name. -}-			when (hasflag eventFlagItemRenamed) $-				if hasflag eventFlagItemIsDir-					then ifM (doesDirectoryExist $ eventPath evt)-						( scan $ eventPath evt-						, runhook delDirHook Nothing-						)-					else maybe (runhook delHook Nothing) handleadd-						=<< getstatus (eventPath evt)-			{- Add hooks are run when a file is modified for -			 - compatability with INotify, which calls the add-			 - hook when a file is closed, and so tends to call-			 - both add and modify for file modifications. -}-			when (hasflag eventFlagItemModified && not (hasflag eventFlagItemIsDir)) $ do-				ms <- getstatus $ eventPath evt-				maybe noop handleadd ms-				runhook modifyHook ms-	  where-		hasflag f = eventFlags evt .&. f /= 0-		runhook h s = maybe noop (\a -> a (eventPath evt) s) (h hooks)-		handleadd s-			| Files.isSymbolicLink s = runhook addSymlinkHook $ Just s-			| Files.isRegularFile s = runhook addHook $ Just s-			| otherwise = noop-	-	scan d = unless (ignoredPath ignored d) $-		mapM_ go =<< dirContentsRecursive d-	  where		-		go f-			| ignoredPath ignored f = noop-			| otherwise = do-				ms <- getstatus f-				case ms of-					Nothing -> noop-					Just s-						| Files.isSymbolicLink s ->-							runhook addSymlinkHook ms-						| Files.isRegularFile s ->-							runhook addHook ms-						| otherwise ->-							noop-		  where-			runhook h s = maybe noop (\a -> a f s) (h hooks)-		-	getstatus = catchMaybeIO . getSymbolicLinkStatus--{- Check each component of the path to see if it's ignored. -}-ignoredPath :: (FilePath -> Bool) -> FilePath -> Bool-ignoredPath ignored = any ignored . map dropTrailingPathSeparator . splitPath
− Utility/INotify.hs
@@ -1,185 +0,0 @@-{- higher-level inotify interface- -- - Copyright 2012 Joey Hess <joey@kitenet.net>- -- - Licensed under the GNU GPL version 3 or higher.- -}--module Utility.INotify where--import Common hiding (isDirectory)-import Utility.ThreadLock-import Utility.DirWatcher.Types--import System.INotify-import qualified System.Posix.Files as Files-import System.IO.Error-import Control.Exception (throw)--{- Watches for changes to files in a directory, and all its subdirectories- - that are not ignored, using inotify. This function returns after- - its initial scan is complete, leaving a thread running. Callbacks are- - made for different events.- -- - Inotify is weak at recursive directory watching; the whole directory- - tree must be scanned and watches set explicitly for each subdirectory.- -- - To notice newly created subdirectories, inotify is used, and- - watches are registered for those directories. There is a race there;- - things can be added to a directory before the watch gets registered.- -- - To close the inotify race, each time a new directory is found, it also - - recursively scans it, assuming all files in it were just added,- - and registering each subdirectory.- -- - Note: Due to the race amelioration, multiple add events may occur- - for the same file.- - - - Note: Moving a file will cause events deleting it from its old location- - and adding it to the new location. - - - - Note: It's assumed that when a file that was open for write is closed, - - it's finished being written to, and can be added.- -- - Note: inotify has a limit to the number of watches allowed,- - /proc/sys/fs/inotify/max_user_watches (default 8192).- - So this will fail if there are too many subdirectories. The- - errHook is called when this happens.- -}-watchDir :: INotify -> FilePath -> (FilePath -> Bool) -> WatchHooks -> IO ()-watchDir i dir ignored hooks-	| ignored dir = noop-	| otherwise = do-		-- Use a lock to make sure events generated during initial-		-- scan come before real inotify events.-		lock <- newLock-		let handler event = withLock lock (void $ go event)-		flip catchNonAsync failedwatch $ do-			void (addWatch i watchevents dir handler)-				`catchIO` failedaddwatch-			withLock lock $-				mapM_ scan =<< filter (not . dirCruft) <$>-					getDirectoryContents dir-  where-	recurse d = watchDir i d ignored hooks--	-- Select only inotify events required by the enabled-	-- hooks, but always include Create so new directories can-	-- be scanned.-	watchevents = Create : addevents ++ delevents ++ modifyevents-	addevents-		| hashook addHook || hashook addSymlinkHook = [MoveIn, CloseWrite]-		| otherwise = []-	delevents-		| hashook delHook || hashook delDirHook = [MoveOut, Delete]-		| otherwise = []-	modifyevents-		| hashook modifyHook = [Modify]-		| otherwise = []--	scan f = unless (ignored f) $ do-		ms <- getstatus f-		case ms of-			Nothing -> return ()-			Just s-				| Files.isDirectory s ->-					recurse $ indir f-				| Files.isSymbolicLink s ->-					runhook addSymlinkHook f ms-				| Files.isRegularFile s ->-					runhook addHook f ms-				| otherwise ->-					noop--	go (Created { isDirectory = isd, filePath = f })-		| isd = recurse $ indir f-		| otherwise = do-			ms <- getstatus f-			case ms of-				Just s-					| Files.isSymbolicLink s -> -						when (hashook addSymlinkHook) $-							runhook addSymlinkHook f ms-					| Files.isRegularFile s ->-						when (hashook addHook) $-							runhook addHook f ms-				_ -> noop-	-- Closing a file is assumed to mean it's done being written,-	-- so a new add event is sent.-	go (Closed { isDirectory = False, maybeFilePath = Just f }) =-			checkfiletype Files.isRegularFile addHook f-	-- When a file or directory is moved in, scan it to add new-	-- stuff.-	go (MovedIn { filePath = f }) = scan f-	go (MovedOut { isDirectory = isd, filePath = f })-		| isd = runhook delDirHook f Nothing-		| otherwise = runhook delHook f Nothing-	-- Verify that the deleted item really doesn't exist,-	-- since there can be spurious deletion events for items-	-- in a directory that has been moved out, but is still-	-- being watched.-	go (Deleted { isDirectory = isd, filePath = f })-		| isd = guarded $ runhook delDirHook f Nothing-		| otherwise = guarded $ runhook delHook f Nothing-	  where-		guarded = unlessM (filetype (const True) f)-	go (Modified { isDirectory = isd, maybeFilePath = Just f })-		| isd = noop-		| otherwise = runhook modifyHook f Nothing-	go _ = noop--	hashook h = isJust $ h hooks--	runhook h f s-		| ignored f = noop-		| otherwise = maybe noop (\a -> a (indir f) s) (h hooks)--	indir f = dir </> f--	getstatus f = catchMaybeIO $ getSymbolicLinkStatus $ indir f-	checkfiletype check h f = do-		ms <- getstatus f-		case ms of-			Just s-				| check s -> runhook h f ms-			_ -> noop-	filetype t f = catchBoolIO $ t <$> getSymbolicLinkStatus (indir f)--	failedaddwatch e-		-- Inotify fails when there are too many watches with a-		-- disk full error.-		| isFullError e =-			case errHook hooks of-				Nothing -> error $ "failed to add inotify watch on directory " ++ dir ++ " (" ++ show e ++ ")"-				Just hook -> tooManyWatches hook dir-		-- The directory could have been deleted.-		| isDoesNotExistError e = return ()-		| otherwise = throw e--	failedwatch e = hPutStrLn stderr $ "failed to add watch on directory " ++ dir ++ " (" ++ show e ++ ")"--tooManyWatches :: (String -> Maybe FileStatus -> IO ()) -> FilePath -> IO ()-tooManyWatches hook dir = do-	sysctlval <- querySysctl [Param maxwatches] :: IO (Maybe Integer)-	hook (unlines $ basewarning : maybe withoutsysctl withsysctl sysctlval) Nothing-  where-	maxwatches = "fs.inotify.max_user_watches"-	basewarning = "Too many directories to watch! (Not watching " ++ dir ++")"-	withoutsysctl = ["Increase the value in /proc/sys/fs/inotify/max_user_watches"]-	withsysctl n = let new = n * 10 in-		[ "Increase the limit permanently by running:"-		, "  echo " ++ maxwatches ++ "=" ++ show new ++-		  " | sudo tee -a /etc/sysctl.conf; sudo sysctl -p"-		, "Or temporarily by running:"-		, "  sudo sysctl -w " ++ maxwatches ++ "=" ++ show new-		]--querySysctl :: Read a => [CommandParam] -> IO (Maybe a)-querySysctl ps = getM go ["sysctl", "/sbin/sysctl", "/usr/sbin/sysctl"]-  where-	go p = do-		v <- catchMaybeIO $ readProcess p (toCommand ps)-		case v of-			Nothing -> return Nothing-			Just s -> return $ parsesysctl s-	parsesysctl s = readish =<< lastMaybe (words s)
− Utility/Kqueue.hs
@@ -1,267 +0,0 @@-{- BSD kqueue file modification notification interface- -- - Copyright 2012 Joey Hess <joey@kitenet.net>- -- - Licensed under the GNU GPL version 3 or higher.- -}--{-# LANGUAGE ForeignFunctionInterface #-}--module Utility.Kqueue (-	Kqueue,-	initKqueue,-	stopKqueue,-	waitChange,-	Change(..),-	changedFile,-	runHooks,-) where--import Common-import Utility.DirWatcher.Types--import System.Posix.Types-import Foreign.C.Types-import Foreign.C.Error-import Foreign.Ptr-import Foreign.Marshal-import qualified Data.Map as M-import qualified Data.Set as S-import qualified System.Posix.Files as Files-import Control.Concurrent--data Change-	= Deleted FilePath-	| DeletedDir FilePath-	| Added FilePath-	deriving (Show)--isAdd :: Change -> Bool-isAdd (Added _) = True-isAdd (Deleted _) = False-isAdd (DeletedDir _) = False--changedFile :: Change -> FilePath-changedFile (Added f) = f-changedFile (Deleted f) = f-changedFile (DeletedDir f) = f--data Kqueue = Kqueue -	{ kqueueFd :: Fd-	, kqueueTop :: FilePath-	, kqueueMap :: DirMap-	, _kqueuePruner :: Pruner-	}--type Pruner = FilePath -> Bool--type DirMap = M.Map Fd DirInfo--{- Enough information to uniquely identify a file in a directory,- - but not too much. -}-data DirEnt = DirEnt-	{ dirEnt :: FilePath -- relative to the parent directory-	, _dirInode :: FileID -- included to notice file replacements-	, isSubDir :: Bool-	}-	deriving (Eq, Ord, Show)--{- A directory, and its last known contents. -}-data DirInfo = DirInfo-	{ dirName :: FilePath-	, dirCache :: S.Set DirEnt-	}-	deriving (Show)--getDirInfo :: FilePath -> IO DirInfo-getDirInfo dir = do-	l <- filter (not . dirCruft) <$> getDirectoryContents dir-	contents <- S.fromList . catMaybes <$> mapM getDirEnt l-	return $ DirInfo dir contents-  where-	getDirEnt f = catchMaybeIO $ do-		s <- getSymbolicLinkStatus (dir </> f)-		return $ DirEnt f (fileID s) (isDirectory s)--{- Difference between the dirCaches of two DirInfos. -}-(//) :: DirInfo -> DirInfo -> [Change]-oldc // newc = deleted ++ added-  where-	deleted = calc gendel oldc newc-	added   = calc genadd newc oldc-	gendel x = (if isSubDir x then DeletedDir else Deleted) $-		dirName oldc </> dirEnt x-	genadd x = Added $ dirName newc </> dirEnt x-	calc a x y = map a $ S.toList $-		S.difference (dirCache x) (dirCache y)--{- Builds a map of directories in a tree, possibly pruning some.- - Opens each directory in the tree, and records its current contents. -}-scanRecursive :: FilePath -> Pruner -> IO DirMap-scanRecursive topdir prune = M.fromList <$> walk [] [topdir]-  where-	walk c [] = return c-	walk c (dir:rest)-		| prune dir = walk c rest-		| otherwise = do-			minfo <- catchMaybeIO $ getDirInfo dir-			case minfo of-				Nothing -> walk c rest-				Just info -> do-					mfd <- catchMaybeIO $-						openFd dir ReadOnly Nothing defaultFileFlags-					case mfd of-						Nothing -> walk c rest-						Just fd -> do-							let subdirs = map (dir </>) . map dirEnt $-								S.toList $ dirCache info-							walk ((fd, info):c) (subdirs ++ rest)--{- Adds a list of subdirectories (and all their children), unless pruned to a- - directory map. Adding a subdirectory that's already in the map will- - cause its contents to be refreshed. -}-addSubDirs :: DirMap -> Pruner -> [FilePath] -> IO DirMap-addSubDirs dirmap prune dirs = do-	newmap <- foldr M.union M.empty <$>-		mapM (\d -> scanRecursive d prune) dirs-	return $ M.union newmap dirmap -- prefer newmap--{- Removes a subdirectory (and all its children) from a directory map. -}-removeSubDir :: DirMap -> FilePath -> IO DirMap-removeSubDir dirmap dir = do-	mapM_ closeFd $ M.keys toremove-	return rest-  where-	(toremove, rest) = M.partition (dirContains dir . dirName) dirmap--findDirContents :: DirMap -> FilePath -> [FilePath]-findDirContents dirmap dir = concatMap absolutecontents $ search-  where-	absolutecontents i = map (dirName i </>)-		(map dirEnt $ S.toList $ dirCache i)-	search = map snd $ M.toList $-		M.filter (\i -> dirName i == dir) dirmap--foreign import ccall safe "libkqueue.h init_kqueue" c_init_kqueue-	:: IO Fd-foreign import ccall safe "libkqueue.h addfds_kqueue" c_addfds_kqueue-	:: Fd -> CInt -> Ptr Fd -> IO ()-foreign import ccall safe "libkqueue.h waitchange_kqueue" c_waitchange_kqueue-	:: Fd -> IO Fd--{- Initializes a Kqueue to watch a directory, and all its subdirectories. -}-initKqueue :: FilePath -> Pruner -> IO Kqueue-initKqueue dir pruned = do-	dirmap <- scanRecursive dir pruned-	h <- c_init_kqueue-	let kq = Kqueue h dir dirmap pruned-	updateKqueue kq-	return kq--{- Updates a Kqueue, adding watches for its map. -}-updateKqueue :: Kqueue -> IO ()-updateKqueue (Kqueue h _ dirmap _) =-	withArrayLen (M.keys dirmap) $ \fdcnt c_fds -> do-		c_addfds_kqueue h (fromIntegral fdcnt) c_fds--{- Stops a Kqueue. Note: Does not directly close the Fds in the dirmap,- - so it can be reused.  -}-stopKqueue :: Kqueue -> IO ()-stopKqueue = closeFd . kqueueFd--{- Waits for a change on a Kqueue.- - May update the Kqueue.- -}-waitChange :: Kqueue -> IO (Kqueue, [Change])-waitChange kq@(Kqueue h _ dirmap _) = do-	changedfd <- c_waitchange_kqueue h-	if changedfd == -1-		then ifM ((==) eINTR <$> getErrno)-			(yield >> waitChange kq, nochange)-		else case M.lookup changedfd dirmap of-			Nothing -> nochange-			Just info -> handleChange kq changedfd info-  where-	nochange = return (kq, [])--{- The kqueue interface does not tell what type of change took place in- - the directory; it could be an added file, a deleted file, a renamed- - file, a new subdirectory, or a deleted subdirectory, or a moved- - subdirectory. - -- - So to determine this, the contents of the directory are compared- - with its last cached contents. The Kqueue is updated to watch new- - directories as necessary.- -}-handleChange :: Kqueue -> Fd -> DirInfo -> IO (Kqueue, [Change])-handleChange kq@(Kqueue _ _ dirmap pruner) fd olddirinfo =-	go =<< catchMaybeIO (getDirInfo $ dirName olddirinfo)-  where-	go (Just newdirinfo) = do-		let changes = filter (not . pruner . changedFile) $-			 olddirinfo // newdirinfo-		let (added, deleted) = partition isAdd changes--		-- Scan newly added directories to add to the map.-		-- (Newly added files will fail getDirInfo.)-		newdirinfos <- catMaybes <$>-			mapM (catchMaybeIO . getDirInfo . changedFile) added-		newmap <- addSubDirs dirmap pruner $ map dirName newdirinfos--		-- Remove deleted directories from the map.-		newmap' <- foldM removeSubDir newmap (map changedFile deleted)--		-- Update the cached dirinfo just looked up.-		let newmap'' = M.insertWith' const fd newdirinfo newmap'--		-- When new directories were added, need to update-		-- the kqueue to watch them.-		let kq' = kq { kqueueMap = newmap'' }-		unless (null newdirinfos) $-			updateKqueue kq'--		return (kq', changes)-	go Nothing = do-		-- The directory has been moved or deleted, so-		-- remove it from our map.-		newmap <- removeSubDir dirmap (dirName olddirinfo)-		return (kq { kqueueMap = newmap }, [])--{- Processes changes on the Kqueue, calling the hooks as appropriate.- - Never returns. -}-runHooks :: Kqueue -> WatchHooks -> IO ()-runHooks kq hooks = do-	-- First, synthetic add events for the whole directory tree contents,-	-- to catch any files created beforehand.-	recursiveadd (kqueueMap kq) (Added $ kqueueTop kq)-	loop kq-  where-	loop q = do-		(q', changes) <- waitChange q-		forM_ changes $ dispatch (kqueueMap q')-		loop q'--	dispatch _ change@(Deleted _) = -		callhook delHook Nothing change-	dispatch _ change@(DeletedDir _) =-		callhook delDirHook Nothing change-	dispatch dirmap change@(Added _) =-		withstatus change $ dispatchadd dirmap-		-	dispatchadd dirmap change s-		| Files.isSymbolicLink s = callhook addSymlinkHook (Just s) change-		| Files.isDirectory s = recursiveadd dirmap change-		| Files.isRegularFile s = callhook addHook (Just s) change-		| otherwise = noop--	recursiveadd dirmap change = do-		let contents = findDirContents dirmap $ changedFile change-		forM_ contents $ \f ->-			withstatus (Added f) $ dispatchadd dirmap--	callhook h s change = case h hooks of-		Nothing -> noop-		Just a -> a (changedFile change) s--	withstatus change a = maybe noop (a change) =<<-		(catchMaybeIO (getSymbolicLinkStatus (changedFile change)))
Utility/Process.hs view
@@ -22,15 +22,16 @@ 	createProcessChecked, 	createBackgroundProcess, 	processTranscript,+	processTranscript', 	withHandle, 	withBothHandles, 	withQuietOutput,-	withNullHandle, 	createProcess, 	startInteractiveProcess, 	stdinHandle, 	stdoutHandle, 	stderrHandle,+	devNull, ) where  import qualified System.Process@@ -162,10 +163,13 @@  - returns a transcript combining its stdout and stderr, and  - whether it succeeded or failed. -} processTranscript :: String -> [String] -> (Maybe String) -> IO (String, Bool)+processTranscript cmd opts input = processTranscript' cmd opts Nothing input++processTranscript' :: String -> [String] -> Maybe [(String, String)] -> (Maybe String) -> IO (String, Bool) #ifndef mingw32_HOST_OS {- This implementation interleves stdout and stderr in exactly the order  - the process writes them. -}-processTranscript cmd opts input = do+processTranscript' cmd opts environ input = do 	(readf, writef) <- createPipe 	readh <- fdToHandle readf 	writeh <- fdToHandle writef@@ -174,6 +178,7 @@ 			{ std_in = if isJust input then CreatePipe else Inherit 			, std_out = UseHandle writeh 			, std_err = UseHandle writeh+			, env = environ 			} 	hClose writeh @@ -195,12 +200,13 @@ 	return (transcript, ok) #else {- This implementation for Windows puts stderr after stdout. -}-processTranscript cmd opts input = do+processTranscript' cmd opts environ input = do 	p@(_, _, _, pid) <- createProcess $ 		(proc cmd opts) 			{ std_in = if isJust input then CreatePipe else Inherit 			, std_out = CreatePipe 			, std_err = CreatePipe+			, env = environ 			}  	getout <- mkreader (stdoutHandle p)@@ -274,20 +280,18 @@ 	:: CreateProcessRunner 	-> CreateProcess 	-> IO ()-withQuietOutput creator p = withNullHandle $ \nullh -> do+withQuietOutput creator p = withFile devNull WriteMode $ \nullh -> do 	let p' = p 		{ std_out = UseHandle nullh 		, std_err = UseHandle nullh 		} 	creator p' $ const $ return () -withNullHandle :: (Handle -> IO a) -> IO a-withNullHandle = withFile devnull WriteMode-  where+devNull :: FilePath #ifndef mingw32_HOST_OS-	devnull = "/dev/null"+devNull = "/dev/null" #else-	devnull = "NUL"+devNull = "NUL" #endif  {- Extract a desired handle from createProcess's tuple.
Utility/Rsync.hs view
@@ -67,7 +67,8 @@  -} rsyncProgress :: MeterUpdate -> [CommandParam] -> IO Bool rsyncProgress meterupdate params = do-	r <- withHandle StdoutHandle createProcessSuccess p (feedprogress 0 [])+	r <- catchBoolIO $ +		withHandle StdoutHandle createProcessSuccess p (feedprogress 0 []) 	{- For an unknown reason, piping rsync's output like this does 	 - causes it to run a second ssh process, which it neglects to wait 	 - on. Reap the resulting zombie. -}
Utility/ThreadScheduler.hs view
@@ -53,8 +53,11 @@ {- Pauses the main thread, letting children run until program termination. -} waitForTermination :: IO () waitForTermination = do+#ifdef mingw32_HOST_OS+	runEvery (Seconds 600) $+		void getLine+#else 	lock <- newEmptyMVar-#ifndef mingw32_HOST_OS 	let check sig = void $ 		installHandler sig (CatchOnce $ putMVar lock ()) Nothing 	check softwareTermination@@ -62,8 +65,8 @@ 	whenM (queryTerminal stdInput) $ 		check keyboardSignal #endif-#endif 	takeMVar lock+#endif  oneSecond :: Microseconds oneSecond = 1000000
Utility/WebApp.hs view
@@ -53,9 +53,13 @@ browserProc url = proc "am" 	["start", "-a", "android.intent.action.VIEW", "-d", url] #else+#ifdef mingw32_HOST_OS+browserProc url = proc "cmd" ["/c start " ++ url]+#else browserProc url = proc "xdg-open" [url] #endif #endif+#endif  {- Binds to a socket on localhost, or possibly a different specified  - hostname or address, and runs a webapp on it.@@ -64,7 +68,7 @@  - such as start a web browser to view the webapp.  -} runWebApp :: Maybe HostName -> Wai.Application -> (SockAddr -> IO ()) -> IO ()-runWebApp h app observer = do+runWebApp h app observer = withSocketsDo $ do 	sock <- getSocket h 	void $ forkIO $ runSettingsSocket webAppSettings sock app 	sockaddr <- fixSockAddr <$> getSocketName sock@@ -93,11 +97,11 @@  -} getSocket :: Maybe HostName -> IO Socket getSocket h = do-#ifdef __ANDROID__+#if defined(__ANDROID__) || defined (mingw32_HOST_OS) 	-- getAddrInfo currently segfaults on Android. 	-- The HostName is ignored by this code. 	when (isJust h) $-		error "getSocket with HostName not supported on Android"+		error "getSocket with HostName not supported on this OS" 	addr <- inet_addr "127.0.0.1"  	sock <- socket AF_INET Stream defaultProtocol 	preparesocket sock
− Utility/Win32Notify.hs
@@ -1,65 +0,0 @@-{- Win32-notify interface- -- - Copyright 2013 Joey Hess <joey@kitenet.net>- -- - Licensed under the GNU GPL version 3 or higher.- -}--module Utility.Win32Notify where--import Common hiding (isDirectory)-import Utility.DirWatcher.Types--import System.Win32.Notify-import qualified System.PosixCompat.Files as Files--watchDir :: FilePath -> (FilePath -> Bool) -> WatchHooks -> IO WatchManager-watchDir dir ignored hooks = do-	scan dir-	wm <- initWatchManager-	void $ watchDirectory wm dir True [Create, Delete, Modify, Move] handle-	return wm-  where-	handle evt-		| ignoredPath ignored (filePath evt) = noop-		| otherwise = case evt of-			(Deleted _ _)-				| isDirectory evt -> runhook delDirHook Nothing-				| otherwise -> runhook delHook Nothing-			(Created _ _)-				| isDirectory evt -> noop-				| otherwise -> runhook addHook Nothing-			(Modified _ _)-				| isDirectory evt -> noop-				{- Add hooks are run when a file is modified for -				 - compatability with INotify, which calls the add-				 - hook when a file is closed, and so tends to call-				 - both add and modify for file modifications. -}-				| otherwise -> do-					runhook addHook Nothing-					runhook modifyHook Nothing-	  where-		runhook h s = maybe noop (\a -> a (filePath evt) s) (h hooks)--	scan d = unless (ignoredPath ignored d) $-		mapM_ go =<< dirContentsRecursive d-	  where		-		go f-			| ignoredPath ignored f = noop-			| otherwise = do-				ms <- getstatus f-				case ms of-					Nothing -> noop-					Just s-						| Files.isRegularFile s ->-							runhook addHook ms-						| otherwise ->-							noop-		  where-			runhook h s = maybe noop (\a -> a f s) (h hooks)-		-	getstatus = catchMaybeIO . getFileStatus--{- Check each component of the path to see if it's ignored. -}-ignoredPath :: (FilePath -> Bool) -> FilePath -> Bool-ignoredPath ignored = any ignored . map dropTrailingPathSeparator . splitPath
+ build.bat view
@@ -0,0 +1,1 @@+C:\MINGW\MSYS\1.0\BIN\SH.EXE standalone/windows/build-simple.sh
debian/changelog view
@@ -1,3 +1,38 @@+git-annex (5.20131213) unstable; urgency=low++  * Avoid using git commit in direct mode, since in some situations+    it will read the full contents of files in the tree.+  * assistant: Batch jobs are now run with ionice and nocache, when+    those commands are available.+  * assistant: Run transferkeys as batch jobs.+  * Automatically fix up bad bare repositories created by+    versions 5.20131118 through 5.20131127.+  * rsync special remote: Fix fallback mode for rsync remotes that+    use hashDirMixed. Closes: #731142+  * copy --from, get --from: When --force is used, ignore the+    location log and always try to get the file from the remote.+  * Deal with box.com changing the url of their webdav endpoint.+  * Android: Fix SRV record lookups for XMPP to use android getprop+    command to find DNS server, since there is no resolv.conf.+  * import: Add --skip-duplicates option.+  * lock: Require --force. Closes: #731606+  * import: better handling of overwriting an existing file/directory/broken+    link when importing+  * Windows: assistant and webapp work! (very experimental)+  * Windows: Support annex.diskreserve.+  * Fix bad behavior in Firefox, which was caused by an earlier fix to+    bad behavior in Chromium.+  * repair: Improve repair of git-annex index file.+  * repair: Remove damaged git-annex sync branches.+  * status: Ignore new files that are gitignored.+  * Fix direct mode's handling when modifications to non-annexed files+    are pulled from a remote. A bug prevented the files from being updated+    in the work tree, and this caused the modification to be reverted.+  * OSX: Remove ssh and ssh-keygen from dmg as they're included in OSX by+    default.++ -- Joey Hess <joeyh@debian.org>  Fri, 13 Dec 2013 14:20:32 -0400+ git-annex (5.20131130) unstable; urgency=low    * init: Fix a bug that caused git annex init, when run in a bare
debian/control view
@@ -73,7 +73,14 @@ 	wget, 	curl, 	openssh-client (>= 1:5.6p1)-Recommends: lsof, gnupg, bind9-host, ssh-askpass, quvi, git-remote-gcrypt (>= 0.20130908-4)+Recommends: +	lsof,+	gnupg,+	bind9-host,+	ssh-askpass,+	quvi,+	git-remote-gcrypt (>= 0.20130908-4),+	nocache Suggests: graphviz, bup, libnss-mdns Description: manage files with git, without checking their contents into git  git-annex allows managing files with git, without checking the file
debian/copyright view
@@ -88,7 +88,7 @@  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Files: static/*/bootstrap* static/img/glyphicons-halflings*+Files: static/bootstrap* static/glyphicons-halflings* Copyright: 2012 Twitter, Inc. License: Apache-2.0  Licensed under the Apache License, Version 2.0 (the "License");
doc/bugs/Android:_500___47__etc__47__resolv.conf_does_not_exist.mdwn view
@@ -22,3 +22,5 @@  # End of transcript or log. """]]++> [[fixed|done]] --[[Joey]] 
+ doc/bugs/Automatic_upgrades_should_be_cryptographically_signed.mdwn view
@@ -0,0 +1,5 @@+All builds of git-annex should be cryptographically signed.  Especially the automatic upgrades.++Signing doesn't minimise the likelihood of unwanted software being installed, but it helps reduce it.++*Please* Joey...
+ doc/bugs/Backup_repository_doesn__39__t_get_all_files.mdwn view
@@ -0,0 +1,35 @@+### Please describe the problem.+Backup group repositories don't download all "unused" files when running the webapp.+++### What steps will reproduce the problem?+Run the webapp, set up two local repositories:++1 - Use this for testing, set to manual type++2 - Use for backups, set to full backup type++Create some files, change them, etc.  See that files and history get transferred from #1 --> #2++Change #2 to being "don't sync".  For example, you are running out of disk space, or are off the network.++Edit a file in #1 a couple of times.  Now change #2 to synchronise.++Now, #2 will reflect #1 in the current state.++Stop the annex assistant.++Change #2 to being indirect mode.  Try to checkout a previous revision. There will be broken symlinks.  git annex get will fail with "no copies of this file" type errors.+++My expectation (incorrectly?) was that all the "history" of my files would be automatically transferred to the backup group repos.  It seems only the git commits are transferred, but the "unused" file content isn't.++--- ++What this tells me is that any changes that occur whilst I am not networked are entirely localised to my machine.  If this is the design expectation, can we squash commits before sending them?  There seems to be no point in having commits pointing to file content that has no chance of being accessed.+++### What version of git-annex are you using? On what operating system?+git-annex version: 5.20131130-gc25be33++
+ doc/bugs/Building_on_OpenBSD.mdwn view
@@ -0,0 +1,40 @@+### Please describe the problem.+Hi!+I just tried to build git-annex through cabal on OpenBSD and encountered some issues.++First I had to install a certain commit of network-info that fixes some compile-time errors (https://github.com/jystic/network-info/issues/6)+Then I had to disable WebDAV in git-annex because DAV wouldn't build (I don't use webdav anyway)++After this git-annex still failed to build, though configure works.+### What steps will reproduce the problem?+Compiling on openbsd through cabal++### What version of git-annex are you using? On what operating system?+git-annex-5.20131130 on OpenBSD 5.4++### Please provide any additional information below.++[[!format sh """+The error in question:+[312 of 389] Compiling Assistant.Pairing.Network ( Assistant/Pairing/Network.hs, dist/build/git-annex/git-annex-tmp/Assistant/Pairing/Network.o )++Assistant/Pairing/Network.hs:101:21:+    Not in scope: type constructor or class `IPv4'++Assistant/Pairing/Network.hs:102:21:+    Not in scope: data constructor `IPv4'++Assistant/Pairing/Network.hs:104:21:+    Not in scope: type constructor or class `IPv6'++Assistant/Pairing/Network.hs:105:21:+    Not in scope: data constructor `IPv6'++Assistant/Pairing/Network.hs:108:32:+    Not in scope: data constructor `IPv4'++Assistant/Pairing/Network.hs:109:47:+    Not in scope: data constructor `IPv6'+"""]]++> [[done]]; see comment --[[Joey]]
+ doc/bugs/Empty_folders_don__39__t_get_remove.mdwn view
@@ -0,0 +1,4 @@+### Please describe the problem.+When you rename, move or delete a folder (with files in it) the old folder doesn't get deleted in the other clients++[[!tag moreinfo]]
doc/bugs/Git_annex_add_fails_on_read-only_files.mdwn view
@@ -35,3 +35,15 @@     upgrade supported from repository versions: 0 1 2      git version 1.8.4.3++> Based on the new example, I don't consider this to be a bug.+> I don't think that `git annex import` should disregard directory+> permissions when importing files from them.+> +> One very good reason not to+> eg, chmod the directory itself is that if it did, running `git annex+> import` on a git-annex repository would defeat git-annex's own use of+> directory permissions to prevent deletion of the files in that+> repository!+> +> So, [[done]] --[[Joey]]
+ doc/bugs/No_manual_page_on_prebuilt_linux_version.mdwn view
@@ -0,0 +1,16 @@+### Please describe the problem, What steps will reproduce the problem?++    $ which git-annex+    ~/.local/bin/git-annex+    $ git help annex+    No manual entry for git-annex+    $ git annex --help+    No manual entry for git-annex++(either that or it display the manual of system-installed git-annex, not the locally installed one)++### What version of git-annex are you using? On what operating system?++Fedora 20++`git-annex --version` doesn't work and the webapp tells me Version: 5.20131130-gc25be33
+ doc/bugs/annex_seems_to_ignore_core.bare_setting.mdwn view
@@ -0,0 +1,45 @@+### Please describe the problem.+I have a transfer repository on a thumbdrive with a FAT file system mounted. It has been working very well for almost a year.+However, the current annex version overrides the core.bare setting with 'false' and tries to checkout the work tree on my thumbdrive (e.g. on a 'git annex status').++### What version of git-annex are you using? On what operating system?++Broken git-annex versions:++ * 5.20131130-gc25be33+ * 5.20131118-gc7e5cde++Working version:++ * 4.20131101-gf59a6d1++OS is Linux.++### Please provide any additional information below.++[[!format sh """+$> git config --list+core.repositoryformatversion=0+core.filemode=false+core.bare=true+core.symlinks=false+core.ignorecase=true+annex.uuid=3fb63b01-40cf-4613-b171-d6cba04028af+annex.version=4+annex.crippledfilesystem=true+annex.direct=true+"""]]++[[!format sh """+$> git annex status -d+[2013-12-05 15:01:30 CET] read: git ["--git-dir=/media/transfer/annex-media.git","--work-tree=/media/transfer","-c","core.bare=false","symbolic-ref","HEAD"]+[2013-12-05 15:01:30 CET] read: git ["--git-dir=/media/transfer/annex-media.git","--work-tree=/media/transfer","-c","core.bare=false","show-ref","--hash","refs/heads/master"]+[2013-12-05 15:01:30 CET] call: git ["--git-dir=/media/transfer/annex-media.git","--work-tree=/media/transfer","-c","core.bare=false","update-ref","refs/heads/annex/direct/master","eb688442ea29660e9bc604434a77821b9c0349ad"]+[2013-12-05 15:01:30 CET] call: git ["--git-dir=/media/transfer/annex-media.git","--work-tree=/media/transfer","-c","core.bare=false","checkout","-q","-B","annex/direct/master"]+...+git-annex: git [Param "checkout",Param "-q",Param "-B",Param "annex/direct/master"] failed+"""]]++> If I understand the followup comment corretcly, it confirms my hypothesis+> that this is about the bug that has since been fixed. So, [[done]].+> --[[Joey]] 
+ doc/bugs/assistant_locked_my_files.mdwn view
@@ -0,0 +1,28 @@+### Please describe the problem.++When the assistant is running, using "git annex unlock" on the commandline may lead to unexpected results.++### What steps will reproduce the problem?++Make sure the assitant is running on a repository.++`git annex unlock somefiles`, try to edit them, wait a while, try to edit.++If you're not lucky, the assistant will notice the unlocked files as new and will add them back, locking them in the process, and you won't be able to save them.++### What version of git-annex are you using? On what operating system?++debian wheezy.++[[!format sh """+git-annex version: 5.20131109-gf2cb5b9+build flags: Assistant Webapp Pairing Testsuite S3 WebDAV Inotify DBus XMPP DNS Feeds Quvi TDFA CryptoHash+key/value backends: SHA256E SHA1E SHA512E SHA224E SHA384E SKEIN256E SKEIN512E SHA256 SHA1 SHA512 SHA224 SHA384 SKEIN256 SKEIN512 WORM URL+remote types: git gcrypt S3 bup directory rsync web webdav glacier hook+local repository version: 3+default repository version: 3+supported repository versions: 3 5+upgrade supported from repository versions: 0 1 2 4+"""]]++### Please provide any additional information below.
+ doc/bugs/copy_to_--fast_should_not_mention_every_file_it_checks.mdwn view
@@ -0,0 +1,25 @@+### Please describe the problem.++When copying files to s3 using,++    git annex copy --quiet --to mys3 --fast++No information whatsoever is printed during upload when ran without `--quite` it prints a line for each file in the repo creating page after page of output for repos with thousands of file basically no way to tell which files got uploaded. Is it possible to have a verbosity level between quite and verbose that only reports progress on actual copy/move operations.++### What steps will reproduce the problem?+++### What version of git-annex are you using? On what operating system?+++### Please provide any additional information below.++[[!format sh """+# If you can, paste a complete transcript of the problem occurring here.+# If the problem is with the git-annex assistant, paste in .git/annex/daemon.log+++# End of transcript or log.+"""]]++[[!meta title="copy --fast --to remote should be quiet when nothing to do"]]
doc/bugs/direct_mode_sync_should_avoid_git_commit.mdwn view
@@ -2,4 +2,4 @@  So, git annex sync should stop using git commit when in direct mode, and instead manually make its own commit. Git.Branch.commit and Git.Branch.update should be able to easily be used for this. -PS: this page was created elsewhere, and therefore not listed in bugs page+> [[done]] --[[Joey]]
doc/bugs/git-annex_does_not_install_on_windows_without_admin_rights.mdwn view
@@ -1,6 +1,8 @@ ### Please describe the problem. -Installing on Windows requires installing git followed by git-annex. Installing the former works without admin rights, but the latter cannot be installed afterwards.+Installing on Windows requires installing git followed by git-annex.+Installing the former works without admin rights, but the latter cannot be+installed afterwards.  ### What steps will reproduce the problem? @@ -15,5 +17,6 @@ ### Please provide any additional information below.  -Installing git creates read-only directories that cannot be used by the git-annex install afterwards. Without admin rights, the read-only flag of the git dir cannot be altered.-+Installing git creates read-only directories that cannot be used by the+git-annex install afterwards. Without admin rights, the read-only flag of+the git dir cannot be altered.
+ doc/bugs/git_annex_lock_dangerous.mdwn view
@@ -0,0 +1,19 @@+### Please describe the problem.++Git annex lock discards data without --force; this is misleading from the name.++### What steps will reproduce the problem?++    git annex unlock something.txt+    kwrite something.txt # edit+    git annex lock something.txt # lock is the opposite of unlock, right?++Oops, just lost my changes!++If you want my opinion, `git annex lock` should either require `-f` to throw away data or should be renamed (e.g. to `revert` or `checkout`).++### What version of git-annex are you using? On what operating system?++git version 1.8.1.2, git-annex version: 4.20130815, Kubuntu 13.04++> Agreed; [[done]] --[[Joey]]
+ doc/bugs/git_annex_status_doesn__39__t_use_.gitignore_in_direct_mode.mdwn view
@@ -0,0 +1,18 @@+Hello all!++I'm doing tests with git annex to see how it works, and to start with it I'm trying to track my /home using some kind of a *white list* with .gitignore.++So I have this .gitignore file:++    /*+    !/web+    +    !/Desktop+    /Desktop/*+    !/Desktop/Work++and when I do *git annex add .* it works as expected: It adds only ~/web and ~/Desktop/Work... but when I do *git annex status* it shows me the entire /home... it seems that *git annex status* doesn't use .gitignore... is this a bug or an intended behavior?++Thanks for your time :)++> [[fixed|done]] --[[Joey]] 
+ doc/bugs/incremental_fsck_should_not_use_sticky_bit.mdwn view
@@ -0,0 +1,15 @@+### Please describe the problem.++There are multiple problems that have the same cause:++ * When using a shared repository (core.sharedrepository = group), the directories that contain the actual objects may be owned by different users. In this case adding or removing the sticky bit is prohibited by the operating system. Thus shared repositories can only be incrementally fscked if all objects are owned by the same user.++ * It is not currently possible to run incremental fscks on the local repository and on a special remote at the same time, because both of them use the same flag space, the sticky bit.++### What steps will reproduce the problem?++Create a shared repository (core.sharedrepository = group), let a different user add an object and then try to fsck it.++### What version of git-annex are you using? On what operating system?++Debian's 4.20131106~bpo70+1
@@ -0,0 +1,26 @@+### Please describe the problem.++I noticed that you (@joey) wrote++> webapp: Odd problem when using Firefox: Some links don't seem to load. Clicking on such a link repeatedly will eventually load the right page. Network console shows web browser is requesting page "/" despite a link to another page being clicked on. Workaround: Use Chrome instead; no such problem there.++in [[todo/windows_support]], and thought I would get around to mentioning that I also see this problem on linux (so it's not windows specific), but I am using firefox.+++### What steps will reproduce the problem?+Click on a link in the webapp; most of the time, even though the link target is correct, the current page is reloaded instead of loading the target.++### What version of git-annex are you using? On what operating system?+5.20131205-gc448602++Ubuntu 13.04, firefox 25.0.1++++--Walter++> [[fixed|done]]; increased number of longpolling failures allowed before+> it enters the chromium back button bugfix workaround to 12.+> Should be more than enough for 3 or 4 long polling elements on a page.+> (Considered only running the chromium bugfix on chromium, but I don't+> want to get into browser detection hacks.) --[[Joey]]
doc/design/assistant/gpgkeys.mdwn view
@@ -24,6 +24,9 @@    with many subkeys may not). Debian has command-line utilities that    can generate and read such a QR code. +   Another way would be to use shamir secret sharing to split the key into+   N peices and send each one to one of the user's repos.+ 3. Help user learn the gpg keys of people they want to share their repo    with, and give them access. If the public key was recorded in the git-annex    branch, this could be easily determined when sharing repositories with
doc/design/assistant/syncing.mdwn view
@@ -1,28 +1,7 @@ Once files are added (or removed or moved), need to send those changes to all the other git clones, at both the git level and the key/value level. -## efficiency--Currently after each file transfer (upload or download), a git sync is done-to all remotes. This is rather a lot of work, also it prevents collecting-presence changes to the git-annex branch into larger commits, which would-save disk space over time.--In many cases, this sync is necessary. For example, when a file is uploaded-to a transfer remote, the location change needs to be synced out so that-other clients know to grab it.--Or, when downloading a file from a drive, the sync lets other locally-paired repositories know we got it, so they can download it from us. -OTOH, this is also a case where a sync is sometimes unnecessary, since-if we're going to upload the file to them after getting it, the sync-only perhaps lets them start downloading it before our transfer queue-reaches a point where we'd upload it.--Do we need all the mapping stuff discussed below to know when we can avoid-syncs?--## TODO+## misc TODO  * Test MountWatcher on LXDE. * Add a hook, so when there's a change to sync, a program can be run@@ -51,30 +30,11 @@   and fall back to some other method -- either storing deferred downloads   on disk, or perhaps scheduling a TransferScanner run to get back into sync. -## data syncing--There are two parts to data syncing. First, map the network and second,-decide what to sync when.--Mapping the network can reuse code in `git annex map`. Once the map is-built, we want to find paths through the network that reach all nodes-eventually, with the least cost. This is a minimum spanning tree problem,-except with a directed graph, so really a Arborescence problem.--With the map, we can determine which nodes to push new content to. Then we-need to control those data transfers, sending to the cheapest nodes first,-and with appropriate rate limiting and control facilities.--This probably will need lots of refinements to get working well.--### first pass: flood syncing+## More efficient syncing -Before mapping the network, the best we can do is flood all files out to every-reachable remote. This is worth doing first, since it's the simplest way to-get the basic functionality of the assistant to work. And we'll need this-anyway.+See [[syncing/efficiency]] -## TransferScanner+## TransferScanner efficiency  The TransferScanner thread needs to find keys that need to be Uploaded to a remote, or Downloaded from it.
+ doc/design/assistant/syncing/efficiency.mdwn view
@@ -0,0 +1,73 @@+Currently, the git-annex assistant syncs with remotes in a way that is+dumb, and potentially inneficient:++1. Files are transferred to each reachable remote whose+   [[preferred_content]] setting indicates it wants the file.++2. After each file transfer (upload or download), a git sync+   is done to all the remotes, to update location log information.++## unncessary transfers++There are network toplogies where #1 is massively inneficient.+For example:++<pre>+  laptopA-----laptopB-----laptopC+      \         |             /+       \---cloud based repo--/+</pre>++When laptopA has a new file, it will first send it to laptopB. It will then+check if the cloud based transfer repository wants a copy. It will, because+laptopC has not yet gotten a copy. So laptopA will proceed with a slow+upload to the cloud, while meanwhile laptopB is sending the file over fast+LAN to laptopC.++(The more common case with no laptopC happens to work efficiently.+So does the case where laptopA is paired with laptopC.)++## unncessary syncing++Less importantly, the constant git syncing after each transfer is rather a+lot of work, and prevents collecting multiple presence changes to the git-annex +branch into larger commits, which would save disk space over time.++In many cases, this sync is necessary. For example, when a file is uploaded+to a transfer remote, the location change needs to be synced out so that+other clients know to grab it.++Or, when downloading a file from a drive, the sync lets other locally+paired repositories know we got it, so they can download it from us. +OTOH, this is also a case where a sync is sometimes unnecessary, since+if we're going to upload the file to them after getting it, the sync+only perhaps lets them start downloading it before our transfer queue+reaches a point where we'd upload it.++It would be good to find a way to detect when syncing is not immediately+necessary, and defer it.++## mapping++Mapping the repository network has the potential to get git-annex the+information it needs to avoid unnecessary transfers and/or unncessary+syncing.++Mapping the network can reuse code in `git annex map`. Once the map is+built, we want to find paths through the network that reach all nodes+eventually, with the least cost. This is a minimum spanning tree problem,+except with a directed graph, so really a Arborescence problem.++A significant problem in mapping is that nodes are mobile, they can move+between networks over time. This breaks LAN based paths through the+network. Mapping would need a way to detect this. Note that individual+git-annex assistants can tell when they've switched networks by using the+`networkConnectedNotifier`.++## P2P signaling++Another approach that might help with these problems is if git-annex+repositories have a non-git out of band signaling mechanism. This could,+for example, be used by laptopB to tell laptopA that it's trying to send +a file directly to laptopC. laptopA could then defer the upload to the+cloud for a while.
+ doc/design/external_special_remote_protocol.mdwn view
@@ -0,0 +1,260 @@+See [[todo/support_for_writing_external_special_remotes]] for motivation.++This is a design for a protocol to be used to communicate between git-annex+and a program implementing an external special remote.++The external special remote program has a name like+`git-annex-remote-$bar`. When `git annex initremote foo type=$bar` is run,+git-annex finds the appropriate program in PATH.++The program is started by git-annex when it needs to access the special+remote, and may be left running for a long period of time. This allows+it to perform expensive setup tasks, etc. Note that git-annex may choose to+start multiple instances of the program (eg, when multiple git-annex+commands are run concurrently in a repository).++## protocol overview++Communication is via stdin and stdout. Therefore, the external special+remote must avoid doing any prompting, or outputting anything like eg,+progress to stdout. (Such stuff can be sent to stderr instead.)++The protocol is line based. Messages are sent in either direction, from+git-annex to the special remote, and from the special remote to git-annex.++## example session++The special remote is responsible for sending the first message, indicating+the version of the protocol it is using.++	VERSION 0++Once it knows the version, git-annex will send a message telling the+special remote to start up.++	PREPARE++The special remote can now ask git-annex for its configuration, as needed,+and check that it's valid. git-annex responds with the configuration values++	GETCONFIG directory+	/media/usbdrive/repo+	GETCONFIG automount+	true++Once the special remote is satisfied with its configuration and is+ready to go, it tells git-annex.++	PREPARE-SUCCESS++Now git-annex will tell the special remote what to do. Let's suppose+it wants to store a key. ++	TRANSFER STORE somekey tmpfile++The special remote can continue sending messages to git-annex during this+transfer. It will typically send progress messages, indicating how many+bytes have been sent:++	PROGRESS STORE somekey 10240+	PROGRESS STORE somekey 20480++Once the key has been stored, the special remote tells git-annex the result:++	TRANSFER-SUCCESS STORE somekey++Once git-annex is done with the special remote, it will close its stdin.+The special remote program can then exit.++## git-annex request messages++These are the request messages git-annex may send to the special remote+program. None of these messages require an immediate reply. The special+remote can send any messages it likes while handling the requests.++Once the special remote has finished performing the request, it should+send one of the corresponding replies listed in the next section.++* `PREPARE`  +  Tells the special remote it's time to prepare itself to be used.+  Only run once, at startup, always immediately after the special remote+  sends VERSION.+* `INITREMOTE`  +  Request that the remote initialized itself. This is where any one-time+  setup tasks can be done, for example creating an Amazon S3 bucket.  +  (PREPARE is still sent before this.)  +  Note: This may be run repeatedly, as a remote is initialized in+  different repositories, or as the configuration of a remote is changed.+  So any one-time setup tasks should be done idempotently.+* `GETCOST`  +  Requests the remote return a use cost. Higher costs are more expensive.+  (See Config/Cost.hs for some standard costs.)+* `TRANSFER STORE|RETRIEVE Key File`  +  Requests the transfer of a key. For Send, the File is the file to upload;+  for Receive the File is where to store the download. Note that the File+  should not influence the filename used on the remote. The filename used+  should be derived from the Key.  +  Multiple transfers might be requested by git-annex, but it's fine for the +  program to serialize them and only do one at a time.+* `HAS Key`  +  Requests the remote check if a key is present in it.+* `REMOVE Key`  +  Requests the remote remove a key's contents.++## special remote replies++These should be sent only in response to the git-annex request messages.+(Any sent unexpectedly will be ignored.)+They do not have to be sent immediately after the request; the special+remote can send other messages and queries (listed in sections below)+as it's performing the request.++* `PREPARE-SUCCESS`  +  Sent as a response to PREPARE once the special remote is ready for use.+* `TRANSFER-SUCCESS STORE|RETRIEVE Key`  +  Indicates the transfer completed successfully.+* `TRANSFER-FAILURE STORE|RETRIEVE Key ErrorMsg`  +  Indicates the transfer failed.+* `HAS-SUCCESS Key`  +  Indicates that a key has been positively verified to be present in the+  remote.+* `HAS-FAILURE Key`  +  Indicates that a key has been positively verified to not be present in the+  remote.+* `HAS-UNKNOWN Key ErrorMsg`  +  Indicates that it is not currently possible to verify if the key is+  present in the remote. (Perhaps the remote cannot be contacted.)+* `REMOVE-SUCCESS Key`  +  Indicates the key has been removed from the remote. May be returned if+  the remote didn't have the key at the point removal was requested.+* `REMOVE-FAILURE Key`  +  Indicates that the key was unable to be removed from the remote.+* `COST Int`  +  Indicates the cost of the remote.+* `COST-UNKNOWN`  +  Indicates the remote has no opinion of its cost.+* `INITREMOTE-SUCCESS Setting=Value ...`  +  Indicates the INITREMOTE succeeded and the remote is ready to use.+  The settings and values can optionally be returned. They will be added+  to the existing configuration of the remote (and may change existing+  values in it).+* `INITREMOTE-FAILURE ErrorMsg`  +  Indicates that INITREMOTE failed.++## special remote messages++These are messages the special remote program can send to+git-annex at any time. It should not expect any response from git-annex.++* `VERSION Int`  +  Supported protocol version. Current version is 0. Must be sent first+  thing at startup, as until it sees this git-annex does not know how to+  talk with the special remote program!+* `ERROR ErrorMsg`  +  Generic error. Can be sent at any time if things get messed up.+  When possible, use a more specific reply from the list above.  +  It would be a good idea to send this if git-annex sends a command+  you do not support. The program should exit after sending this, as+  git-annex will not talk to it any further.+* `PROGRESS STORE|RETRIEVE Key Int`  +  Indicates the current progress of the transfer. May be repeated any+  number of times during the transfer process. This is highly recommended+  for STORE. (It is optional but good for RETRIEVE.)++## special remote queries++After git-annex has sent the special remote a request, and before the+special remote sends back a reply, git-annex enters quiet mode. It will+avoid sending additional messages. While git-annex is in quiet mode,+the special remote can send queries to it. Queries can not be sent at any+other time.++When it sees a query, git-annex will respond a line containing+*only* the requested data.++* `DIRHASH Key`  +  Gets a two level hash associated with a Key. Something like "abc/def".+  This is always the same for any given Key, so can be used for eg,+  creating hash directory structures to store Keys in.+* `GETCONFIG Setting`+  Gets one of the special remote's configuration settings.+* `SETSTATE Key Value`  +  git-annex can store state in the git-annex branch on a+  per-special-remote, per-key basis. This sets that state.+* `GETSTATE Key`  +  Gets any state previously stored for the key from the git-annex branch.  +  Note that some special remotes may be accessed from multiple+  repositories, and the state is only eventually consistently synced+  between them. If two repositories set different values in the state+  for a key, the one that sets it last wins.++## Simple shell example++[[!format sh """+#!/bin/sh+set -e++echo VERSION 0++while read line; do+	set -- $line+	case "$1" in+		INITREMOTE)+			# XXX do anything necessary to create resources+			# used by the remote. Try to be idempotent.+			# Use GETCONFIG to get any needed configuration+			# settings.+			echo INITREMOTE-SUCCESS+		;;+		GETCOST)+			echo COST-UNKNOWN+		;;+		PREPARE)+			# XXX Use GETCONFIG to get configuration settings,+			# and do anything needed to start using the+			# special remote here.+			echo PREPARE-SUCCESS+		;;+		TRANSFER)+			key="$3"+			file="$4"+			case "$2" in+				STORE)+					# XXX upload file here+					# XXX when possible, send PROGRESS+					echo TRANSFER-SUCCESS STORE "$key"+				;;+				RETRIEVE)+					# XXX download file here+					echo TRANSFER-SUCCESS RETRIEVE "$key"+				;;+				+			esac+		;;+		HAS)+			key="$2"+			echo HAS-UNKNOWN "$key" "not implemented"+		;;+		REMOVE)+			key="$2"+			# XXX remove key here+			echo REMOVE-SUCCESS "$key"+		;;+		*)+			echo ERROR "unknown command received: $line"+			exit 1+		;;+	esac	+done++# XXX anything that needs to be done at shutdown can be done here+"""]]++## TODO++* Communicate when the network connection may have changed, so long-running+  remotes can reconnect.+* uuid discovery during initremote.+* Support for splitting files into chunks.+* Use same verbs as used in special remote interface (instead of different+  verbs used in Types.Remote).
doc/design/roadmap.mdwn view
@@ -6,8 +6,8 @@  * Month 1 [[!traillink assistant/encrypted_git_remotes]] * Month 2 [[!traillink assistant/disaster_recovery]]-* **Month 3 user-driven features and polishing** [[todo/direct_mode_guard]] [[assistant/upgrading]]-* Month 4 improve special remote interface & git-annex enhancement contest+* Month 3 user-driven features and polishing [[todo/direct_mode_guard]] [[assistant/upgrading]]+* **Month 4 Windows porting, [[todo/support_for_writing_external_special_remotes]] & encourage others to contribute to git-annex** * Month 5 [[!traillink assistant/xmpp_security]] * Month 6 Windows assistant and webapp * Month 7 user-driven features and polishing
+ doc/devblog/day_68__bits_and_pieces.mdwn view
@@ -0,0 +1,14 @@+Made a release yesterday to fix a bug that made git-annex init in a bare+repository set core.bare=false. This bug only affected git-annex 5, it+was introduced when building the direct mode guard. Currently recovering+from it is a [manual (pretty easy) process](http://git-annex.branchable.com/bugs/assistant_creating_.git_directory_inside_bare_repo/#comment-73a8ce8aa100baa7c03861b769fdca29).+Perhas I should automate that, but I mostly wanted to get a fix out+before too many people encountered the bug.++Today, I made the assistant run batch jobs with ionice and nocache, when+those commands are available. Also, when the assistant transfers files,+that also runs as a batch job.++Changed how git-annex does commits, avoiding using `git commit` in direct+mode, since in some situations `git commit` (not with `-a`!) wants to+read the contents of files in the work tree, which can be very slow.
+ doc/devblog/day_69__catching_up.mdwn view
@@ -0,0 +1,14 @@+Still working through thanksgiving backlog. Around 55 messages to go.++Wrote hairy code to automatically fix up bad bare repositories created by+recent versions of git-annex. Managed to do it with only 1 stat call+overhead (per local repository). Will probably keep that code in git-annex+for a year or so, despite the bug only being present for a few weeks,+because the repositories that need to be fixed might be on removable drives+that are rarely used.++Various other small bug fixes, including dealing with box.com having+changed their WebDAV endpoint url.++Spent a while evaluating various key/value storage possibilities. +[[bugs/incremental_fsck_should_not_use_sticky_bit]] has the details.
+ doc/devblog/day_70__preliminary_user_survey_analysis.mdwn view
@@ -0,0 +1,104 @@+The [2013 git-annex user survey](http://git-annex-survey.branchable.com/polls/2013/)+has been running for several weeks and around 375 people have answered+at least the first question. While I am going to leave it up through the+end of the year, I went over the data today to see what interesting+preliminary conclusions I can draw.++* 11% build git-annex from source. More than I would have guessed.++* 20% use the prebuilt versions from the git-annex website.+  +  This is a number to keep in mind later, when more people have upgraded to+  the last release, which checks for upgrades. I can run some stats on+  the number of upgrade checks I receive, and multiplying that by 5 would+  give a good approximation of the total number of computers running+  git-annex.++* I'm surprised to see so many more Linux (79%) than OSX (15%) users.+  Also surprising is there are more Windows (2%) than Android (1%) users.+  (Android numbers may be artificially low since many users will use it in+  addition to one of the other OSes.)++* Android and Windows unsurprisingly lead in ports requested, but the +  Synology NAS is a surprise runner up, with 5% (more than IOS).++  In theory it would not be too hard to make a standalone arm tarball,+  which could be used on such a device, although IIRC the Synology had+  problems with a too old linker and libc. It would help if I could make+  the standalone tarball not depend on the system linker at all.+  +  A susprising number (3%) want some kind of port the the Raspberry Pi, which+  is weird because I'd think they'd just be using Raspbian on it.. but a+  standalone arm tarball would also cover that use case.++* A minimum of 1664 (probably closer to 2000) git annex repositories are being+  used by the 248 people who answered that question. Around 7 repositories+  per person average, which is either one repository checked out on 7+  different machines or two repositories on 3 machines, etc.++* At least 143 terabytes of data are being stored in git-annex. This does+  not count redundant data. (It also excludes several hundred terabytes from+  one instituion that I don't think are fully online yet.)+  Average user has more than half a terabyte of data.++* 8% of users store scientific data in git-annex! :) A couple of users are+  using it for game development assets, and 5% of users are using it for+  some form of business data.++* Only 10% of users are sharing a git-annex repository with at least one+  other person. 27% use it by themselves, but want to get others using+  their repositories. This probably points to it needing to be easier for+  nontechnical users.++* 61% of git-annex users have good or very good knowledge of git.+  This question intentionally used the same wording as the +  [general git user survey](https://git.wiki.kernel.org/index.php/GitSurvey2012),+  so the results can be compared. The curves have somewhat different+  shapes, with git-annex's users being biased more toward the higher+  knowledge levels than git's users.++* The question about how happy users are also used the same wording.+  While 74% of users are happy with git-annex, 94% are similarly happy with+  git, and a while the median git-annex user is happy, the median git user+  is very happy.+  +  The 10% who wrote in "very enthusiastic, but still often+  bitten by quirks (so not very happy yet, but with lots of confidence in+  the potential" might have thrown off this comparison some, but they+  certianly made their point!++* 3% of respondants say that a bug is preventing them from using git-annex,+  but that they have not reported the bug yet. Frustrating! 1% say that a+  bug that's been reported already is blocking them.++* 18% wrote in that they need the webapp to support using github (etc)+  as a central server. I've been moving in that direction with the+  encryption and some other changes, so it's probably time to make a UI for+  that.++* 12% want more control over which files are stored locally when using the+  assistant.++* A really surprising thing happened when someone wrote in that I should+  work on "not needing twice disk space of repo in direct mode", and 5% of+  people then picked this choice. This is some kind of documentation+  problem, because of course git-annex never needs 2x disk space, whether+  using direct mode or not. That's one of its advantages over git!++* Somewhere between 59 and 161 of the survey respondants use Debian.+  I can compare this with [Debian popularity contest data](http://qa.debian.org/popcon-graph.php?packages=git-annex)+  which has 400 active installations and 1000 total installations,+  and make guesses about what fraction of all git-annex users have answered+  the survey. By making different assumptions I got guesses that varied by+  2 orders of magnitude, so not worth bothering with. Explicitly asking how+  many people use each Linux distribution would be a good idea in next+  year's survey.++----++Main work today was fixing Android DNS lookups, which was trying to use+/etc/resolv.conf to look up SRV records for XMPP, and had to be changed to+use a getprop command instead. Since I can't remember dealing with this+before (not impossible I made some quick fix to the dns library before and+lost it though), I'm wondering if XMPP was ever usable on Android before.+Cannot remember. May work now, anyway...
+ doc/devblog/day_71__that_was_unexpected.mdwn view
@@ -0,0 +1,30 @@+Had planned to spend all day not working on git-annex and instead getting+caught up on conference videos. However, got a little bit multitasky while+watching those, and started investigating why, last time I worked on+Windows port, git-annex was failing to link. ++A good thing to do while watching conference videos since it involved lots of +test builds with different flags. Eventially solved it. +Building w/o WebDAV avoids crashing the compiler anyhow.++Thought I'd try the resulting binary and see if perhaps I had forgotten to+use the threaded RTS when I was running ghc by hand to link it last time,+and perhaps that was why threads+[[seemed to have hung|day_56__git-annex_user_survey]] back then.++It was. This became clear when I saw a "deadlocked indefinitely in MVar"+error message, which tells me that it's at least using the threaded RTS.+So, I fixed that, and a few other minor things, and ran this command+in a DOS prompt box:++	git annex watch --force --foreground --debug++And I've been making changes to files in that repository, and amazingly,+the watcher is noticing them, and committing them!++So, I was almost entirely there to a windows port of the watcher a month+ago, and didn't know. It has some rough edges, including not doing anything+to check if a newly created file is open for write when adding it, and+getting the full assistant ported will be more work, and the full webapp+may be a whole other set of problems, but this is a quite nice milestone+for the Windows port.
+ doc/devblog/day_72__windows_webapp_not.mdwn view
@@ -0,0 +1,22 @@+Got the entire webapp to build on Windows.++Compiling was easy. One line of code had to be #ifdefed out, and the whole+rest of the webapp UI just built!++Linking was epic. It seems that I really am runninginto a 32kb command line length+limit, which causes the link command to fail on Windows. git-annex with all+its bells and whistles enabled is just too big. Filed a +[ghc bug report](https://ghc.haskell.org/trac/ghc/ticket/8596), and got back a+helpful response about using <http://gcc.gnu.org/wiki/Response_Files> to+work around.++6 hours of slogging through compiling dependencies and fighting with+toolchain later, I have managed to link git-annex with the webapp!++The process is not automated yet. While I was able to automate+passing gcc a @file with its parameters, gcc then calls collect2, which+calls ld, and both are passed too many parameters. I have not found a way+to get gcc to generate a response file. So I did it manually. Urgh.++Also, it crashes on startup with `getAddrInfo` failure. But some more+porting is to be expected, now that the windows webapp links.. ;)
+ doc/devblog/day_73__EvilLinker.mdwn view
@@ -0,0 +1,28 @@+Android has the EvilSplicer, now Windows gets the EvilLinker. Fully+automated, and truly horrible solution to the too long command line problem.++Now when I run `git annex webapp` on windows, it almost manages to open+the web browser.++At the same time, I worked with Yuri to upgrade the Windows autobuilder to a+newer Haskell platform, which can install Yesod. I have not quite achieved+a successful webapp build on the autobuilder, but it seems close.++----++Here's a nice Haskell exercise for someone. I wrote this quick and dirty+function in the EvilSplicer, but it's crying out for a generalized solution.++[[!format haskell """+{- Input contains something like + - c:/program files/haskell platform/foo -LC:/Program Files/Haskell Platform/ -L...+ - and the *right* spaces must be escaped with \+ -+ - Argh.+ -}+escapeDosPaths :: String -> String+escapeDosPaths = replace "Program Files" "Program\\ Files"+        . replace "program files" "program\\ files"+        . replace "Haskell Platform" "Haskell\\ Platform"+        . replace "haskell platform" "haskell\\ platform"+"""]]
+ doc/devblog/day_74__so_close.mdwn view
@@ -0,0 +1,20 @@+Windows webapp now starts, opens a web browser, and ... crashes. ++<img src="https://identi.ca/uploads/joeyh/2013/12/7/hDkkSA.png">++This  is [a bug in warp](https://github.com/yesodweb/wai/issues/202)+or a deep level of the stack. I know that yesod apps have run on Windows+before, so apparently something has changed and introduced this problem.++Also have a problem with the autobuilder; the EvilSplicer or something+it runs is locking up on that system for reasons not yet determined.++Looks like I will need to wait a bit longer for the windows webapp, but I+could keep working on porting the assistant in the meantime. ++The most important thing that I need to port is how to check if a file+is being written to at the same time the assistant adds it to the+repository. No real `lsof` equivilant on Windows. I might be able to do+something with exclusive locking to detect if there's a writer (but this+would also block using the file while it was being added). Or I may be able+to avoid the need for this check, at least in direct mode.
+ doc/devblog/day_75__hallelujah.mdwn view
@@ -0,0 +1,8 @@+I have seen the glory of the webapp running on Windows.++One of the warp developers pointed me in the right direction and I+developed a fix for the `recv` bug.++My Windows and MSIE are old and fall over on some of the+javascript, so it's not glorious enough for a screenshot. But large chunks+of it do seem to work.
+ doc/devblog/day_76__results.mdwn view
@@ -0,0 +1,15 @@+Fixed up a few problems with the Windows webapp, and it's now completely+usable, using any browser other than MSIE. While there are missing+features in the windows port, all the UI for the features it does have+seems to just work in the webapp.++Fixed a ugly problem with Firefox, which turned out to have been introduced+a while ago by a workaround for an ugly problem in Chrome. Web browsers are+so wonderful, until they're crap.++Think I've fixed the bug in the EvilLinker that was causing it to hang on+the autobuilder, but still don't have a Windows autobuild with the webapp+just yet.++Also improved `git annex import` some more, and worked on a bug in git+repository repair, which I will need to spend some more time on tomorrow.
+ doc/devblog/day_77__it_builds.mdwn view
@@ -0,0 +1,8 @@+Got the Windows autobuilder building the webapp. Have not tried that build+yet myself, but I have high hopes it will work.++Made other Windows improvements, including making the installer+write a start menu entry file, and adding free disk space checking.++Spent rest of the day improving git repair code on a real-world corrupted+repository.
+ doc/devblog/day_78__desidetracked.mdwn view
@@ -0,0 +1,34 @@+I've switched over to mostly working on Windows porting in the evenings+when bored, with days spent on other git-annex stuff. So, getting back to+the planned [[design/roadmap]] for this month..++Set up a [tip4commit for git-annex](http://tip4commit.com/projects/152).+Anyone who gets a commit merged in will receive a currently small amount of+bitcoin. This would almost be a good way to encourage more committers+other than me, by putting say, half the money I have earmarked for that into+the tip jar. The problem is, I make too many commits myself, so most of the+money would be quickly tipped back out to me! I have gotten in touch with the+tip4commit people, and hope they will give me a way to blacklist+myself from being tipped.++Designed a [[design/external_special_remote_protocol]] that seems pretty+good for first-class special remotes implemented outside git-annex.+It's moderately complicated on the git-annex side to make it simple and+flexible on the special remote side, but I estimate only a few days to build+it once I have the design finalized.++# windows++Tested the autobuilt windows webapp. It works! Sorted out some issues with+the bundled libraries.++Reworked how `git annex transferkeys` communicates, to make it easier to+port it to Windows. Narrowly managed to avoid needing to write Haskell+bindings to Windows's equivilant of `pipe(2)`. I think the Windows+assistant can transfer keys now. and the webapp UI may even be able to be+used to stop transfers. Needs testing.++Investigated what I'll need to get XMPP working on Windows. Most of the+libs are available in cygwin, but gsasl would need to be built from source.+Also some kind of space-in-path problem is preventing cabal installing some+of the necessary dependencies.
+ doc/devblog/day_79__catch_up.mdwn view
@@ -0,0 +1,3 @@+Spent most of today catching up with a weeks's worth of traffic.++Fixed 2 bugs. Message backlog is 23 messages.
doc/encryption.mdwn view
@@ -28,7 +28,7 @@  The [[hybrid_key_design|design/encryption]] allows additional encryption keys to be added on to a special remote later. Due to this-flexability, it is the default and recommended encryption scheme.+flexibility, it is the default and recommended encryption scheme.   	git annex initremote newremote type=... [encryption=hybrid] keyid=KEYID ... 
+ doc/forum/Android_-_ext3__47__4__47__....mdwn view
@@ -0,0 +1,1 @@+Is there a good way to use a ext4 formated external sdcard on a rooted android with symlinks. If android mounts it (with the sdcard command i think) symlinks don't work. If i mount it with mount the permissions are a problem because every app has a different user.
+ doc/forum/Can_Not_Sync_to_Git_Repo.mdwn view
@@ -0,0 +1,1 @@+On one my repos (git repo on github data on S3) I've started getting, `fatal: Cannot force update the current branch` `git-annex: failed to update refs/heads/master` other clones of this repository can sync fine but this one started failing after adding a couple of files.
+ doc/forum/S3_Host_Question.mdwn view
@@ -0,0 +1,11 @@+I have two machines A & B.  Each have their our repository.++On machine A I have created a remotehost (S3) and have synced successfully.++I am trying to link machine B to the same remote host.  I keep getting an error on the initremote command on machine B.++I tried using the same command as I did on A and it is not working.   Is there a different command to link machine B to an existing remote repository?++Any help is appreciated.++Rob
+ doc/forum/Windows_S3_host_issue.mdwn view
@@ -0,0 +1,11 @@+I am trying to connect to dreamhost's objects (S3) platform.  I am using the windows version.  +Am I specifying the host correctly? Any help is appreciated.++$ git-annex initremote host="objects.dreamhost.com" cloud keyid=XXXXX type=S3++initremote host=objects.dreamhost.com (encryption setup) (hybrid cipher with gpg+ key 70827ADCDE25DA0F) (checking bucket...)+git-annex: user error (openTCPConnection: host lookup failure for "host=objects.+dreamhost.com-f5573b49-3668-4f94-a1da-aa55085c45e8.s3.amazonaws.com")+failed+git-annex.exe: initremote: 1 failed
− doc/forum/dropping_files_not_working_when_using_git_annex_assistant.txt
@@ -1,18 +0,0 @@-Just playing with git-annex which looks great so far, but I noticed that when you make use off "git annex assistant" to watch and sync your repo with the remote it doesn't drop files anymore. They just stay in the repo.--What I have is the following:--- 2 repo's in direct mode-- they both have each other as remote-- they're synced and stay synced with the assistant daemon running (in both repo's started "git annex assistant")-- is see changes coming and precessed, so so far so good.--Then I drop in one repo a path for instance like : git annex drop iso-Afterwards I still see the files (and contents) in that repo. New files in the iso path are still synced to the other and vise versa.--Then I kill the assistant on both side's and drop the path again. This time it's dropped as expected and the contents of the file in the iso path are gone.-Starting the assistant again brings is back though :(--I really liked the assistant feature and possibility of dropping the files from one repo, but they don't seem to work together.--Is this a bur or expected behaviour? I think the latter since the assistant also does the git annex get commands so sounds logical?
@@ -0,0 +1,18 @@+I'm testing out git-annex between a few computers one being a mac (osx 10.9) and a laptop (linux mint 16).  With a vps running git annex as a transfer annex.++Anyway sync is *almost* working...++When I add files on my mac's annex they upload, and go to my laptop as they should.++When I add files on my laptop's annex they upload, and the mac "downloads" them but only creates broken symlinks to the files.+++I looked in the log and nothing out of the ordinary is happening... is this a bug with the osx version or what?+++**more info**  ++* the symlink on the osx annex is symlinking to a file in .git/annex/objects  +* the osx annex changes the aliases to real files every time I restart the git annex daemon  ++Thanks!
+ doc/forum/handling_MP3_metadata_changes.txt view
@@ -0,0 +1,12 @@+Hello,++I'm still looking for a way to version control the metadata (title, artist, album name, ...) of my MP3s, I wonder if git annex could help for this problem ?+The method I use now (without git annex) is to export the MP3 metadata to an textual format with one line per tag. +It's this textual file I handles with git. +The problem is to handle the mapping between the orignal file and the export file with file renaming or moving.+I consider to use the checksum of the audio content (without metadata, this checksum never changes) to handle this problem.+Maybe git annex has a different approach (better) to solve this problem ?+How git annex would be use to solve the orignal problem ?++Regards,+Emmanuel Berry
+ doc/forum/local_pairing_with_2_mac.mdwn view
@@ -0,0 +1,27 @@+Hey !+I am trying to find ways to use git annex as a tool to share big binary files for our development projects (such as PSD files).+Our team has artists that will not use command line tools so I have been testing git-annex assistant with a lot of hope.+However all the tests I am doing are just failing. °.° '++in this thread I would like to focus on what would seem to me as an easy first approach : local pairing.++So my team and I are on mac. I am just trying to sync 2 computers on the same network. But the process is stuck on the "local pairing in process" step, just after I enter the secret phrase.++I have enabled sshd (preferences -> remote login) on both computers, checked the firewall to authorize git-annex, so I am probably missing something here. +the logs on my computer does not say anything usefull ([2013-12-04 22:04:34 CET] main: Pairing in progress) but on the other computer I have this :++git-annex: ssh-keygen failed+[2013-12-04 22:04:33 CET] PairListener: utku@MacBook-Air-de-utku.local:~/Documents/git-test is sending a pair request.+dyld: lazy symbol binding failed: Symbol not found: ___strlcpy_chk+ Referenced from: /Applications/git-annex.app/Contents/MacOS/bundle/ssh-keygen+ Expected in: /usr/lib/libSystem.B.dylib++dyld: Symbol not found: ___strlcpy_chk+ Referenced from: /Applications/git-annex.app/Contents/MacOS/bundle/ssh-keygen+ Expected in: /usr/lib/libSystem.B.dylib++git-annex: ssh-keygen failed++Don't know if that helps. I don't know which info I need to provide.++cheers
doc/git-annex.mdwn view
@@ -101,8 +101,12 @@   When used with the `--to` option, copies the content of annexed files from   the current repository to the specified one. -  To avoid contacting the remote to check if it has every file, specify `--fast`+  To avoid contacting the remote to check if it has every file+  when copying --to the repository, specify `--fast` +  To force checking the remote for every file when copying --from the+  repository, specify `--force`.+ * `status` [path ...]`    Similar to `git status --short`, displays the status of the files in the@@ -131,7 +135,7 @@ * `sync [remote ...]`    Use this command when you want to synchronize the local repository with-  one or more of its remotes. You can specifiy the remotes to sync with;+  one or more of its remotes. You can specify the remotes to sync with;   the default is to sync with all remotes. Or specify `--fast` to sync with   the remotes with the lowest annex-cost value. @@ -165,7 +169,7 @@   copy automatically.  * `mirror [path ...]`-  +   This causes a destination repository to mirror a source repository.    To use the local repository as the source repository,@@ -177,7 +181,7 @@   repository. If a file's content is present in the source repository, it is   copied to the destination repository. If a file's content is not present in   the source repository, it will be dropped from the destination repository-  when possible. +  when possible.    Note that mirror does not sync the git repository, but only the file   contents.@@ -231,11 +235,14 @@   To only import files whose content has not been seen before by git-annex,   use the `--deduplicate` option. Duplicate files will be deleted from the   import location.-  ++  To only import files whose content has not been seen before by git-annex,+  but avoid deleting duplicate files, use the `--skip-duplicates` option.+   The `--clean-duplicates` option does not import any new files, but any files   found in the import location that are duplicates of content in the annex   are deleted.-  +   (Note that using `--deduplicate` or `--clean-duplicates` with the WORM   backend does not look at file content, but filename and mtime.) @@ -263,7 +270,7 @@   By default, all files in the directory will be added to the repository.   (Including dotfiles.) To block some files from being added, use   `.gitignore` files.-  +   By default, all files that are added are added to the annex, the same   as when you run `git annex add`. If you configure annex.largefiles,   files that it does not match will instead be added with `git add`.@@ -298,7 +305,7 @@ * `init [description]`    Until a repository (or one of its remotes) has been initialized,-  git-annex will refuse to operate on it, to avoid accidentially+  git-annex will refuse to operate on it, to avoid accidentally   using it in a repository that was not intended to have an annex.    It's useful, but not mandatory, to initialize each new clone@@ -322,23 +329,23 @@   command will prompt for parameters as needed.    All special remotes support encryption. You can either specify-  `encryption=none` to disable encryption, or specify -  `encryption=hybrid keyid=$keyid ...` to specify a gpg key id (or an email+  `encryption=none` to disable encryption, or specify+  `encryption=hybrid keyid=$keyid ...` to specify a GPG key id (or an email   address associated with a key.)    There are actually three schemes that can be used for management of the   encryption keys. When using the encryption=hybrid scheme, additional-  gpg keys can be given access to the encrypted special remote easily+  GPG keys can be given access to the encrypted special remote easily   (without re-encrypting everything). When using encryption=shared,   a shared key is generated and stored in the git repository, allowing   anyone who can clone the git repository to access it. Finally, when using   encryption=pubkey, content in the special remote is directly encrypted-  to the specified gpg keys, and additional ones cannot easily be given+  to the specified GPG keys, and additional ones cannot easily be given   access.    Note that with encryption enabled, a cryptographic key is created.   This requires sufficient entropy. If initremote seems to hang or take-  a long time while generating the key, you may want to ctrl-c it and+  a long time while generating the key, you may want to Ctrl-c it and   re-run with `--fast`, which causes it to use a lower-quality source of   randomness. @@ -350,7 +357,7 @@    Enables use of an existing special remote in the current repository,   which may be a different repository than the one in which it was-  originally created with the initremote command. +  originally created with the initremote command.    The name of the remote is the same name used when origianlly    creating that remote with "initremote". Run "git annex enableremote"@@ -365,7 +372,7 @@   the as the encryption scheme cannot be changed once a special remote   has been created.) -  The gpg keys that an encrypted special remote is encrypted to can be+  The GPG keys that an encrypted special remote is encrypted to can be   changed using the keyid+= and keyid-= parameters. These respectively   add and remove keys from the list. However, note that removing a key   does NOT necessarily prevent the key's owner from accessing data@@ -535,30 +542,30 @@   data about past locations of files. The resulting branch will use less   space, but `git annex log` will not be able to show where   files used to be located.-  +   To also prune references to repositories that have been marked as dead,   specify `--drop-dead`.    When this rewritten branch is merged into other clones of   the repository, `git-annex` will automatically perform the same rewriting   to their local `git-annex` branches. So the forgetfulness will automatically-  propigate out from its starting point until all repositories running+  propagate out from its starting point until all repositories running   git-annex have forgotten their old history. (You may need to force   git to push the branch to any git repositories not running git-annex.)  * `repair` -  This can repair many of the problems with git repositories that `git fsck` +  This can repair many of the problems with git repositories that `git fsck`   detects, but does not itself fix. It's useful if a repository has become-  badly damaged. One way this can happen is if a repisitory used by git-annex+  badly damaged. One way this can happen is if a repository used by git-annex   is on a removable drive that gets unplugged at the wrong time.-  +   This command can actually be used inside git repositories that do not   use git-annex at all; when used in a repository using git-annex, it   does additional repairs of the git-annex branch.    It works by deleting any corrupt objects from the git repository, and-  retriving all missing objects it can from the remotes of the repository.+  retrieving all missing objects it can from the remotes of the repository.    If that is not sufficient to fully recover the repository, it can also   reset branches back to commits before the corruption happened, delete@@ -612,7 +619,7 @@   Displays the location log for the specified file or files,   showing each repository they were added to ("+") and removed from ("-"). -  To limit how far back to seach for location log changes, the options+  To limit how far back to search for location log changes, the options   `--since`, `--after`, `--until`, `--before`, and `--max-count` can be specified.   They are passed through to git log. For example, `--since "1 month ago"` @@ -1028,7 +1035,7 @@  When a repository is in one of the standard predefined groups, like "backup" and "client", setting its preferred content to "standard" will use a-built-in preferred content expression ddeveloped for that group.+built-in preferred content expression developed for that group.  # SCHEDULED JOBS @@ -1066,13 +1073,13 @@ * `annex.numcopies`    Number of copies of files to keep across all repositories. (default: 1)-  +   Note that setting numcopies to 0 is very unsafe.  * `annex.backends` -  Space-separated list of names of the key-value backends to use. -  The first listed is used to store new files by default. +  Space-separated list of names of the key-value backends to use.+  The first listed is used to store new files by default.  * `annex.diskreserve` @@ -1156,7 +1163,7 @@    Note that upgrade checking is only done when git-annex is installed   from one of the prebuilt images from its website. This does not-  bypass eg, a Linux distribution's own upgrade handling code.+  bypass e.g., a Linux distribution's own upgrade handling code.    This setting also controls whether to restart the git-annex assistant   when the git-annex binary is detected to have changed. That is useful
− doc/ikiwiki/pagespec.mdwn
@@ -1,86 +0,0 @@-[[!meta robots="noindex, follow"]]-To select a set of pages, such as pages that are locked, pages-whose commit emails you want subscribe to, or pages to combine into a-blog, the wiki uses a PageSpec. This is an expression that matches-a set of pages.--The simplest PageSpec is a simple list of pages. For example, this matches-any of the three listed pages:--	foo or bar or baz--More often you will want to match any pages that have a particular thing in-their name. You can do this using a glob pattern. "`*`" stands for any part-of a page name, and "`?`" for any single letter of a page name. So this-matches all pages about music, and any [[SubPage]]s of the SandBox, but does-not match the SandBox itself:--	*music* or SandBox/*--You can also prefix an item with "`!`" to skip pages that match it. So to-match all pages except for Discussion pages and the SandBox:--	* and !SandBox and !*/Discussion--Some more elaborate limits can be added to what matches using these functions:--* "`glob(someglob)`" - matches pages and other files that match the given glob.-  Just writing the glob by itself is actually a shorthand for this function.-* "`page(glob)`" - like `glob()`, but only matches pages, not other files-* "`link(page)`" - matches only pages that link to a given page (or glob)-* "`tagged(tag)`" - matches pages that are tagged or link to the given tag (or-  tags matched by a glob)-* "`backlink(page)`" - matches only pages that a given page links to-* "`creation_month(month)`" - matches only files created on the given month-  number-* "`creation_day(mday)`" - or day of the month-* "`creation_year(year)`" - or year-* "`created_after(page)`" - matches only files created after the given page-  was created-* "`created_before(page)`" - matches only files created before the given page-  was created-* "`internal(glob)`" - like `glob()`, but matches even internal-use -  pages that globs do not usually match.-* "`title(glob)`", "`author(glob)`", "`authorurl(glob)`",-  "`license(glob)`", "`copyright(glob)`", "`guid(glob)`" -  - match pages that have the given metadata, matching the specified glob.-* "`user(username)`" - tests whether a modification is being made by a-  user with the specified username. If openid is enabled, an openid can also-  be put here. Glob patterns can be used in the username. For example, -  to match all openid users, use `user(*://*)`-* "`admin()`" - tests whether a modification is being made by one of the-  wiki admins.-* "`ip(address)`" - tests whether a modification is being made from the-  specified IP address. Glob patterns can be used in the address. For-  example, `ip(127.0.0.*)`-* "`comment(glob)`" - matches comments to a page matching the glob.-* "`comment_pending(glob)`" - matches unmoderated, pending comments.-* "`postcomment(glob)`" - matches only when comments are being -  posted to a page matching the specified glob--For example, to match all pages in a blog that link to the page about music-and were written in 2005:--	blog/* and link(music) and creation_year(2005)--Note the use of "and" in the above example, that means that only pages that-match each of the three expressions match the whole. Use "and" when you-want to combine expression like that; "or" when it's enough for a page to-match one expression. Note that it doesn't make sense to say "index and-SandBox", since no page can match both expressions.--More complex expressions can also be created, by using parentheses for-grouping. For example, to match pages in a blog that are tagged with either-of two tags, use:--	blog/* and (tagged(foo) or tagged(bar))--Note that page names in PageSpecs are matched against the absolute-filenames of the pages in the wiki, so a pagespec "foo" used on page-"a/b" will not match a page named "a/foo" or "a/b/foo". To match-relative to the directory of the page containing the pagespec, you can-use "./". For example, "./foo" on page "a/b" matches page "a/foo".--To indicate the name of the page the PageSpec is used in, you can-use a single dot. For example, `link(.)` matches all the pages-linking to the page containing the PageSpec.
doc/install/Ubuntu.mdwn view
@@ -30,6 +30,11 @@ 	sudo apt-get update 	sudo apt-get install git-annex +If you don't have add-apt-repository installed run this command first:++	sudo apt-get install software-properties-common python-software-properties++ ## Oneiric  	sudo apt-get install git-annex
doc/install/Windows.mdwn view
@@ -5,8 +5,7 @@  This port is in an early state. While it works well enough to use git-annex, many things will not work. See [[todo/windows_support]] for-current status. Note especially that git-annex always uses [[direct_mode]]-on Windows.+current status.  The autobuilder is not currently able to run the test suite, so testing git-annex on Windows is up to you! To check that the build of@@ -25,10 +24,15 @@ ## building it yourself  To build git-annex from source on Windows, you need to install-the Haskell Platform, Mingw, and Cygwin. Use Cygwin to install-gcc, rsync, git, wget, ssh, and gnupg. To build the git-annex installer,-you also need to install the NulSoft installer system.+the Haskell Platform, Mingw, and Cygwin. Use Cygwin to install:+gcc rsync git wget ssh gnupg -There is a shell script `standalone/windows/build.sh` that can be-used to build git-annex. Note that this shell script cannot be run-in Cygwin; run it with the Mingw sh.+Once the prerequisites are installed, run:++	cabal update+	git clone git://git-annex.branchable.com/ gitannex+	cd gitannex+	build++(To build the git-annex installer, you also need to install the NulSoft+installer system.)
doc/install/fromscratch.mdwn view
@@ -65,6 +65,8 @@     (optional; recommended for watch mode)   * [gcrypt](https://github.com/joeyh/git-remote-gcrypt)     (optional)+  * [nocache](https://github.com/Feh/nocache)+    (optional)   * multicast DNS support, provided on linux by [nss-mdns](http://www.0pointer.de/lennart/projects/nss-mdns/)     (optional; recommended for the assistant to support pairing well)   * [ikiwiki](http://ikiwiki.info) (optional; used to build the docs)
− doc/news/version_4.20131106.mdwn
@@ -1,18 +0,0 @@-git-annex 4.20131106 released with [[!toggle text="these changes"]]-[[!toggleable text="""-   * Improve local pairing behavior when two computers both try to start-     the pairing process separately.-   * sync: Work even when the local git repository is new and empty,-     with no master branch.-   * gcrypt, bup: Fix bug that prevented using these special remotes-     with encryption=pubkey.-   * Fix enabling of gcrypt repository accessed over ssh;-     git-annex-shell gcryptsetup had a bug that caused it to fail-     with permission denied.-   * Fix zombie process that occurred when switching between repository-     views in the webapp.-   * map: Work when there are gcrypt remotes.-   * Fix build w/o webapp.-   * Fix exception handling bug that could cause .git/annex/index to be used-     for git commits outside the git-annex branch. Known to affect git-annex-     when used with the git shipped with Ubuntu 13.10."""]]
+ doc/news/version_5.20131213.mdwn view
@@ -0,0 +1,32 @@+git-annex 5.20131213 released with [[!toggle text="these changes"]]+[[!toggleable text="""+   * Avoid using git commit in direct mode, since in some situations+     it will read the full contents of files in the tree.+   * assistant: Batch jobs are now run with ionice and nocache, when+     those commands are available.+   * assistant: Run transferkeys as batch jobs.+   * Automatically fix up bad bare repositories created by+     versions 5.20131118 through 5.20131127.+   * rsync special remote: Fix fallback mode for rsync remotes that+     use hashDirMixed. Closes: #[731142](http://bugs.debian.org/731142)+   * copy --from, get --from: When --force is used, ignore the+     location log and always try to get the file from the remote.+   * Deal with box.com changing the url of their webdav endpoint.+   * Android: Fix SRV record lookups for XMPP to use android getprop+     command to find DNS server, since there is no resolv.conf.+   * import: Add --skip-duplicates option.+   * lock: Require --force. Closes: #[731606](http://bugs.debian.org/731606)+   * import: better handling of overwriting an existing file/directory/broken+     link when importing+   * Windows: assistant and webapp work! (very experimental)+   * Windows: Support annex.diskreserve.+   * Fix bad behavior in Firefox, which was caused by an earlier fix to+     bad behavior in Chromium.+   * repair: Improve repair of git-annex index file.+   * repair: Remove damaged git-annex sync branches.+   * status: Ignore new files that are gitignored.+   * Fix direct mode's handling when modifications to non-annexed files+     are pulled from a remote. A bug prevented the files from being updated+     in the work tree, and this caused the modification to be reverted.+   * OSX: Remove ssh and ssh-keygen from dmg as they're included in OSX by+     default."""]]
+ doc/not/comment_10_d8fb9add7e98dadea2a39f8827f75447._comment view
@@ -0,0 +1,10 @@+[[!comment format=mdwn+ username="http://joeyh.name/"+ ip="209.250.56.87"+ subject="comment 10"+ date="2013-12-11T15:40:35Z"+ content="""+@Zellyn, what you describe does not sound unreasonable. But it's hard to say if it's a backup. For example, if you delete a file from the archive folder, and that happened to be the only copy of the file, it's gone.++It's definitely possible to use git-annex in backup-like ways, but what I want to discourage is users thinking that just putting files into git-annex means that they have a backup. Proper backups need to be designed, and tested. It helps to use software that is explicitly designed as a backup solution. git-annex is more about file distribution, and some archiving, than backups.+"""]]
+ doc/not/comment_11_6c23aba5a9c341f2d5e2007e4b43f2ea._comment view
@@ -0,0 +1,8 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawkQafKy7hNSEolLs6TvbgUnkklTctUY9LI"+ nickname="Zellyn"+ subject="Backup"+ date="2013-12-11T17:38:39Z"+ content="""+@joeyh - ok, good to know. So as long as I realize I need to sync with my hard drives before deleting, it should work fine as a backup solution. Sweet!+"""]]
+ doc/not/comment_9_69aa47398a3c13ce64f146de985b727d._comment view
@@ -0,0 +1,10 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawkQafKy7hNSEolLs6TvbgUnkklTctUY9LI"+ nickname="Zellyn"+ subject="Not a backup system..."+ date="2013-12-10T20:55:05Z"+ content="""+I'd like to understand the \"not a backup system\" point better. My current plan was to use git annex assistant to save my annex folder onto two hard drives, one at home and one at work. Step two is to move most big stuff into .../archive/... folders, and step three is to add an annex folder on my wife's laptop, so we can use the hard drives to back up everything.++Does that sound unreasonable?+"""]]
+ doc/sync/comment_8_b89161c82c05634d35f6b65bf8360a96._comment view
@@ -0,0 +1,14 @@+[[!comment format=mdwn+ username="https://www.google.com/accounts/o8/id?id=AItOawkI9AR8BqG4RPw_Ov2lnDCJWMuM6WMRobQ"+ nickname="Dav"+ subject="Use case for not syncing to all remotes"+ date="2013-12-08T19:20:26Z"+ content="""+Just in case you haven't considered such a scenario - maybe you have suggestions for how to collaborate more effectively with git annex (and avoid warning messages):++I'm trying to teach beginning scientist programmers (mostly graduate students), and a common scenario is to fork some scientific code. I'd like forking on github to be mundane, and not trigger warnings, and generally have as little for folks to explicitly keep track of as possible (this seems to be a common concern we share, which leads you to prefer syncing to all remotes without the option to configure the default behavior!).++However, I am currently working with students on forking and fixing up scientific code where the upstream maintainer doesn't want to allow pushes upstream, except via pull request. So, part of our approach is to set up some common shared datasets in git annex (and these just end up in our fork). If we have an \"upstream\" remote, git annex will try to sync with it, and report an error.++So - that's why I'd like to be able to configure the deactivation of syncing to a defined branch (e.g., \"upstream\"). However, if you have other suggestions to smooth the workflow, I would also like to hear those!+"""]]
+ doc/sync/comment_9_849883b7cc05bfcb01914d8737098010._comment view
@@ -0,0 +1,18 @@+[[!comment format=mdwn+ username="http://joeyh.name/"+ ip="209.250.56.87"+ subject="comment 9"+ date="2013-12-12T17:54:55Z"+ content="""+@Dav what kind of url does the upstream remote have? Perhaps it would be sufficient to make sync skip trying to push to git:// and http[s]:// remotes. Both are unlikely to accept pushes and in the cases where they do accept pushes it would be fine to need a manual `git push`. ++Anyway, you can already configure which remotes get synced with. From the man page:++<pre>+       remote.&lt;name&gt;.annex-sync+              If set to false, prevents  git-annex  sync  (and  the  git-annex+              assistant) from syncing with this remote.+</pre>++So `git config remote.upstream.annex-sync=false`+"""]]
doc/tips/replacing_Sparkleshare_or_dvcs-autosync_with_the_assistant.mdwn view
@@ -24,10 +24,20 @@  	git config annex.largefiles "largerthan=100kb and not (include=*.c or include=*.h)" +----+ Now if you run `git annex add`, it will only add the large files to the annex. You can `git add` the small files directly to git. -Better, if you run `git annex assistant`, it will *automatically*+Note that in order to use `git add` on the small files, your repository+needs to be in indirect mode, rather than [[direct mode]]. If it's in+direct mode, `git add` will fail. You can fix that:++	git annex indirect++----++A less manual option is to run `git annex assistant`. It will *automatically* add the large files to the annex, and store the small files in git. It'll notice every time you modify a file, and immediately commit it, too. And sync it out to other repositories you configure using `git annex
+ doc/todo/Improve_direct_mode_using_copy_on_write.mdwn view
@@ -0,0 +1,42 @@+Direct mode is great because it removes symlinks. A must-have for directories like `~/Documents`. Unfortunately, it removes the possibility to use `git` commands other than `git-annex`. Also, it doen't preserve history of files.++I would be great to have a mode where:++- files are available in plain, not as sylinks+- the repository could still be trusted to hold version of some files from other repositories+- from a user point of view, the history of a file before the checkout would be preserved.++In feature rich file systems that have copy on write feature, it could be implemented by having the files in both places at the same time:++- the current version of a file would be in the working copy+- the file in the working copy would be a copy-on-write of the file in the annex repository+- when the file in the working copy changes, `git-annex` notices it and copy the file in the annex repository using copy-on-write semantic++If the file system do not support copy-on-write, it could be an option (do you want secure direct mode that takes twice the disk space or light direct mode that don't preserve the history of your files?)++This would make direct more much more robust.++copy on write is available using `cp --reflink=always`. It correspond to the following code ([coreutils src/copy.c line 224](http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/copy.c#n224)):++    /* Perform the O(1) btrfs clone operation, if possible.+       Upon success, return 0.  Otherwise, return -1 and set errno.  */+    static inline int+    clone_file (int dest_fd, int src_fd)+    {+    #ifdef __linux__+    # undef BTRFS_IOCTL_MAGIC+    # define BTRFS_IOCTL_MAGIC 0x94+    # undef BTRFS_IOC_CLONE+    # define BTRFS_IOC_CLONE _IOW (BTRFS_IOCTL_MAGIC, 9, int)+      return ioctl (dest_fd, BTRFS_IOC_CLONE, src_fd);+    #else+      (void) dest_fd;+      (void) src_fd;+      errno = ENOTSUP;+      return -1;+    #endif+    }++Looking at the code it would be preferable to exec directly to `cp`, see [copy_range() on LWN](http://lwn.net/Articles/550621/) and this [more recent article about splice() on LWN](http://lwn.net/Articles/567086/)++Also, `cp --reflink` fall back to copy when copy-on-write is not available while `cp --reflink=always` do not.
doc/todo/dumb_plaindir_remote___40__e.g._for_NAS_mounts__41__.mdwn view
@@ -3,3 +3,5 @@ I tried to put a direct-mode repo on the drive but this is painfully slow. The git-annex process than runs on my desktop and accesses the repo over SMB over the slow fritzbox over USB.  I'd wish that git-annex could be told to just use a (mounted) folder as a direct-mode remote.++> [[done]]; dup. --[[Joey]] 
doc/todo/windows_support.mdwn view
@@ -5,19 +5,34 @@  * Does not work with Cygwin's build of git (that git does not consistently   support use of DOS style paths, which git-annex uses on Windows). -  Must use the upstream build of git for Windows.+  Must use Msysgit. * rsync special remotes are known buggy. * Bad file locking, it's probably not safe to run more than one git-annex   process at the same time on Windows. * Ssh connection caching does not work on Windows, so `git annex get`   has to connect twice to the remote system over ssh per file, which   is much slower than on systems supporting connection caching.-* Webapp doesn't build yet.-* `git annex watch` builds, but does not quite work.-* `git annex assistant` builds, but has not been tested, and is known-  to not download any files. (transferrer doesn't built yet)-* watch and assistant cannot be built with cabal. Possibly due to too many-  files overflowing command line length limit at link stage.-  To build a binary with them: -  `ghc --make git-annex.hs -threaded -XPackageImports -DWITH_ASSISTANT=1 -DWITH_WIN32NOTIFY=1`-  (should add all the other flags cabal uses)+* `git annex watch` works, but does not detect when files are still open+  for write as they're being added (no lsof). So watch/webapp/assistant+  may be unsafe.+* `git annex assistant` has not been tested, is probably quite incomplete+  and/or buggy.+* Doesn't daemonize. Maybe use+  <http://hackage.haskell.org/package/Win32-services>+  or perhaps easier,+  <http://hackage.haskell.org/package/Win32-services-wrapper>+* XMPP library not yet built.+  +  This should work to install the deps, using libs from cygwin++	cabal install libxml-sax --extra-lib-dirs=C:\\cygwin\\lib --extra-include-dirs=C:\\cygwin\\usr\\include\\libxml2+	cabal install gnuidn --extra-lib-dirs=C:\\cygwin\\lib --extra-include-dirs=C:\\cygwin\\usr\\include\\+	cabal install gnutls --extra-lib-dirs=C:\\cygwin\\lib --extra-include-dirs=C:\\cygwin\\usr\\include\\++  While the 1st line works, the rest fail oddly. Looks like lack of+  quoting when cabal runs c2hs and gcc, as "Haskell Platform" is+  taken as 2 filenames. Needs investigation why this happens here+  and not other times..++  Also needs gsasl, which is not in cygwin. +  See <http://josefsson.org/gsasl4win/README.html>
git-annex.1 view
@@ -92,8 +92,12 @@ When used with the \fB\-\-to\fP option, copies the content of annexed files from the current repository to the specified one. .IP-To avoid contacting the remote to check if it has every file, specify \fB\-\-fast\fP+To avoid contacting the remote to check if it has every file+when copying \-\-to the repository, specify \fB\-\-fast\fP .IP+To force checking the remote for every file when copying \-\-from the+repository, specify \fB\-\-force\fP.+.IP .IP "\fBstatus\fP [path ...]" Similar to \fBgit status \-\-short\fP, displays the status of the files in the working tree. Shows files that are not checked into git, files that@@ -117,7 +121,7 @@ .IP .IP "\fBsync [remote ...]\fP" Use this command when you want to synchronize the local repository with-one or more of its remotes. You can specifiy the remotes to sync with;+one or more of its remotes. You can specify the remotes to sync with; the default is to sync with all remotes. Or specify \fB\-\-fast\fP to sync with the remotes with the lowest annex\-cost value. .IP@@ -161,7 +165,7 @@ repository. If a file's content is present in the source repository, it is copied to the destination repository. If a file's content is not present in the source repository, it will be dropped from the destination repository-when possible. +when possible. .IP Note that mirror does not sync the git repository, but only the file contents.@@ -213,6 +217,9 @@ use the \fB\-\-deduplicate\fP option. Duplicate files will be deleted from the import location. .IP+To only import files whose content has not been seen before by git\-annex,+but avoid deleting duplicate files, use the \fB\-\-skip\-duplicates\fP option.+.IP The \fB\-\-clean\-duplicates\fP option does not import any new files, but any files found in the import location that are duplicates of content in the annex are deleted.@@ -274,7 +281,7 @@ .IP "\fBinit [description]\fP" .IP Until a repository (or one of its remotes) has been initialized,-git\-annex will refuse to operate on it, to avoid accidentially+git\-annex will refuse to operate on it, to avoid accidentally using it in a repository that was not intended to have an annex. .IP It's useful, but not mandatory, to initialize each new clone@@ -296,23 +303,23 @@ command will prompt for parameters as needed. .IP All special remotes support encryption. You can either specify-\fBencryption=none\fP to disable encryption, or specify -\fBencryption=hybrid keyid=$keyid ...\fP to specify a gpg key id (or an email+\fBencryption=none\fP to disable encryption, or specify+\fBencryption=hybrid keyid=$keyid ...\fP to specify a GPG key id (or an email address associated with a key.) .IP There are actually three schemes that can be used for management of the encryption keys. When using the encryption=hybrid scheme, additional-gpg keys can be given access to the encrypted special remote easily+GPG keys can be given access to the encrypted special remote easily (without re\-encrypting everything). When using encryption=shared, a shared key is generated and stored in the git repository, allowing anyone who can clone the git repository to access it. Finally, when using encryption=pubkey, content in the special remote is directly encrypted-to the specified gpg keys, and additional ones cannot easily be given+to the specified GPG keys, and additional ones cannot easily be given access. .IP Note that with encryption enabled, a cryptographic key is created. This requires sufficient entropy. If initremote seems to hang or take-a long time while generating the key, you may want to ctrl\-c it and+a long time while generating the key, you may want to Ctrl\-c it and re\-run with \fB\-\-fast\fP, which causes it to use a lower\-quality source of randomness. .IP@@ -323,7 +330,7 @@ .IP "\fBenableremote name [param=value ...]\fP" Enables use of an existing special remote in the current repository, which may be a different repository than the one in which it was-originally created with the initremote command. +originally created with the initremote command. .IP The name of the remote is the same name used when origianlly  creating that remote with "initremote". Run "git annex enableremote"@@ -338,7 +345,7 @@ the as the encryption scheme cannot be changed once a special remote has been created.) .IP-The gpg keys that an encrypted special remote is encrypted to can be+The GPG keys that an encrypted special remote is encrypted to can be changed using the keyid+= and keyid\-= parameters. These respectively add and remove keys from the list. However, note that removing a key does NOT necessarily prevent the key's owner from accessing data@@ -497,14 +504,14 @@ When this rewritten branch is merged into other clones of the repository, \fBgit\-annex\fP will automatically perform the same rewriting to their local \fBgit\-annex\fP branches. So the forgetfulness will automatically-propigate out from its starting point until all repositories running+propagate out from its starting point until all repositories running git\-annex have forgotten their old history. (You may need to force git to push the branch to any git repositories not running git\-annex.) .IP .IP "\fBrepair\fP"-This can repair many of the problems with git repositories that \fBgit fsck\fP +This can repair many of the problems with git repositories that \fBgit fsck\fP detects, but does not itself fix. It's useful if a repository has become-badly damaged. One way this can happen is if a repisitory used by git\-annex+badly damaged. One way this can happen is if a repository used by git\-annex is on a removable drive that gets unplugged at the wrong time. .IP This command can actually be used inside git repositories that do not@@ -512,7 +519,7 @@ does additional repairs of the git\-annex branch. .IP It works by deleting any corrupt objects from the git repository, and-retriving all missing objects it can from the remotes of the repository.+retrieving all missing objects it can from the remotes of the repository. .IP If that is not sufficient to fully recover the repository, it can also reset branches back to commits before the corruption happened, delete@@ -562,7 +569,7 @@ Displays the location log for the specified file or files, showing each repository they were added to ("+") and removed from ("\-"). .IP-To limit how far back to seach for location log changes, the options+To limit how far back to search for location log changes, the options \fB\-\-since\fP, \fB\-\-after\fP, \fB\-\-until\fP, \fB\-\-before\fP, and \fB\-\-max\-count\fP can be specified. They are passed through to git log. For example, \fB\-\-since "1 month ago"\fP .IP@@ -926,7 +933,7 @@ .PP When a repository is in one of the standard predefined groups, like "backup" and "client", setting its preferred content to "standard" will use a-built\-in preferred content expression ddeveloped for that group.+built\-in preferred content expression developed for that group. .PP .SH SCHEDULED JOBS The git\-annex assistant daemon can be configured to run scheduled jobs.@@ -964,8 +971,8 @@ Note that setting numcopies to 0 is very unsafe. .IP .IP "\fBannex.backends\fP"-Space\-separated list of names of the key\-value backends to use. -The first listed is used to store new files by default. +Space\-separated list of names of the key\-value backends to use.+The first listed is used to store new files by default. .IP .IP "\fBannex.diskreserve\fP" Amount of disk space to reserve. Disk space is checked when transferring@@ -1039,7 +1046,7 @@ .IP Note that upgrade checking is only done when git\-annex is installed from one of the prebuilt images from its website. This does not-bypass eg, a Linux distribution's own upgrade handling code.+bypass e.g., a Linux distribution's own upgrade handling code. .IP This setting also controls whether to restart the git\-annex assistant when the git\-annex binary is detected to have changed. That is useful
git-annex.cabal view
@@ -1,5 +1,5 @@ Name: git-annex-Version: 5.20131130+Version: 5.20131213 Cabal-Version: >= 1.8 License: GPL-3 Maintainer: Joey Hess <joey@kitenet.net>@@ -91,13 +91,8 @@    base (>= 4.5 && < 4.9), monad-control, MonadCatchIO-transformers,    IfElse, text, QuickCheck >= 2.1, bloomfilter, edit-distance, process,    SafeSemaphore, uuid, random, dlist, unix-compat, async-  -- Need to list these because they're generated from .hsc files.-  Other-Modules: Utility.Touch Utility.Mounts-  Include-Dirs: Utility-  C-Sources: Utility/libdiskfree.c Utility/libmounts.c   CC-Options: -Wall   GHC-Options: -Wall-  CPP-Options: -DWITH_CLIBS   Extensions: PackageImports   -- Some things don't work with the non-threaded RTS.   GHC-Options: -threaded@@ -105,8 +100,15 @@   if flag(Production)     GHC-Options: -O2 -  if (! os(windows))+  if (os(windows))+    Build-Depends: Win32, Win32-extras+  else     Build-Depends: unix+    -- Need to list these because they're generated from .hsc files.+    Other-Modules: Utility.Touch Utility.Mounts+    Include-Dirs: Utility+    C-Sources: Utility/libdiskfree.c Utility/libmounts.c+    CPP-Options: -DWITH_CLIBS    if flag(TestSuite)     Build-Depends: tasty, tasty-hunit, tasty-quickcheck@@ -163,12 +165,12 @@   if flag(AndroidSplice)     CPP-Options: -DANDROID_SPLICES -  if flag(Webapp) && (! os(windows))+  if flag(Webapp)     Build-Depends:      yesod, yesod-default, yesod-static, yesod-form, yesod-core,      case-insensitive, http-types, transformers, wai, wai-logger, warp,      blaze-builder, crypto-api, hamlet, clientsession,-     template-haskell, data-default, aeson+     template-haskell, data-default, aeson, network-conduit     CPP-Options: -DWITH_WEBAPP    if flag(Pairing)
standalone/android/install-haskell-packages view
@@ -98,6 +98,7 @@ 	patched DAV 	patched language-javascript 	patched uuid+	patched dns  	cd .. 
+ standalone/windows/build-simple.sh view
@@ -0,0 +1,43 @@+#!/bin/sh+# Script to build git-annex on windows. Run by build.bat+# Does not currently build the NSIS installer. See build.sh for how to do+# that.++set -e+set -x++# Path to the Haskell Platform.+HP="/c/Program Files/Haskell Platform/2013.2.0.0"++PATH="$HP/bin:$HP/lib/extralibs/bin:$PATH"++# Run a command with the cygwin environment available.+# However, programs not from cygwin are preferred.+withcyg () {+	PATH="$PATH:/c/cygwin/bin" "$@"+}+withcygpreferred () {+	PATH="/c/cygwin/bin:$PATH" "$@"+}++# Install haskell dependencies.+# cabal install is not run in cygwin, because we don't want configure scripts+# for haskell libraries to link them with the cygwin library.+cabal install --only-dependencies || true++# Build git-annex+if [ ! -e "dist/setup-config" ]; then+	withcyg cabal configure+fi+if ! withcyg cabal build; then+	ghc --make Build/EvilLinker+	withcyg Build/EvilLinker+fi++# Build the installer+cabal install nsis+ghc --make Build/NullSoftInstaller.hs+PATH="$PATH:/cygdrive/c/Program Files/NSIS"+# Want to include cygwin programs in bundle, not others, since+# it includes the cygwin libs that go with them.+withcygpreferred Build/NullSoftInstaller.exe
standalone/windows/build.sh view
@@ -6,29 +6,36 @@ set -x set -e -HP="/c/Program Files (x86)/Haskell Platform/2012.4.0.0"-FLAGS="-Webapp -Assistant -XMPP"--PATH="$HP/bin:$HP/lib/extralibs/bin:/c/Program Files (x86)/NSIS:$PATH"+# Path to the Haskell Platform.+HP="/c/Program Files (x86)/Haskell Platform/2013.2.0.0" -UPGRADE_LOCATION=http://downloads.kitenet.net/git-annex/windows/current/git-annex-installer.exe+PATH="$HP/bin:$HP/lib/extralibs/bin:/c/Program Files (x86)/NSIS:/c/msysgit/cmd:/c/msysgit/bin:$PATH"  # Run a command with the cygwin environment available. # However, programs not from cygwin are preferred. withcyg () { 	PATH="$PATH:/c/cygwin/bin" "$@" }+withcygpreferred () {+	PATH="/c/cygwin/bin:$PATH" "$@"+} +# This tells git-annex where to upgrade itself from.+UPGRADE_LOCATION=http://downloads.kitenet.net/git-annex/windows/current/git-annex-installer.exe++# Uncomment to get rid of cabal installed libraries.+#rm -rf /c/Users/jenkins/AppData/Roaming/cabal /c/Users/jenkins/AppData/Roaming/ghc+ # Don't allow build artifact from a past successful build to be extracted # if we fail.-rm -f git-annex-installer.exe+#rm -f git-annex-installer.exe  # Install haskell dependencies. # cabal install is not run in cygwin, because we don't want configure scripts # for haskell libraries to link them with the cygwin library. cabal update || true -cabal install --only-dependencies -f"$FLAGS"+cabal install --only-dependencies || true  # Detect when the last build was an incremental build and failed,  # and try a full build. Done this way because this shell seems a bit@@ -41,16 +48,23 @@ touch last-incremental-failed  # Build git-annex-withcyg cabal configure -f"$FLAGS"-withcyg cabal build-	+withcyg cabal configure+if ! withcyg cabal build; then+	rm -f Build/EvilLinker.exe+	ghc --make Build/EvilLinker+	Build/EvilLinker+fi+ # Build the installer cabal install nsis ghc --make Build/NullSoftInstaller.hs-withcyg Build/NullSoftInstaller.exe+# Want to include cygwin programs in bundle, not others, since+# it includes the cygwin libs that go with them.+withcygpreferred Build/NullSoftInstaller.exe  rm -f last-incremental-failed  # Test git-annex+# (doesn't currently work well on autobuilder, reason unknown) rm -rf .t withcyg dist/build/git-annex/git-annex.exe test || true
+ static/bootstrap-collapse.js view
@@ -0,0 +1,138 @@+/* =============================================================+ * bootstrap-collapse.js v2.0.2+ * http://twitter.github.com/bootstrap/javascript.html#collapse+ * =============================================================+ * Copyright 2012 Twitter, Inc.+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * http://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ * ============================================================ */++!function( $ ){++  "use strict"++  var Collapse = function ( element, options ) {+  	this.$element = $(element)+    this.options = $.extend({}, $.fn.collapse.defaults, options)++    if (this.options["parent"]) {+      this.$parent = $(this.options["parent"])+    }++    this.options.toggle && this.toggle()+  }++  Collapse.prototype = {++    constructor: Collapse++  , dimension: function () {+      var hasWidth = this.$element.hasClass('width')+      return hasWidth ? 'width' : 'height'+    }++  , show: function () {+      var dimension = this.dimension()+        , scroll = $.camelCase(['scroll', dimension].join('-'))+        , actives = this.$parent && this.$parent.find('.in')+        , hasData++      if (actives && actives.length) {+        hasData = actives.data('collapse')+        actives.collapse('hide')+        hasData || actives.data('collapse', null)+      }++      this.$element[dimension](0)+      this.transition('addClass', 'show', 'shown')+      this.$element[dimension](this.$element[0][scroll])++    }++  , hide: function () {+      var dimension = this.dimension()+      this.reset(this.$element[dimension]())+      this.transition('removeClass', 'hide', 'hidden')+      this.$element[dimension](0)+    }++  , reset: function ( size ) {+      var dimension = this.dimension()++      this.$element+        .removeClass('collapse')+        [dimension](size || 'auto')+        [0].offsetWidth++      this.$element[size ? 'addClass' : 'removeClass']('collapse')++      return this+    }++  , transition: function ( method, startEvent, completeEvent ) {+      var that = this+        , complete = function () {+            if (startEvent == 'show') that.reset()+            that.$element.trigger(completeEvent)+          }++      this.$element+        .trigger(startEvent)+        [method]('in')++      $.support.transition && this.$element.hasClass('collapse') ?+        this.$element.one($.support.transition.end, complete) :+        complete()+  	}++  , toggle: function () {+      this[this.$element.hasClass('in') ? 'hide' : 'show']()+  	}++  }++  /* COLLAPSIBLE PLUGIN DEFINITION+  * ============================== */++  $.fn.collapse = function ( option ) {+    return this.each(function () {+      var $this = $(this)+        , data = $this.data('collapse')+        , options = typeof option == 'object' && option+      if (!data) $this.data('collapse', (data = new Collapse(this, options)))+      if (typeof option == 'string') data[option]()+    })+  }++  $.fn.collapse.defaults = {+    toggle: true+  }++  $.fn.collapse.Constructor = Collapse+++ /* COLLAPSIBLE DATA-API+  * ==================== */++  $(function () {+    $('body').on('click.collapse.data-api', '[data-toggle=collapse]', function ( e ) {+      var $this = $(this), href+        , target = $this.attr('data-target')+          || e.preventDefault()+          || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7+        , option = $(target).data('collapse') ? 'toggle' : $this.data()+      $(target).collapse(option)+    })+  })++}( window.jQuery );
+ static/bootstrap-dropdown.js view
@@ -0,0 +1,92 @@+/* ============================================================+ * bootstrap-dropdown.js v2.0.2+ * http://twitter.github.com/bootstrap/javascript.html#dropdowns+ * ============================================================+ * Copyright 2012 Twitter, Inc.+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * http://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ * ============================================================ */+++!function( $ ){++  "use strict"++ /* DROPDOWN CLASS DEFINITION+  * ========================= */++  var toggle = '[data-toggle="dropdown"]'+    , Dropdown = function ( element ) {+        var $el = $(element).on('click.dropdown.data-api', this.toggle)+        $('html').on('click.dropdown.data-api', function () {+          $el.parent().removeClass('open')+        })+      }++  Dropdown.prototype = {++    constructor: Dropdown++  , toggle: function ( e ) {+      var $this = $(this)+        , selector = $this.attr('data-target')+        , $parent+        , isActive++      if (!selector) {+        selector = $this.attr('href')+        selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7+      }++      $parent = $(selector)+      $parent.length || ($parent = $this.parent())++      isActive = $parent.hasClass('open')++      clearMenus()+      !isActive && $parent.toggleClass('open')++      return false+    }++  }++  function clearMenus() {+    $(toggle).parent().removeClass('open')+  }+++  /* DROPDOWN PLUGIN DEFINITION+   * ========================== */++  $.fn.dropdown = function ( option ) {+    return this.each(function () {+      var $this = $(this)+        , data = $this.data('dropdown')+      if (!data) $this.data('dropdown', (data = new Dropdown(this)))+      if (typeof option == 'string') data[option].call($this)+    })+  }++  $.fn.dropdown.Constructor = Dropdown+++  /* APPLY TO STANDARD DROPDOWN ELEMENTS+   * =================================== */++  $(function () {+    $('html').on('click.dropdown.data-api', clearMenus)+    $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle)+  })++}( window.jQuery );
+ static/bootstrap-modal.js view
@@ -0,0 +1,210 @@+/* =========================================================+ * bootstrap-modal.js v2.0.2+ * http://twitter.github.com/bootstrap/javascript.html#modals+ * =========================================================+ * Copyright 2012 Twitter, Inc.+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * http://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ * ========================================================= */+++!function( $ ){++  "use strict"++ /* MODAL CLASS DEFINITION+  * ====================== */++  var Modal = function ( content, options ) {+    this.options = options+    this.$element = $(content)+      .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))+  }++  Modal.prototype = {++      constructor: Modal++    , toggle: function () {+        return this[!this.isShown ? 'show' : 'hide']()+      }++    , show: function () {+        var that = this++        if (this.isShown) return++        $('body').addClass('modal-open')++        this.isShown = true+        this.$element.trigger('show')++        escape.call(this)+        backdrop.call(this, function () {+          var transition = $.support.transition && that.$element.hasClass('fade')++          !that.$element.parent().length && that.$element.appendTo(document.body) //don't move modals dom position++          that.$element+            .show()++          if (transition) {+            that.$element[0].offsetWidth // force reflow+          }++          that.$element.addClass('in')++          transition ?+            that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :+            that.$element.trigger('shown')++        })+      }++    , hide: function ( e ) {+        e && e.preventDefault()++        if (!this.isShown) return++        var that = this+        this.isShown = false++        $('body').removeClass('modal-open')++        escape.call(this)++        this.$element+          .trigger('hide')+          .removeClass('in')++        $.support.transition && this.$element.hasClass('fade') ?+          hideWithTransition.call(this) :+          hideModal.call(this)+      }++  }+++ /* MODAL PRIVATE METHODS+  * ===================== */++  function hideWithTransition() {+    var that = this+      , timeout = setTimeout(function () {+          that.$element.off($.support.transition.end)+          hideModal.call(that)+        }, 500)++    this.$element.one($.support.transition.end, function () {+      clearTimeout(timeout)+      hideModal.call(that)+    })+  }++  function hideModal( that ) {+    this.$element+      .hide()+      .trigger('hidden')++    backdrop.call(this)+  }++  function backdrop( callback ) {+    var that = this+      , animate = this.$element.hasClass('fade') ? 'fade' : ''++    if (this.isShown && this.options.backdrop) {+      var doAnimate = $.support.transition && animate++      this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')+        .appendTo(document.body)++      if (this.options.backdrop != 'static') {+        this.$backdrop.click($.proxy(this.hide, this))+      }++      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow++      this.$backdrop.addClass('in')++      doAnimate ?+        this.$backdrop.one($.support.transition.end, callback) :+        callback()++    } else if (!this.isShown && this.$backdrop) {+      this.$backdrop.removeClass('in')++      $.support.transition && this.$element.hasClass('fade')?+        this.$backdrop.one($.support.transition.end, $.proxy(removeBackdrop, this)) :+        removeBackdrop.call(this)++    } else if (callback) {+      callback()+    }+  }++  function removeBackdrop() {+    this.$backdrop.remove()+    this.$backdrop = null+  }++  function escape() {+    var that = this+    if (this.isShown && this.options.keyboard) {+      $(document).on('keyup.dismiss.modal', function ( e ) {+        e.which == 27 && that.hide()+      })+    } else if (!this.isShown) {+      $(document).off('keyup.dismiss.modal')+    }+  }+++ /* MODAL PLUGIN DEFINITION+  * ======================= */++  $.fn.modal = function ( option ) {+    return this.each(function () {+      var $this = $(this)+        , data = $this.data('modal')+        , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)+      if (!data) $this.data('modal', (data = new Modal(this, options)))+      if (typeof option == 'string') data[option]()+      else if (options.show) data.show()+    })+  }++  $.fn.modal.defaults = {+      backdrop: true+    , keyboard: true+    , show: true+  }++  $.fn.modal.Constructor = Modal+++ /* MODAL DATA-API+  * ============== */++  $(function () {+    $('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {+      var $this = $(this), href+        , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7+        , option = $target.data('modal') ? 'toggle' : $.extend({}, $target.data(), $this.data())++      e.preventDefault()+      $target.modal(option)+    })+  })++}( window.jQuery );
+ static/bootstrap-responsive.css view
@@ -0,0 +1,815 @@+/*!+ * Bootstrap Responsive v2.0.4+ *+ * Copyright 2012 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 @twitter by @mdo and @fat.+ */++.clearfix {+  *zoom: 1;+}++.clearfix:before,+.clearfix:after {+  display: table;+  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: 28px;+  -webkit-box-sizing: border-box;+     -moz-box-sizing: border-box;+      -ms-box-sizing: border-box;+          box-sizing: border-box;+}++.hidden {+  display: none;+  visibility: hidden;+}++.visible-phone {+  display: none !important;+}++.visible-tablet {+  display: none !important;+}++.hidden-desktop {+  display: none !important;+}++@media (max-width: 767px) {+  .visible-phone {+    display: inherit !important;+  }+  .hidden-phone {+    display: none !important;+  }+  .hidden-desktop {+    display: inherit !important;+  }+  .visible-desktop {+    display: none !important;+  }+}++@media (min-width: 768px) and (max-width: 979px) {+  .visible-tablet {+    display: inherit !important;+  }+  .hidden-tablet {+    display: none !important;+  }+  .hidden-desktop {+    display: inherit !important;+  }+  .visible-desktop {+    display: none !important ;+  }+}++@media (max-width: 480px) {+  .nav-collapse {+    -webkit-transform: translate3d(0, 0, 0);+  }+  .page-header h1 small {+    display: block;+    line-height: 18px;+  }+  input[type="checkbox"],+  input[type="radio"] {+    border: 1px solid #ccc;+  }+  .form-horizontal .control-group > label {+    float: none;+    width: auto;+    padding-top: 0;+    text-align: left;+  }+  .form-horizontal .controls {+    margin-left: 0;+  }+  .form-horizontal .control-list {+    padding-top: 0;+  }+  .form-horizontal .form-actions {+    padding-right: 10px;+    padding-left: 10px;+  }+  .modal {+    position: absolute;+    top: 10px;+    right: 10px;+    left: 10px;+    width: auto;+    margin: 0;+  }+  .modal.fade.in {+    top: auto;+  }+  .modal-header .close {+    padding: 10px;+    margin: -10px;+  }+  .carousel-caption {+    position: static;+  }+}++@media (max-width: 767px) {+  body {+    padding-right: 20px;+    padding-left: 20px;+  }+  .navbar-fixed-top,+  .navbar-fixed-bottom {+    margin-right: -20px;+    margin-left: -20px;+  }+  .container-fluid {+    padding: 0;+  }+  .dl-horizontal dt {+    float: none;+    width: auto;+    clear: none;+    text-align: left;+  }+  .dl-horizontal dd {+    margin-left: 0;+  }+  .container {+    width: auto;+  }+  .row-fluid {+    width: 100%;+  }+  .row,+  .thumbnails {+    margin-left: 0;+  }+  [class*="span"],+  .row-fluid [class*="span"] {+    display: block;+    float: none;+    width: auto;+    margin-left: 0;+  }+  .input-large,+  .input-xlarge,+  .input-xxlarge,+  input[class*="span"],+  select[class*="span"],+  textarea[class*="span"],+  .uneditable-input {+    display: block;+    width: 100%;+    min-height: 28px;+    -webkit-box-sizing: border-box;+       -moz-box-sizing: border-box;+        -ms-box-sizing: border-box;+            box-sizing: border-box;+  }+  .input-prepend input,+  .input-append input,+  .input-prepend input[class*="span"],+  .input-append input[class*="span"] {+    display: inline-block;+    width: auto;+  }+}++@media (min-width: 768px) and (max-width: 979px) {+  .row {+    margin-left: -20px;+    *zoom: 1;+  }+  .row:before,+  .row:after {+    display: table;+    content: "";+  }+  .row:after {+    clear: both;+  }+  [class*="span"] {+    float: left;+    margin-left: 20px;+  }+  .container,+  .navbar-fixed-top .container,+  .navbar-fixed-bottom .container {+    width: 724px;+  }+  .span12 {+    width: 724px;+  }+  .span11 {+    width: 662px;+  }+  .span10 {+    width: 600px;+  }+  .span9 {+    width: 538px;+  }+  .span8 {+    width: 476px;+  }+  .span7 {+    width: 414px;+  }+  .span6 {+    width: 352px;+  }+  .span5 {+    width: 290px;+  }+  .span4 {+    width: 228px;+  }+  .span3 {+    width: 166px;+  }+  .span2 {+    width: 104px;+  }+  .span1 {+    width: 42px;+  }+  .offset12 {+    margin-left: 764px;+  }+  .offset11 {+    margin-left: 702px;+  }+  .offset10 {+    margin-left: 640px;+  }+  .offset9 {+    margin-left: 578px;+  }+  .offset8 {+    margin-left: 516px;+  }+  .offset7 {+    margin-left: 454px;+  }+  .offset6 {+    margin-left: 392px;+  }+  .offset5 {+    margin-left: 330px;+  }+  .offset4 {+    margin-left: 268px;+  }+  .offset3 {+    margin-left: 206px;+  }+  .offset2 {+    margin-left: 144px;+  }+  .offset1 {+    margin-left: 82px;+  }+  .row-fluid {+    width: 100%;+    *zoom: 1;+  }+  .row-fluid:before,+  .row-fluid:after {+    display: table;+    content: "";+  }+  .row-fluid:after {+    clear: both;+  }+  .row-fluid [class*="span"] {+    display: block;+    float: left;+    width: 100%;+    min-height: 28px;+    margin-left: 2.762430939%;+    *margin-left: 2.709239449638298%;+    -webkit-box-sizing: border-box;+       -moz-box-sizing: border-box;+        -ms-box-sizing: border-box;+            box-sizing: border-box;+  }+  .row-fluid [class*="span"]:first-child {+    margin-left: 0;+  }+  .row-fluid .span12 {+    width: 99.999999993%;+    *width: 99.9468085036383%;+  }+  .row-fluid .span11 {+    width: 91.436464082%;+    *width: 91.38327259263829%;+  }+  .row-fluid .span10 {+    width: 82.87292817100001%;+    *width: 82.8197366816383%;+  }+  .row-fluid .span9 {+    width: 74.30939226%;+    *width: 74.25620077063829%;+  }+  .row-fluid .span8 {+    width: 65.74585634900001%;+    *width: 65.6926648596383%;+  }+  .row-fluid .span7 {+    width: 57.182320438000005%;+    *width: 57.129128948638304%;+  }+  .row-fluid .span6 {+    width: 48.618784527%;+    *width: 48.5655930376383%;+  }+  .row-fluid .span5 {+    width: 40.055248616%;+    *width: 40.0020571266383%;+  }+  .row-fluid .span4 {+    width: 31.491712705%;+    *width: 31.4385212156383%;+  }+  .row-fluid .span3 {+    width: 22.928176794%;+    *width: 22.874985304638297%;+  }+  .row-fluid .span2 {+    width: 14.364640883%;+    *width: 14.311449393638298%;+  }+  .row-fluid .span1 {+    width: 5.801104972%;+    *width: 5.747913482638298%;+  }+  input,+  textarea,+  .uneditable-input {+    margin-left: 0;+  }+  input.span12,+  textarea.span12,+  .uneditable-input.span12 {+    width: 714px;+  }+  input.span11,+  textarea.span11,+  .uneditable-input.span11 {+    width: 652px;+  }+  input.span10,+  textarea.span10,+  .uneditable-input.span10 {+    width: 590px;+  }+  input.span9,+  textarea.span9,+  .uneditable-input.span9 {+    width: 528px;+  }+  input.span8,+  textarea.span8,+  .uneditable-input.span8 {+    width: 466px;+  }+  input.span7,+  textarea.span7,+  .uneditable-input.span7 {+    width: 404px;+  }+  input.span6,+  textarea.span6,+  .uneditable-input.span6 {+    width: 342px;+  }+  input.span5,+  textarea.span5,+  .uneditable-input.span5 {+    width: 280px;+  }+  input.span4,+  textarea.span4,+  .uneditable-input.span4 {+    width: 218px;+  }+  input.span3,+  textarea.span3,+  .uneditable-input.span3 {+    width: 156px;+  }+  input.span2,+  textarea.span2,+  .uneditable-input.span2 {+    width: 94px;+  }+  input.span1,+  textarea.span1,+  .uneditable-input.span1 {+    width: 32px;+  }+}++@media (min-width: 1200px) {+  .row {+    margin-left: -30px;+    *zoom: 1;+  }+  .row:before,+  .row:after {+    display: table;+    content: "";+  }+  .row:after {+    clear: both;+  }+  [class*="span"] {+    float: left;+    margin-left: 30px;+  }+  .container,+  .navbar-fixed-top .container,+  .navbar-fixed-bottom .container {+    width: 1170px;+  }+  .span12 {+    width: 1170px;+  }+  .span11 {+    width: 1070px;+  }+  .span10 {+    width: 970px;+  }+  .span9 {+    width: 870px;+  }+  .span8 {+    width: 770px;+  }+  .span7 {+    width: 670px;+  }+  .span6 {+    width: 570px;+  }+  .span5 {+    width: 470px;+  }+  .span4 {+    width: 370px;+  }+  .span3 {+    width: 270px;+  }+  .span2 {+    width: 170px;+  }+  .span1 {+    width: 70px;+  }+  .offset12 {+    margin-left: 1230px;+  }+  .offset11 {+    margin-left: 1130px;+  }+  .offset10 {+    margin-left: 1030px;+  }+  .offset9 {+    margin-left: 930px;+  }+  .offset8 {+    margin-left: 830px;+  }+  .offset7 {+    margin-left: 730px;+  }+  .offset6 {+    margin-left: 630px;+  }+  .offset5 {+    margin-left: 530px;+  }+  .offset4 {+    margin-left: 430px;+  }+  .offset3 {+    margin-left: 330px;+  }+  .offset2 {+    margin-left: 230px;+  }+  .offset1 {+    margin-left: 130px;+  }+  .row-fluid {+    width: 100%;+    *zoom: 1;+  }+  .row-fluid:before,+  .row-fluid:after {+    display: table;+    content: "";+  }+  .row-fluid:after {+    clear: both;+  }+  .row-fluid [class*="span"] {+    display: block;+    float: left;+    width: 100%;+    min-height: 28px;+    margin-left: 2.564102564%;+    *margin-left: 2.510911074638298%;+    -webkit-box-sizing: border-box;+       -moz-box-sizing: border-box;+        -ms-box-sizing: border-box;+            box-sizing: border-box;+  }+  .row-fluid [class*="span"]:first-child {+    margin-left: 0;+  }+  .row-fluid .span12 {+    width: 100%;+    *width: 99.94680851063829%;+  }+  .row-fluid .span11 {+    width: 91.45299145300001%;+    *width: 91.3997999636383%;+  }+  .row-fluid .span10 {+    width: 82.905982906%;+    *width: 82.8527914166383%;+  }+  .row-fluid .span9 {+    width: 74.358974359%;+    *width: 74.30578286963829%;+  }+  .row-fluid .span8 {+    width: 65.81196581200001%;+    *width: 65.7587743226383%;+  }+  .row-fluid .span7 {+    width: 57.264957265%;+    *width: 57.2117657756383%;+  }+  .row-fluid .span6 {+    width: 48.717948718%;+    *width: 48.6647572286383%;+  }+  .row-fluid .span5 {+    width: 40.170940171000005%;+    *width: 40.117748681638304%;+  }+  .row-fluid .span4 {+    width: 31.623931624%;+    *width: 31.5707401346383%;+  }+  .row-fluid .span3 {+    width: 23.076923077%;+    *width: 23.0237315876383%;+  }+  .row-fluid .span2 {+    width: 14.529914530000001%;+    *width: 14.4767230406383%;+  }+  .row-fluid .span1 {+    width: 5.982905983%;+    *width: 5.929714493638298%;+  }+  input,+  textarea,+  .uneditable-input {+    margin-left: 0;+  }+  input.span12,+  textarea.span12,+  .uneditable-input.span12 {+    width: 1160px;+  }+  input.span11,+  textarea.span11,+  .uneditable-input.span11 {+    width: 1060px;+  }+  input.span10,+  textarea.span10,+  .uneditable-input.span10 {+    width: 960px;+  }+  input.span9,+  textarea.span9,+  .uneditable-input.span9 {+    width: 860px;+  }+  input.span8,+  textarea.span8,+  .uneditable-input.span8 {+    width: 760px;+  }+  input.span7,+  textarea.span7,+  .uneditable-input.span7 {+    width: 660px;+  }+  input.span6,+  textarea.span6,+  .uneditable-input.span6 {+    width: 560px;+  }+  input.span5,+  textarea.span5,+  .uneditable-input.span5 {+    width: 460px;+  }+  input.span4,+  textarea.span4,+  .uneditable-input.span4 {+    width: 360px;+  }+  input.span3,+  textarea.span3,+  .uneditable-input.span3 {+    width: 260px;+  }+  input.span2,+  textarea.span2,+  .uneditable-input.span2 {+    width: 160px;+  }+  input.span1,+  textarea.span1,+  .uneditable-input.span1 {+    width: 60px;+  }+  .thumbnails {+    margin-left: -30px;+  }+  .thumbnails > li {+    margin-left: 30px;+  }+  .row-fluid .thumbnails {+    margin-left: 0;+  }+}++@media (max-width: 979px) {+  body {+    padding-top: 0;+  }+  .navbar-fixed-top,+  .navbar-fixed-bottom {+    position: static;+  }+  .navbar-fixed-top {+    margin-bottom: 18px;+  }+  .navbar-fixed-bottom {+    margin-top: 18px;+  }+  .navbar-fixed-top .navbar-inner,+  .navbar-fixed-bottom .navbar-inner {+    padding: 5px;+  }+  .navbar .container {+    width: auto;+    padding: 0;+  }+  .navbar .brand {+    padding-right: 10px;+    padding-left: 10px;+    margin: 0 0 0 -5px;+  }+  .nav-collapse {+    clear: both;+  }+  .nav-collapse .nav {+    float: none;+    margin: 0 0 9px;+  }+  .nav-collapse .nav > li {+    float: none;+  }+  .nav-collapse .nav > li > a {+    margin-bottom: 2px;+  }+  .nav-collapse .nav > .divider-vertical {+    display: none;+  }+  .nav-collapse .nav .nav-header {+    color: #999999;+    text-shadow: none;+  }+  .nav-collapse .nav > li > a,+  .nav-collapse .dropdown-menu a {+    padding: 6px 15px;+    font-weight: bold;+    color: #999999;+    -webkit-border-radius: 3px;+       -moz-border-radius: 3px;+            border-radius: 3px;+  }+  .nav-collapse .btn {+    padding: 4px 10px 4px;+    font-weight: normal;+    -webkit-border-radius: 4px;+       -moz-border-radius: 4px;+            border-radius: 4px;+  }+  .nav-collapse .dropdown-menu li + li a {+    margin-bottom: 2px;+  }+  .nav-collapse .nav > li > a:hover,+  .nav-collapse .dropdown-menu a:hover {+    background-color: #222222;+  }+  .nav-collapse.in .btn-group {+    padding: 0;+    margin-top: 5px;+  }+  .nav-collapse .dropdown-menu {+    position: static;+    top: auto;+    left: auto;+    display: block;+    float: none;+    max-width: none;+    padding: 0;+    margin: 0 15px;+    background-color: transparent;+    border: none;+    -webkit-border-radius: 0;+       -moz-border-radius: 0;+            border-radius: 0;+    -webkit-box-shadow: none;+       -moz-box-shadow: none;+            box-shadow: none;+  }+  .nav-collapse .dropdown-menu:before,+  .nav-collapse .dropdown-menu:after {+    display: none;+  }+  .nav-collapse .dropdown-menu .divider {+    display: none;+  }+  .nav-collapse .navbar-form,+  .nav-collapse .navbar-search {+    float: none;+    padding: 9px 15px;+    margin: 9px 0;+    border-top: 1px solid #222222;+    border-bottom: 1px solid #222222;+    -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);+       -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);+            box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);+  }+  .navbar .nav-collapse .nav.pull-right {+    float: none;+    margin-left: 0;+  }+  .nav-collapse,+  .nav-collapse.collapse {+    height: 0;+    overflow: hidden;+  }+  .navbar .btn-navbar {+    display: block;+  }+  .navbar-static .navbar-inner {+    padding-right: 10px;+    padding-left: 10px;+  }+}++@media (min-width: 980px) {+  .nav-collapse.collapse {+    height: auto !important;+    overflow: visible !important;+  }+}
+ static/bootstrap.css view
@@ -0,0 +1,4983 @@+/*!+ * Bootstrap v2.0.4+ *+ * Copyright 2012 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 @twitter by @mdo and @fat.+ */++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 {+  max-width: 100%;+  vertical-align: middle;+  border: 0;+  -ms-interpolation-mode: bicubic;+}++#map_canvas 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,+input[type="button"],+input[type="reset"],+input[type="submit"] {+  cursor: pointer;+  -webkit-appearance: button;+}++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;+}++.clearfix {+  *zoom: 1;+}++.clearfix:before,+.clearfix:after {+  display: table;+  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: 28px;+  -webkit-box-sizing: border-box;+     -moz-box-sizing: border-box;+      -ms-box-sizing: border-box;+          box-sizing: border-box;+}++body {+  margin: 0;+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;+  font-size: 13px;+  line-height: 18px;+  color: #333333;+  background-color: #ffffff;+}++a {+  color: #0088cc;+  text-decoration: none;+}++a:hover {+  color: #005580;+  text-decoration: underline;+}++.row {+  margin-left: -20px;+  *zoom: 1;+}++.row:before,+.row:after {+  display: table;+  content: "";+}++.row:after {+  clear: both;+}++[class*="span"] {+  float: left;+  margin-left: 20px;+}++.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;+  content: "";+}++.row-fluid:after {+  clear: both;+}++.row-fluid [class*="span"] {+  display: block;+  float: left;+  width: 100%;+  min-height: 28px;+  margin-left: 2.127659574%;+  *margin-left: 2.0744680846382977%;+  -webkit-box-sizing: border-box;+     -moz-box-sizing: border-box;+      -ms-box-sizing: border-box;+          box-sizing: border-box;+}++.row-fluid [class*="span"]:first-child {+  margin-left: 0;+}++.row-fluid .span12 {+  width: 99.99999998999999%;+  *width: 99.94680850063828%;+}++.row-fluid .span11 {+  width: 91.489361693%;+  *width: 91.4361702036383%;+}++.row-fluid .span10 {+  width: 82.97872339599999%;+  *width: 82.92553190663828%;+}++.row-fluid .span9 {+  width: 74.468085099%;+  *width: 74.4148936096383%;+}++.row-fluid .span8 {+  width: 65.95744680199999%;+  *width: 65.90425531263828%;+}++.row-fluid .span7 {+  width: 57.446808505%;+  *width: 57.3936170156383%;+}++.row-fluid .span6 {+  width: 48.93617020799999%;+  *width: 48.88297871863829%;+}++.row-fluid .span5 {+  width: 40.425531911%;+  *width: 40.3723404216383%;+}++.row-fluid .span4 {+  width: 31.914893614%;+  *width: 31.8617021246383%;+}++.row-fluid .span3 {+  width: 23.404255317%;+  *width: 23.3510638276383%;+}++.row-fluid .span2 {+  width: 14.89361702%;+  *width: 14.8404255306383%;+}++.row-fluid .span1 {+  width: 6.382978723%;+  *width: 6.329787233638298%;+}++.container {+  margin-right: auto;+  margin-left: auto;+  *zoom: 1;+}++.container:before,+.container:after {+  display: table;+  content: "";+}++.container:after {+  clear: both;+}++.container-fluid {+  padding-right: 20px;+  padding-left: 20px;+  *zoom: 1;+}++.container-fluid:before,+.container-fluid:after {+  display: table;+  content: "";+}++.container-fluid:after {+  clear: both;+}++p {+  margin: 0 0 9px;+}++p small {+  font-size: 11px;+  color: #999999;+}++.lead {+  margin-bottom: 18px;+  font-size: 20px;+  font-weight: 200;+  line-height: 27px;+}++h1,+h2,+h3,+h4,+h5,+h6 {+  margin: 0;+  font-family: inherit;+  font-weight: bold;+  color: inherit;+  text-rendering: optimizelegibility;+}++h1 small,+h2 small,+h3 small,+h4 small,+h5 small,+h6 small {+  font-weight: normal;+  color: #999999;+}++h1 {+  font-size: 30px;+  line-height: 36px;+}++h1 small {+  font-size: 18px;+}++h2 {+  font-size: 24px;+  line-height: 36px;+}++h2 small {+  font-size: 18px;+}++h3 {+  font-size: 18px;+  line-height: 27px;+}++h3 small {+  font-size: 14px;+}++h4,+h5,+h6 {+  line-height: 18px;+}++h4 {+  font-size: 14px;+}++h4 small {+  font-size: 12px;+}++h5 {+  font-size: 12px;+}++h6 {+  font-size: 11px;+  color: #999999;+  text-transform: uppercase;+}++.page-header {+  padding-bottom: 17px;+  margin: 18px 0;+  border-bottom: 1px solid #eeeeee;+}++.page-header h1 {+  line-height: 1;+}++ul,+ol {+  padding: 0;+  margin: 0 0 9px 25px;+}++ul ul,+ul ol,+ol ol,+ol ul {+  margin-bottom: 0;+}++ul {+  list-style: disc;+}++ol {+  list-style: decimal;+}++li {+  line-height: 18px;+}++ul.unstyled,+ol.unstyled {+  margin-left: 0;+  list-style: none;+}++dl {+  margin-bottom: 18px;+}++dt,+dd {+  line-height: 18px;+}++dt {+  font-weight: bold;+  line-height: 17px;+}++dd {+  margin-left: 9px;+}++.dl-horizontal dt {+  float: left;+  width: 120px;+  overflow: hidden;+  clear: left;+  text-align: right;+  text-overflow: ellipsis;+  white-space: nowrap;+}++.dl-horizontal dd {+  margin-left: 130px;+}++hr {+  margin: 18px 0;+  border: 0;+  border-top: 1px solid #eeeeee;+  border-bottom: 1px solid #ffffff;+}++strong {+  font-weight: bold;+}++em {+  font-style: italic;+}++.muted {+  color: #999999;+}++abbr[title] {+  cursor: help;+  border-bottom: 1px dotted #999999;+}++abbr.initialism {+  font-size: 90%;+  text-transform: uppercase;+}++blockquote {+  padding: 0 0 0 15px;+  margin: 0 0 18px;+  border-left: 5px solid #eeeeee;+}++blockquote p {+  margin-bottom: 0;+  font-size: 16px;+  font-weight: 300;+  line-height: 22.5px;+}++blockquote small {+  display: block;+  line-height: 18px;+  color: #999999;+}++blockquote small:before {+  content: '\2014 \00A0';+}++blockquote.pull-right {+  float: right;+  padding-right: 15px;+  padding-left: 0;+  border-right: 5px solid #eeeeee;+  border-left: 0;+}++blockquote.pull-right p,+blockquote.pull-right small {+  text-align: right;+}++q:before,+q:after,+blockquote:before,+blockquote:after {+  content: "";+}++address {+  display: block;+  margin-bottom: 18px;+  font-style: normal;+  line-height: 18px;+}++small {+  font-size: 100%;+}++cite {+  font-style: normal;+}++code,+pre {+  padding: 0 3px 2px;+  font-family: Menlo, Monaco, Consolas, "Courier New", monospace;+  font-size: 12px;+  color: #333333;+  -webkit-border-radius: 3px;+     -moz-border-radius: 3px;+          border-radius: 3px;+}++code {+  padding: 2px 4px;+  color: #d14;+  background-color: #f7f7f9;+  border: 1px solid #e1e1e8;+}++pre {+  display: block;+  padding: 8.5px;+  margin: 0 0 9px;+  font-size: 12.025px;+  line-height: 18px;+  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: 18px;+}++pre code {+  padding: 0;+  color: inherit;+  background-color: transparent;+  border: 0;+}++.pre-scrollable {+  max-height: 340px;+  overflow-y: scroll;+}++form {+  margin: 0 0 18px;+}++fieldset {+  padding: 0;+  margin: 0;+  border: 0;+}++legend {+  display: block;+  width: 100%;+  padding: 0;+  margin-bottom: 27px;+  font-size: 19.5px;+  line-height: 36px;+  color: #333333;+  border: 0;+  border-bottom: 1px solid #e5e5e5;+}++legend small {+  font-size: 13.5px;+  color: #999999;+}++label,+input,+button,+select,+textarea {+  font-size: 13px;+  font-weight: normal;+  line-height: 18px;+}++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: 18px;+  padding: 4px;+  margin-bottom: 9px;+  font-size: 13px;+  line-height: 18px;+  color: #555555;+}++input,+textarea {+  width: 210px;+}++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: #ffffff;+  border: 1px solid #cccccc;+  -webkit-border-radius: 3px;+     -moz-border-radius: 3px;+          border-radius: 3px;+  -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 0.2s, box-shadow linear 0.2s;+     -moz-transition: border linear 0.2s, box-shadow linear 0.2s;+      -ms-transition: border linear 0.2s, box-shadow linear 0.2s;+       -o-transition: border linear 0.2s, box-shadow linear 0.2s;+          transition: border linear 0.2s, box-shadow linear 0.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;+  /* IE6-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: 3px 0;+  *margin-top: 0;+  /* IE7 */++  line-height: normal;+  cursor: pointer;+}++input[type="submit"],+input[type="reset"],+input[type="button"],+input[type="radio"],+input[type="checkbox"] {+  width: auto;+}++.uneditable-textarea {+  width: auto;+  height: auto;+}++select,+input[type="file"] {+  height: 28px;+  /* In IE7, the height of the select element cannot be changed by height, only font-size */++  *margin-top: 4px;+  /* For IE7, add top margin to align select with labels */++  line-height: 28px;+}++select {+  width: 220px;+  border: 1px solid #bbb;+}++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;+}++.radio,+.checkbox {+  min-height: 18px;+  padding-left: 18px;+}++.radio input[type="radio"],+.checkbox input[type="checkbox"] {+  float: left;+  margin-left: -18px;+}++.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-prepend [class*="span"],+.row-fluid .input-append [class*="span"] {+  display: inline-block;+}++input,+textarea,+.uneditable-input {+  margin-left: 0;+}++input.span12,+textarea.span12,+.uneditable-input.span12 {+  width: 930px;+}++input.span11,+textarea.span11,+.uneditable-input.span11 {+  width: 850px;+}++input.span10,+textarea.span10,+.uneditable-input.span10 {+  width: 770px;+}++input.span9,+textarea.span9,+.uneditable-input.span9 {+  width: 690px;+}++input.span8,+textarea.span8,+.uneditable-input.span8 {+  width: 610px;+}++input.span7,+textarea.span7,+.uneditable-input.span7 {+  width: 530px;+}++input.span6,+textarea.span6,+.uneditable-input.span6 {+  width: 450px;+}++input.span5,+textarea.span5,+.uneditable-input.span5 {+  width: 370px;+}++input.span4,+textarea.span4,+.uneditable-input.span4 {+  width: 290px;+}++input.span3,+textarea.span3,+.uneditable-input.span3 {+  width: 210px;+}++input.span2,+textarea.span2,+.uneditable-input.span2 {+  width: 130px;+}++input.span1,+textarea.span1,+.uneditable-input.span1 {+  width: 50px;+}++input[disabled],+select[disabled],+textarea[disabled],+input[readonly],+select[readonly],+textarea[readonly] {+  cursor: not-allowed;+  background-color: #eeeeee;+  border-color: #ddd;+}++input[type="radio"][disabled],+input[type="checkbox"][disabled],+input[type="radio"][readonly],+input[type="checkbox"][readonly] {+  background-color: transparent;+}++.control-group.warning > 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;+  border-color: #c09853;+}++.control-group.warning .checkbox:focus,+.control-group.warning .radio:focus,+.control-group.warning input:focus,+.control-group.warning select:focus,+.control-group.warning textarea:focus {+  border-color: #a47e3c;+  -webkit-box-shadow: 0 0 6px #dbc59e;+     -moz-box-shadow: 0 0 6px #dbc59e;+          box-shadow: 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 > 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;+  border-color: #b94a48;+}++.control-group.error .checkbox:focus,+.control-group.error .radio:focus,+.control-group.error input:focus,+.control-group.error select:focus,+.control-group.error textarea:focus {+  border-color: #953b39;+  -webkit-box-shadow: 0 0 6px #d59392;+     -moz-box-shadow: 0 0 6px #d59392;+          box-shadow: 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 > 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;+  border-color: #468847;+}++.control-group.success .checkbox:focus,+.control-group.success .radio:focus,+.control-group.success input:focus,+.control-group.success select:focus,+.control-group.success textarea:focus {+  border-color: #356635;+  -webkit-box-shadow: 0 0 6px #7aba7b;+     -moz-box-shadow: 0 0 6px #7aba7b;+          box-shadow: 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;+}++input:focus:required:invalid,+textarea:focus:required:invalid,+select:focus:required:invalid {+  color: #b94a48;+  border-color: #ee5f5b;+}++input:focus:required:invalid:focus,+textarea:focus:required:invalid:focus,+select:focus:required:invalid:focus {+  border-color: #e9322d;+  -webkit-box-shadow: 0 0 6px #f8b9b7;+     -moz-box-shadow: 0 0 6px #f8b9b7;+          box-shadow: 0 0 6px #f8b9b7;+}++.form-actions {+  padding: 17px 20px 18px;+  margin-top: 18px;+  margin-bottom: 18px;+  background-color: #f5f5f5;+  border-top: 1px solid #e5e5e5;+  *zoom: 1;+}++.form-actions:before,+.form-actions:after {+  display: table;+  content: "";+}++.form-actions:after {+  clear: both;+}++.uneditable-input {+  overflow: hidden;+  white-space: nowrap;+  cursor: not-allowed;+  background-color: #ffffff;+  border-color: #eee;+  -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);+}++:-moz-placeholder {+  color: #999999;+}++:-ms-input-placeholder {+  color: #999999;+}++::-webkit-input-placeholder {+  color: #999999;+}++.help-block,+.help-inline {+  color: #555555;+}++.help-block {+  display: block;+  margin-bottom: 9px;+}++.help-inline {+  display: inline-block;+  *display: inline;+  padding-left: 5px;+  vertical-align: middle;+  *zoom: 1;+}++.input-prepend,+.input-append {+  margin-bottom: 5px;+}++.input-prepend input,+.input-append input,+.input-prepend select,+.input-append select,+.input-prepend .uneditable-input,+.input-append .uneditable-input {+  position: relative;+  margin-bottom: 0;+  *margin-left: 0;+  vertical-align: middle;+  -webkit-border-radius: 0 3px 3px 0;+     -moz-border-radius: 0 3px 3px 0;+          border-radius: 0 3px 3px 0;+}++.input-prepend input:focus,+.input-append input:focus,+.input-prepend select:focus,+.input-append select:focus,+.input-prepend .uneditable-input:focus,+.input-append .uneditable-input:focus {+  z-index: 2;+}++.input-prepend .uneditable-input,+.input-append .uneditable-input {+  border-left-color: #ccc;+}++.input-prepend .add-on,+.input-append .add-on {+  display: inline-block;+  width: auto;+  height: 18px;+  min-width: 16px;+  padding: 4px 5px;+  font-weight: normal;+  line-height: 18px;+  text-align: center;+  text-shadow: 0 1px 0 #ffffff;+  vertical-align: middle;+  background-color: #eeeeee;+  border: 1px solid #ccc;+}++.input-prepend .add-on,+.input-append .add-on,+.input-prepend .btn,+.input-append .btn {+  margin-left: -1px;+  -webkit-border-radius: 0;+     -moz-border-radius: 0;+          border-radius: 0;+}++.input-prepend .active,+.input-append .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: 3px 0 0 3px;+     -moz-border-radius: 3px 0 0 3px;+          border-radius: 3px 0 0 3px;+}++.input-append input,+.input-append select,+.input-append .uneditable-input {+  -webkit-border-radius: 3px 0 0 3px;+     -moz-border-radius: 3px 0 0 3px;+          border-radius: 3px 0 0 3px;+}++.input-append .uneditable-input {+  border-right-color: #ccc;+  border-left-color: #eee;+}++.input-append .add-on:last-child,+.input-append .btn:last-child {+  -webkit-border-radius: 0 3px 3px 0;+     -moz-border-radius: 0 3px 3px 0;+          border-radius: 0 3px 3px 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 .add-on:first-child,+.input-prepend.input-append .btn:first-child {+  margin-right: -1px;+  -webkit-border-radius: 3px 0 0 3px;+     -moz-border-radius: 3px 0 0 3px;+          border-radius: 3px 0 0 3px;+}++.input-prepend.input-append .add-on:last-child,+.input-prepend.input-append .btn:last-child {+  margin-left: -1px;+  -webkit-border-radius: 0 3px 3px 0;+     -moz-border-radius: 0 3px 3px 0;+          border-radius: 0 3px 3px 0;+}++.search-query {+  padding-right: 14px;+  padding-right: 4px \9;+  padding-left: 14px;+  padding-left: 4px \9;+  /* IE7-8 doesn't have border-radius, so don't indent the padding */++  margin-bottom: 0;+  -webkit-border-radius: 14px;+     -moz-border-radius: 14px;+          border-radius: 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;+  *zoom: 1;+}++.form-search .hide,+.form-inline .hide,+.form-horizontal .hide {+  display: none;+}++.form-search label,+.form-inline label {+  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: 9px;+}++legend + .control-group {+  margin-top: 18px;+  -webkit-margin-top-collapse: separate;+}++.form-horizontal .control-group {+  margin-bottom: 18px;+  *zoom: 1;+}++.form-horizontal .control-group:before,+.form-horizontal .control-group:after {+  display: table;+  content: "";+}++.form-horizontal .control-group:after {+  clear: both;+}++.form-horizontal .control-label {+  float: left;+  width: 140px;+  padding-top: 5px;+  text-align: right;+}++.form-horizontal .controls {+  *display: inline-block;+  *padding-left: 20px;+  margin-left: 160px;+  *margin-left: 0;+}++.form-horizontal .controls:first-child {+  *padding-left: 160px;+}++.form-horizontal .help-block {+  margin-top: 9px;+  margin-bottom: 0;+}++.form-horizontal .form-actions {+  padding-left: 160px;+}++table {+  max-width: 100%;+  background-color: transparent;+  border-collapse: collapse;+  border-spacing: 0;+}++.table {+  width: 100%;+  margin-bottom: 18px;+}++.table th,+.table td {+  padding: 8px;+  line-height: 18px;+  text-align: left;+  vertical-align: top;+  border-top: 1px solid #dddddd;+}++.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 #dddddd;+}++.table-condensed th,+.table-condensed td {+  padding: 4px 5px;+}++.table-bordered {+  border: 1px solid #dddddd;+  border-collapse: separate;+  *border-collapse: collapsed;+  border-left: 0;+  -webkit-border-radius: 4px;+     -moz-border-radius: 4px;+          border-radius: 4px;+}++.table-bordered th,+.table-bordered td {+  border-left: 1px solid #dddddd;+}++.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 {+  -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 {+  -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 {+  -webkit-border-radius: 0 0 0 4px;+     -moz-border-radius: 0 0 0 4px;+          border-radius: 0 0 0 4px;+  -webkit-border-bottom-left-radius: 4px;+          border-bottom-left-radius: 4px;+  -moz-border-radius-bottomleft: 4px;+}++.table-bordered thead:last-child tr:last-child th:last-child,+.table-bordered tbody:last-child tr:last-child td:last-child {+  -webkit-border-bottom-right-radius: 4px;+          border-bottom-right-radius: 4px;+  -moz-border-radius-bottomright: 4px;+}++.table-striped tbody tr:nth-child(odd) td,+.table-striped tbody tr:nth-child(odd) th {+  background-color: #f9f9f9;+}++.table tbody tr:hover td,+.table tbody tr:hover th {+  background-color: #f5f5f5;+}++table .span1 {+  float: none;+  width: 44px;+  margin-left: 0;+}++table .span2 {+  float: none;+  width: 124px;+  margin-left: 0;+}++table .span3 {+  float: none;+  width: 204px;+  margin-left: 0;+}++table .span4 {+  float: none;+  width: 284px;+  margin-left: 0;+}++table .span5 {+  float: none;+  width: 364px;+  margin-left: 0;+}++table .span6 {+  float: none;+  width: 444px;+  margin-left: 0;+}++table .span7 {+  float: none;+  width: 524px;+  margin-left: 0;+}++table .span8 {+  float: none;+  width: 604px;+  margin-left: 0;+}++table .span9 {+  float: none;+  width: 684px;+  margin-left: 0;+}++table .span10 {+  float: none;+  width: 764px;+  margin-left: 0;+}++table .span11 {+  float: none;+  width: 844px;+  margin-left: 0;+}++table .span12 {+  float: none;+  width: 924px;+  margin-left: 0;+}++table .span13 {+  float: none;+  width: 1004px;+  margin-left: 0;+}++table .span14 {+  float: none;+  width: 1084px;+  margin-left: 0;+}++table .span15 {+  float: none;+  width: 1164px;+  margin-left: 0;+}++table .span16 {+  float: none;+  width: 1244px;+  margin-left: 0;+}++table .span17 {+  float: none;+  width: 1324px;+  margin-left: 0;+}++table .span18 {+  float: none;+  width: 1404px;+  margin-left: 0;+}++table .span19 {+  float: none;+  width: 1484px;+  margin-left: 0;+}++table .span20 {+  float: none;+  width: 1564px;+  margin-left: 0;+}++table .span21 {+  float: none;+  width: 1644px;+  margin-left: 0;+}++table .span22 {+  float: none;+  width: 1724px;+  margin-left: 0;+}++table .span23 {+  float: none;+  width: 1804px;+  margin-left: 0;+}++table .span24 {+  float: none;+  width: 1884px;+  margin-left: 0;+}++[class^="icon-"],+[class*=" icon-"] {+  display: inline-block;+  width: 14px;+  height: 14px;+  *margin-right: .3em;+  line-height: 14px;+  vertical-align: text-top;+  background-image: url("glyphicons-halflings.png");+  background-position: 14px 14px;+  background-repeat: no-repeat;+}++[class^="icon-"]:last-child,+[class*=" icon-"]:last-child {+  *margin-left: 0;+}++.icon-white {+  background-image: url("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 {+  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 {+  background-position: -384px -120px;+}++.icon-folder-open {+  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 #000000;+  border-right: 4px solid transparent;+  border-left: 4px solid transparent;+  content: "";+  opacity: 0.3;+  filter: alpha(opacity=30);+}++.dropdown .caret {+  margin-top: 8px;+  margin-left: 2px;+}++.dropdown:hover .caret,+.open .caret {+  opacity: 1;+  filter: alpha(opacity=100);+}++.dropdown-menu {+  position: absolute;+  top: 100%;+  left: 0;+  z-index: 1000;+  display: none;+  float: left;+  min-width: 160px;+  padding: 4px 0;+  margin: 1px 0 0;+  list-style: none;+  background-color: #ffffff;+  border: 1px solid #ccc;+  border: 1px solid rgba(0, 0, 0, 0.2);+  *border-right-width: 2px;+  *border-bottom-width: 2px;+  -webkit-border-radius: 5px;+     -moz-border-radius: 5px;+          border-radius: 5px;+  -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: 8px 1px;+  *margin: -5px 0 5px;+  overflow: hidden;+  background-color: #e5e5e5;+  border-bottom: 1px solid #ffffff;+}++.dropdown-menu a {+  display: block;+  padding: 3px 15px;+  clear: both;+  font-weight: normal;+  line-height: 18px;+  color: #333333;+  white-space: nowrap;+}++.dropdown-menu li > a:hover,+.dropdown-menu .active > a,+.dropdown-menu .active > a:hover {+  color: #ffffff;+  text-decoration: none;+  background-color: #0088cc;+}++.open {+  *z-index: 1000;+}++.open > .dropdown-menu {+  display: block;+}++.pull-right > .dropdown-menu {+  right: 0;+  left: auto;+}++.dropup .caret,+.navbar-fixed-bottom .dropdown .caret {+  border-top: 0;+  border-bottom: 4px solid #000000;+  content: "\2191";+}++.dropup .dropdown-menu,+.navbar-fixed-bottom .dropdown .dropdown-menu {+  top: auto;+  bottom: 100%;+  margin-bottom: 1px;+}++.typeahead {+  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 #eee;+  border: 1px solid rgba(0, 0, 0, 0.05);+  -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 0.15s linear;+     -moz-transition: opacity 0.15s linear;+      -ms-transition: opacity 0.15s linear;+       -o-transition: opacity 0.15s linear;+          transition: opacity 0.15s linear;+}++.fade.in {+  opacity: 1;+}++.collapse {+  position: relative;+  height: 0;+  overflow: hidden;+  -webkit-transition: height 0.35s ease;+     -moz-transition: height 0.35s ease;+      -ms-transition: height 0.35s ease;+       -o-transition: height 0.35s ease;+          transition: height 0.35s ease;+}++.collapse.in {+  height: auto;+}++.close {+  float: right;+  font-size: 20px;+  font-weight: bold;+  line-height: 18px;+  color: #000000;+  text-shadow: 0 1px 0 #ffffff;+  opacity: 0.2;+  filter: alpha(opacity=20);+}++.close:hover {+  color: #000000;+  text-decoration: none;+  cursor: pointer;+  opacity: 0.4;+  filter: alpha(opacity=40);+}++button.close {+  padding: 0;+  cursor: pointer;+  background: transparent;+  border: 0;+  -webkit-appearance: none;+}++.btn {+  display: inline-block;+  *display: inline;+  padding: 4px 10px 4px;+  margin-bottom: 0;+  *margin-left: .3em;+  font-size: 13px;+  line-height: 18px;+  *line-height: 20px;+  color: #333333;+  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: -ms-linear-gradient(top, #ffffff, #e6e6e6);+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));+  background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);+  background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);+  background-image: linear-gradient(top, #ffffff, #e6e6e6);+  background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);+  background-repeat: repeat-x;+  border: 1px solid #cccccc;+  *border: 0;+  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);+  border-color: #e6e6e6 #e6e6e6 #bfbfbf;+  border-bottom-color: #b3b3b3;+  -webkit-border-radius: 4px;+     -moz-border-radius: 4px;+          border-radius: 4px;+  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', 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:active,+.btn.active,+.btn.disabled,+.btn[disabled] {+  background-color: #e6e6e6;+  *background-color: #d9d9d9;+}++.btn:active,+.btn.active {+  background-color: #cccccc \9;+}++.btn:first-child {+  *margin-left: 0;+}++.btn:hover {+  color: #333333;+  text-decoration: none;+  background-color: #e6e6e6;+  *background-color: #d9d9d9;+  /* Buttons in IE7 don't get borders, so darken on hover */++  background-position: 0 -15px;+  -webkit-transition: background-position 0.1s linear;+     -moz-transition: background-position 0.1s linear;+      -ms-transition: background-position 0.1s linear;+       -o-transition: background-position 0.1s linear;+          transition: background-position 0.1s linear;+}++.btn:focus {+  outline: thin dotted #333;+  outline: 5px auto -webkit-focus-ring-color;+  outline-offset: -2px;+}++.btn.active,+.btn:active {+  background-color: #e6e6e6;+  background-color: #d9d9d9 \9;+  background-image: none;+  outline: 0;+  -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 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-color: #e6e6e6;+  background-image: none;+  opacity: 0.65;+  filter: alpha(opacity=65);+  -webkit-box-shadow: none;+     -moz-box-shadow: none;+          box-shadow: none;+}++.btn-large {+  padding: 9px 14px;+  font-size: 15px;+  line-height: normal;+  -webkit-border-radius: 5px;+     -moz-border-radius: 5px;+          border-radius: 5px;+}++.btn-large [class^="icon-"] {+  margin-top: 1px;+}++.btn-small {+  padding: 5px 9px;+  font-size: 11px;+  line-height: 16px;+}++.btn-small [class^="icon-"] {+  margin-top: -1px;+}++.btn-mini {+  padding: 2px 6px;+  font-size: 11px;+  line-height: 14px;+}++.btn-primary,+.btn-primary:hover,+.btn-warning,+.btn-warning:hover,+.btn-danger,+.btn-danger:hover,+.btn-success,+.btn-success:hover,+.btn-info,+.btn-info:hover,+.btn-inverse,+.btn-inverse:hover {+  color: #ffffff;+  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);+}++.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 {+  border-color: #ccc;+  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);+}++.btn-primary {+  background-color: #0074cc;+  *background-color: #0055cc;+  background-image: -ms-linear-gradient(top, #0088cc, #0055cc);+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0055cc));+  background-image: -webkit-linear-gradient(top, #0088cc, #0055cc);+  background-image: -o-linear-gradient(top, #0088cc, #0055cc);+  background-image: -moz-linear-gradient(top, #0088cc, #0055cc);+  background-image: linear-gradient(top, #0088cc, #0055cc);+  background-repeat: repeat-x;+  border-color: #0055cc #0055cc #003580;+  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='#0088cc', endColorstr='#0055cc', GradientType=0);+  filter: progid:dximagetransform.microsoft.gradient(enabled=false);+}++.btn-primary:hover,+.btn-primary:active,+.btn-primary.active,+.btn-primary.disabled,+.btn-primary[disabled] {+  background-color: #0055cc;+  *background-color: #004ab3;+}++.btn-primary:active,+.btn-primary.active {+  background-color: #004099 \9;+}++.btn-warning {+  background-color: #faa732;+  *background-color: #f89406;+  background-image: -ms-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: -moz-linear-gradient(top, #fbb450, #f89406);+  background-image: linear-gradient(top, #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='#fbb450', endColorstr='#f89406', GradientType=0);+  filter: progid:dximagetransform.microsoft.gradient(enabled=false);+}++.btn-warning:hover,+.btn-warning:active,+.btn-warning.active,+.btn-warning.disabled,+.btn-warning[disabled] {+  background-color: #f89406;+  *background-color: #df8505;+}++.btn-warning:active,+.btn-warning.active {+  background-color: #c67605 \9;+}++.btn-danger {+  background-color: #da4f49;+  *background-color: #bd362f;+  background-image: -ms-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: -moz-linear-gradient(top, #ee5f5b, #bd362f);+  background-image: linear-gradient(top, #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='#ee5f5b', endColorstr='#bd362f', GradientType=0);+  filter: progid:dximagetransform.microsoft.gradient(enabled=false);+}++.btn-danger:hover,+.btn-danger:active,+.btn-danger.active,+.btn-danger.disabled,+.btn-danger[disabled] {+  background-color: #bd362f;+  *background-color: #a9302a;+}++.btn-danger:active,+.btn-danger.active {+  background-color: #942a25 \9;+}++.btn-success {+  background-color: #5bb75b;+  *background-color: #51a351;+  background-image: -ms-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: -moz-linear-gradient(top, #62c462, #51a351);+  background-image: linear-gradient(top, #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='#62c462', endColorstr='#51a351', GradientType=0);+  filter: progid:dximagetransform.microsoft.gradient(enabled=false);+}++.btn-success:hover,+.btn-success:active,+.btn-success.active,+.btn-success.disabled,+.btn-success[disabled] {+  background-color: #51a351;+  *background-color: #499249;+}++.btn-success:active,+.btn-success.active {+  background-color: #408140 \9;+}++.btn-info {+  background-color: #49afcd;+  *background-color: #2f96b4;+  background-image: -ms-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: -moz-linear-gradient(top, #5bc0de, #2f96b4);+  background-image: linear-gradient(top, #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='#5bc0de', endColorstr='#2f96b4', GradientType=0);+  filter: progid:dximagetransform.microsoft.gradient(enabled=false);+}++.btn-info:hover,+.btn-info:active,+.btn-info.active,+.btn-info.disabled,+.btn-info[disabled] {+  background-color: #2f96b4;+  *background-color: #2a85a0;+}++.btn-info:active,+.btn-info.active {+  background-color: #24748c \9;+}++.btn-inverse {+  background-color: #414141;+  *background-color: #222222;+  background-image: -ms-linear-gradient(top, #555555, #222222);+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#555555), to(#222222));+  background-image: -webkit-linear-gradient(top, #555555, #222222);+  background-image: -o-linear-gradient(top, #555555, #222222);+  background-image: -moz-linear-gradient(top, #555555, #222222);+  background-image: linear-gradient(top, #555555, #222222);+  background-repeat: repeat-x;+  border-color: #222222 #222222 #000000;+  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);+  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#555555', endColorstr='#222222', GradientType=0);+  filter: progid:dximagetransform.microsoft.gradient(enabled=false);+}++.btn-inverse:hover,+.btn-inverse:active,+.btn-inverse.active,+.btn-inverse.disabled,+.btn-inverse[disabled] {+  background-color: #222222;+  *background-color: #151515;+}++.btn-inverse:active,+.btn-inverse.active {+  background-color: #080808 \9;+}++button.btn,+input[type="submit"].btn {+  *padding-top: 2px;+  *padding-bottom: 2px;+}++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-group {+  position: relative;+  *margin-left: .3em;+  *zoom: 1;+}++.btn-group:before,+.btn-group:after {+  display: table;+  content: "";+}++.btn-group:after {+  clear: both;+}++.btn-group:first-child {+  *margin-left: 0;+}++.btn-group + .btn-group {+  margin-left: 5px;+}++.btn-toolbar {+  margin-top: 9px;+  margin-bottom: 9px;+}++.btn-toolbar .btn-group {+  display: inline-block;+  *display: inline;+  /* IE7 inline-block hack */++  *zoom: 1;+}++.btn-group > .btn {+  position: relative;+  float: left;+  margin-left: -1px;+  -webkit-border-radius: 0;+     -moz-border-radius: 0;+          border-radius: 0;+}++.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 > .dropdown-toggle {+  *padding-top: 4px;+  padding-right: 8px;+  *padding-bottom: 4px;+  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-right: 5px;+  padding-left: 5px;+}++.btn-group > .btn-small.dropdown-toggle {+  *padding-top: 4px;+  *padding-bottom: 4px;+}++.btn-group > .btn-large.dropdown-toggle {+  padding-right: 12px;+  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: #0055cc;+}++.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: #222222;+}++.btn .caret {+  margin-top: 7px;+  margin-left: 0;+}++.btn:hover .caret,+.open.btn-group .caret {+  opacity: 1;+  filter: alpha(opacity=100);+}++.btn-mini .caret {+  margin-top: 5px;+}++.btn-small .caret {+  margin-top: 6px;+}++.btn-large .caret {+  margin-top: 6px;+  border-top-width: 5px;+  border-right-width: 5px;+  border-left-width: 5px;+}++.dropup .btn-large .caret {+  border-top: 0;+  border-bottom: 5px solid #000000;+}++.btn-primary .caret,+.btn-warning .caret,+.btn-danger .caret,+.btn-info .caret,+.btn-success .caret,+.btn-inverse .caret {+  border-top-color: #ffffff;+  border-bottom-color: #ffffff;+  opacity: 0.75;+  filter: alpha(opacity=75);+}++.alert {+  padding: 8px 35px 8px 14px;+  margin-bottom: 18px;+  color: #c09853;+  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-heading {+  color: inherit;+}++.alert .close {+  position: relative;+  top: -2px;+  right: -21px;+  line-height: 18px;+}++.alert-success {+  color: #468847;+  background-color: #dff0d8;+  border-color: #d6e9c6;+}++.alert-danger,+.alert-error {+  color: #b94a48;+  background-color: #f2dede;+  border-color: #eed3d7;+}++.alert-info {+  color: #3a87ad;+  background-color: #d9edf7;+  border-color: #bce8f1;+}++.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: 18px;+  margin-left: 0;+  list-style: none;+}++.nav > li > a {+  display: block;+}++.nav > li > a:hover {+  text-decoration: none;+  background-color: #eeeeee;+}++.nav > .pull-right {+  float: right;+}++.nav .nav-header {+  display: block;+  padding: 3px 15px;+  font-size: 11px;+  font-weight: bold;+  line-height: 18px;+  color: #999999;+  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 {+  color: #ffffff;+  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);+  background-color: #0088cc;+}++.nav-list [class^="icon-"] {+  margin-right: 2px;+}++.nav-list .divider {+  *width: 100%;+  height: 1px;+  margin: 8px 1px;+  *margin: -5px 0 5px;+  overflow: hidden;+  background-color: #e5e5e5;+  border-bottom: 1px solid #ffffff;+}++.nav-tabs,+.nav-pills {+  *zoom: 1;+}++.nav-tabs:before,+.nav-pills:before,+.nav-tabs:after,+.nav-pills:after {+  display: table;+  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: 18px;+  border: 1px solid transparent;+  -webkit-border-radius: 4px 4px 0 0;+     -moz-border-radius: 4px 4px 0 0;+          border-radius: 4px 4px 0 0;+}++.nav-tabs > li > a:hover {+  border-color: #eeeeee #eeeeee #dddddd;+}++.nav-tabs > .active > a,+.nav-tabs > .active > a:hover {+  color: #555555;+  cursor: default;+  background-color: #ffffff;+  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 {+  color: #ffffff;+  background-color: #0088cc;+}++.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-radius: 4px 4px 0 0;+     -moz-border-radius: 4px 4px 0 0;+          border-radius: 4px 4px 0 0;+}++.nav-tabs.nav-stacked > li:last-child > a {+  -webkit-border-radius: 0 0 4px 4px;+     -moz-border-radius: 0 0 4px 4px;+          border-radius: 0 0 4px 4px;+}++.nav-tabs.nav-stacked > li > a:hover {+  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 5px 5px;+     -moz-border-radius: 0 0 5px 5px;+          border-radius: 0 0 5px 5px;+}++.nav-pills .dropdown-menu {+  -webkit-border-radius: 4px;+     -moz-border-radius: 4px;+          border-radius: 4px;+}++.nav-tabs .dropdown-toggle .caret,+.nav-pills .dropdown-toggle .caret {+  margin-top: 6px;+  border-top-color: #0088cc;+  border-bottom-color: #0088cc;+}++.nav-tabs .dropdown-toggle:hover .caret,+.nav-pills .dropdown-toggle:hover .caret {+  border-top-color: #005580;+  border-bottom-color: #005580;+}++.nav-tabs .active .dropdown-toggle .caret,+.nav-pills .active .dropdown-toggle .caret {+  border-top-color: #333333;+  border-bottom-color: #333333;+}++.nav > .dropdown.active > a:hover {+  color: #000000;+  cursor: pointer;+}++.nav-tabs .open .dropdown-toggle,+.nav-pills .open .dropdown-toggle,+.nav > li.dropdown.open.active > a:hover {+  color: #ffffff;+  background-color: #999999;+  border-color: #999999;+}++.nav li.dropdown.open .caret,+.nav li.dropdown.open.active .caret,+.nav li.dropdown.open a:hover .caret {+  border-top-color: #ffffff;+  border-bottom-color: #ffffff;+  opacity: 1;+  filter: alpha(opacity=100);+}++.tabs-stacked .open > a:hover {+  border-color: #999999;+}++.tabbable {+  *zoom: 1;+}++.tabbable:before,+.tabbable:after {+  display: table;+  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 {+  border-top-color: #ddd;+  border-bottom-color: transparent;+}++.tabs-below > .nav-tabs > .active > a,+.tabs-below > .nav-tabs > .active > a:hover {+  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 {+  border-color: #eeeeee #dddddd #eeeeee #eeeeee;+}++.tabs-left > .nav-tabs .active > a,+.tabs-left > .nav-tabs .active > a:hover {+  border-color: #ddd transparent #ddd #ddd;+  *border-right-color: #ffffff;+}++.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 {+  border-color: #eeeeee #eeeeee #eeeeee #dddddd;+}++.tabs-right > .nav-tabs .active > a,+.tabs-right > .nav-tabs .active > a:hover {+  border-color: #ddd #ddd #ddd transparent;+  *border-left-color: #ffffff;+}++.navbar {+  *position: relative;+  *z-index: 2;+  margin-bottom: 18px;+  overflow: visible;+}++.navbar-inner {+  min-height: 40px;+  padding-right: 20px;+  padding-left: 20px;+  background-color: #2c2c2c;+  background-image: -moz-linear-gradient(top, #333333, #222222);+  background-image: -ms-linear-gradient(top, #333333, #222222);+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));+  background-image: -webkit-linear-gradient(top, #333333, #222222);+  background-image: -o-linear-gradient(top, #333333, #222222);+  background-image: linear-gradient(top, #333333, #222222);+  background-repeat: repeat-x;+  -webkit-border-radius: 4px;+     -moz-border-radius: 4px;+          border-radius: 4px;+  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);+  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);+     -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);+          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);+}++.navbar .container {+  width: auto;+}++.nav-collapse.collapse {+  height: auto;+}++.navbar {+  color: #999999;+}++.navbar .brand:hover {+  text-decoration: none;+}++.navbar .brand {+  display: block;+  float: left;+  padding: 8px 20px 12px;+  margin-left: -20px;+  font-size: 20px;+  font-weight: 200;+  line-height: 1;+  color: #999999;+}++.navbar .navbar-text {+  margin-bottom: 0;+  line-height: 40px;+}++.navbar .navbar-link {+  color: #999999;+}++.navbar .navbar-link:hover {+  color: #ffffff;+}++.navbar .btn,+.navbar .btn-group {+  margin-top: 5px;+}++.navbar .btn-group .btn {+  margin: 0;+}++.navbar-form {+  margin-bottom: 0;+  *zoom: 1;+}++.navbar-form:before,+.navbar-form:after {+  display: table;+  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 {+  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: 6px;+  white-space: nowrap;+}++.navbar-form .input-append input,+.navbar-form .input-prepend input {+  margin-top: 0;+}++.navbar-search {+  position: relative;+  float: left;+  margin-top: 6px;+  margin-bottom: 0;+}++.navbar-search .search-query {+  padding: 4px 9px;+  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;+  font-size: 13px;+  font-weight: normal;+  line-height: 1;+  color: #ffffff;+  background-color: #626262;+  border: 1px solid #151515;+  -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;+      -ms-transition: none;+       -o-transition: none;+          transition: none;+}++.navbar-search .search-query:-moz-placeholder {+  color: #cccccc;+}++.navbar-search .search-query:-ms-input-placeholder {+  color: #cccccc;+}++.navbar-search .search-query::-webkit-input-placeholder {+  color: #cccccc;+}++.navbar-search .search-query:focus,+.navbar-search .search-query.focused {+  padding: 5px 10px;+  color: #333333;+  text-shadow: 0 1px 0 #ffffff;+  background-color: #ffffff;+  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-fixed-top,+.navbar-fixed-bottom {+  position: fixed;+  right: 0;+  left: 0;+  z-index: 1030;+  margin-bottom: 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-fixed-top .container,+.navbar-fixed-bottom .container {+  width: 940px;+}++.navbar-fixed-top {+  top: 0;+}++.navbar-fixed-bottom {+  bottom: 0;+}++.navbar .nav {+  position: relative;+  left: 0;+  display: block;+  float: left;+  margin: 0 10px 0 0;+}++.navbar .nav.pull-right {+  float: right;+}++.navbar .nav > li {+  display: block;+  float: left;+}++.navbar .nav > li > a {+  float: none;+  padding: 9px 10px 11px;+  line-height: 19px;+  color: #999999;+  text-decoration: none;+  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);+}++.navbar .btn {+  display: inline-block;+  padding: 4px 10px 4px;+  margin: 5px 5px 6px;+  line-height: 18px;+}++.navbar .btn-group {+  padding: 5px 5px 6px;+  margin: 0;+}++.navbar .nav > li > a:hover {+  color: #ffffff;+  text-decoration: none;+  background-color: transparent;+}++.navbar .nav .active > a,+.navbar .nav .active > a:hover {+  color: #ffffff;+  text-decoration: none;+  background-color: #222222;+}++.navbar .divider-vertical {+  width: 1px;+  height: 40px;+  margin: 0 9px;+  overflow: hidden;+  background-color: #222222;+  border-right: 1px solid #333333;+}++.navbar .nav.pull-right {+  margin-right: 0;+  margin-left: 10px;+}++.navbar .btn-navbar {+  display: none;+  float: right;+  padding: 7px 10px;+  margin-right: 5px;+  margin-left: 5px;+  background-color: #2c2c2c;+  *background-color: #222222;+  background-image: -ms-linear-gradient(top, #333333, #222222);+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));+  background-image: -webkit-linear-gradient(top, #333333, #222222);+  background-image: -o-linear-gradient(top, #333333, #222222);+  background-image: linear-gradient(top, #333333, #222222);+  background-image: -moz-linear-gradient(top, #333333, #222222);+  background-repeat: repeat-x;+  border-color: #222222 #222222 #000000;+  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);+  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#333333', endColorstr='#222222', 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:active,+.navbar .btn-navbar.active,+.navbar .btn-navbar.disabled,+.navbar .btn-navbar[disabled] {+  background-color: #222222;+  *background-color: #151515;+}++.navbar .btn-navbar:active,+.navbar .btn-navbar.active {+  background-color: #080808 \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 .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 .dropdown-menu:after {+  position: absolute;+  top: -6px;+  left: 10px;+  display: inline-block;+  border-right: 6px solid transparent;+  border-bottom: 6px solid #ffffff;+  border-left: 6px solid transparent;+  content: '';+}++.navbar-fixed-bottom .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 .dropdown-menu:after {+  top: auto;+  bottom: -6px;+  border-top: 6px solid #ffffff;+  border-bottom: 0;+}++.navbar .nav li.dropdown .dropdown-toggle .caret,+.navbar .nav li.dropdown.open .caret {+  border-top-color: #ffffff;+  border-bottom-color: #ffffff;+}++.navbar .nav li.dropdown.active .caret {+  opacity: 1;+  filter: alpha(opacity=100);+}++.navbar .nav li.dropdown.open > .dropdown-toggle,+.navbar .nav li.dropdown.active > .dropdown-toggle,+.navbar .nav li.dropdown.open.active > .dropdown-toggle {+  background-color: transparent;+}++.navbar .nav li.dropdown.active > .dropdown-toggle:hover {+  color: #ffffff;+}++.navbar .pull-right .dropdown-menu,+.navbar .dropdown-menu.pull-right {+  right: 0;+  left: auto;+}++.navbar .pull-right .dropdown-menu:before,+.navbar .dropdown-menu.pull-right:before {+  right: 12px;+  left: auto;+}++.navbar .pull-right .dropdown-menu:after,+.navbar .dropdown-menu.pull-right:after {+  right: 13px;+  left: auto;+}++.breadcrumb {+  padding: 7px 14px;+  margin: 0 0 18px;+  list-style: none;+  background-color: #fbfbfb;+  background-image: -moz-linear-gradient(top, #ffffff, #f5f5f5);+  background-image: -ms-linear-gradient(top, #ffffff, #f5f5f5);+  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f5f5f5));+  background-image: -webkit-linear-gradient(top, #ffffff, #f5f5f5);+  background-image: -o-linear-gradient(top, #ffffff, #f5f5f5);+  background-image: linear-gradient(top, #ffffff, #f5f5f5);+  background-repeat: repeat-x;+  border: 1px solid #ddd;+  -webkit-border-radius: 3px;+     -moz-border-radius: 3px;+          border-radius: 3px;+  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0);+  -webkit-box-shadow: inset 0 1px 0 #ffffff;+     -moz-box-shadow: inset 0 1px 0 #ffffff;+          box-shadow: inset 0 1px 0 #ffffff;+}++.breadcrumb li {+  display: inline-block;+  *display: inline;+  text-shadow: 0 1px 0 #ffffff;+  *zoom: 1;+}++.breadcrumb .divider {+  padding: 0 5px;+  color: #999999;+}++.breadcrumb .active a {+  color: #333333;+}++.pagination {+  height: 36px;+  margin: 18px 0;+}++.pagination ul {+  display: inline-block;+  *display: inline;+  margin-bottom: 0;+  margin-left: 0;+  -webkit-border-radius: 3px;+     -moz-border-radius: 3px;+          border-radius: 3px;+  *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 li {+  display: inline;+}++.pagination a {+  float: left;+  padding: 0 14px;+  line-height: 34px;+  text-decoration: none;+  border: 1px solid #ddd;+  border-left-width: 0;+}++.pagination a:hover,+.pagination .active a {+  background-color: #f5f5f5;+}++.pagination .active a {+  color: #999999;+  cursor: default;+}++.pagination .disabled span,+.pagination .disabled a,+.pagination .disabled a:hover {+  color: #999999;+  cursor: default;+  background-color: transparent;+}++.pagination li:first-child a {+  border-left-width: 1px;+  -webkit-border-radius: 3px 0 0 3px;+     -moz-border-radius: 3px 0 0 3px;+          border-radius: 3px 0 0 3px;+}++.pagination li:last-child a {+  -webkit-border-radius: 0 3px 3px 0;+     -moz-border-radius: 0 3px 3px 0;+          border-radius: 0 3px 3px 0;+}++.pagination-centered {+  text-align: center;+}++.pagination-right {+  text-align: right;+}++.pager {+  margin-bottom: 18px;+  margin-left: 0;+  text-align: center;+  list-style: none;+  *zoom: 1;+}++.pager:before,+.pager:after {+  display: table;+  content: "";+}++.pager:after {+  clear: both;+}++.pager li {+  display: inline;+}++.pager a {+  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 a:hover {+  text-decoration: none;+  background-color: #f5f5f5;+}++.pager .next a {+  float: right;+}++.pager .previous a {+  float: left;+}++.pager .disabled a,+.pager .disabled a:hover {+  color: #999999;+  cursor: default;+  background-color: #fff;+}++.modal-open .dropdown-menu {+  z-index: 2050;+}++.modal-open .dropdown.open {+  *z-index: 2050;+}++.modal-open .popover {+  z-index: 2060;+}++.modal-open .tooltip {+  z-index: 2070;+}++.modal-backdrop {+  position: fixed;+  top: 0;+  right: 0;+  bottom: 0;+  left: 0;+  z-index: 1040;+  background-color: #000000;+}++.modal-backdrop.fade {+  opacity: 0;+}++.modal-backdrop,+.modal-backdrop.fade.in {+  opacity: 0.8;+  filter: alpha(opacity=80);+}++.modal {+  position: fixed;+  top: 50%;+  left: 50%;+  z-index: 1050;+  width: 560px;+  margin: -250px 0 0 -280px;+  overflow: auto;+  background-color: #ffffff;+  border: 1px solid #999;+  border: 1px solid rgba(0, 0, 0, 0.3);+  *border: 1px solid #999;+  -webkit-border-radius: 6px;+     -moz-border-radius: 6px;+          border-radius: 6px;+  -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);+     -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);+          box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);+  -webkit-background-clip: padding-box;+     -moz-background-clip: padding-box;+          background-clip: padding-box;+}++.modal.fade {+  top: -25%;+  -webkit-transition: opacity 0.3s linear, top 0.3s ease-out;+     -moz-transition: opacity 0.3s linear, top 0.3s ease-out;+      -ms-transition: opacity 0.3s linear, top 0.3s ease-out;+       -o-transition: opacity 0.3s linear, top 0.3s ease-out;+          transition: opacity 0.3s linear, top 0.3s ease-out;+}++.modal.fade.in {+  top: 50%;+}++.modal-header {+  padding: 9px 15px;+  border-bottom: 1px solid #eee;+}++.modal-header .close {+  margin-top: 2px;+}++.modal-body {+  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 #ffffff;+     -moz-box-shadow: inset 0 1px 0 #ffffff;+          box-shadow: inset 0 1px 0 #ffffff;+}++.modal-footer:before,+.modal-footer:after {+  display: table;+  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;+}++.tooltip {+  position: absolute;+  z-index: 1020;+  display: block;+  padding: 5px;+  font-size: 11px;+  opacity: 0;+  filter: alpha(opacity=0);+  visibility: visible;+}++.tooltip.in {+  opacity: 0.8;+  filter: alpha(opacity=80);+}++.tooltip.top {+  margin-top: -2px;+}++.tooltip.right {+  margin-left: 2px;+}++.tooltip.bottom {+  margin-top: 2px;+}++.tooltip.left {+  margin-left: -2px;+}++.tooltip.top .tooltip-arrow {+  bottom: 0;+  left: 50%;+  margin-left: -5px;+  border-top: 5px solid #000000;+  border-right: 5px solid transparent;+  border-left: 5px solid transparent;+}++.tooltip.left .tooltip-arrow {+  top: 50%;+  right: 0;+  margin-top: -5px;+  border-top: 5px solid transparent;+  border-bottom: 5px solid transparent;+  border-left: 5px solid #000000;+}++.tooltip.bottom .tooltip-arrow {+  top: 0;+  left: 50%;+  margin-left: -5px;+  border-right: 5px solid transparent;+  border-bottom: 5px solid #000000;+  border-left: 5px solid transparent;+}++.tooltip.right .tooltip-arrow {+  top: 50%;+  left: 0;+  margin-top: -5px;+  border-top: 5px solid transparent;+  border-right: 5px solid #000000;+  border-bottom: 5px solid transparent;+}++.tooltip-inner {+  max-width: 200px;+  padding: 3px 8px;+  color: #ffffff;+  text-align: center;+  text-decoration: none;+  background-color: #000000;+  -webkit-border-radius: 4px;+     -moz-border-radius: 4px;+          border-radius: 4px;+}++.tooltip-arrow {+  position: absolute;+  width: 0;+  height: 0;+}++.popover {+  position: absolute;+  top: 0;+  left: 0;+  z-index: 1010;+  display: none;+  padding: 5px;+}++.popover.top {+  margin-top: -5px;+}++.popover.right {+  margin-left: 5px;+}++.popover.bottom {+  margin-top: 5px;+}++.popover.left {+  margin-left: -5px;+}++.popover.top .arrow {+  bottom: 0;+  left: 50%;+  margin-left: -5px;+  border-top: 5px solid #000000;+  border-right: 5px solid transparent;+  border-left: 5px solid transparent;+}++.popover.right .arrow {+  top: 50%;+  left: 0;+  margin-top: -5px;+  border-top: 5px solid transparent;+  border-right: 5px solid #000000;+  border-bottom: 5px solid transparent;+}++.popover.bottom .arrow {+  top: 0;+  left: 50%;+  margin-left: -5px;+  border-right: 5px solid transparent;+  border-bottom: 5px solid #000000;+  border-left: 5px solid transparent;+}++.popover.left .arrow {+  top: 50%;+  right: 0;+  margin-top: -5px;+  border-top: 5px solid transparent;+  border-bottom: 5px solid transparent;+  border-left: 5px solid #000000;+}++.popover .arrow {+  position: absolute;+  width: 0;+  height: 0;+}++.popover-inner {+  width: 280px;+  padding: 3px;+  overflow: hidden;+  background: #000000;+  background: rgba(0, 0, 0, 0.8);+  -webkit-border-radius: 6px;+     -moz-border-radius: 6px;+          border-radius: 6px;+  -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);+     -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);+          box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);+}++.popover-title {+  padding: 9px 15px;+  line-height: 1;+  background-color: #f5f5f5;+  border-bottom: 1px solid #eee;+  -webkit-border-radius: 3px 3px 0 0;+     -moz-border-radius: 3px 3px 0 0;+          border-radius: 3px 3px 0 0;+}++.popover-content {+  padding: 14px;+  background-color: #ffffff;+  -webkit-border-radius: 0 0 3px 3px;+     -moz-border-radius: 0 0 3px 3px;+          border-radius: 0 0 3px 3px;+  -webkit-background-clip: padding-box;+     -moz-background-clip: padding-box;+          background-clip: padding-box;+}++.popover-content p,+.popover-content ul,+.popover-content ol {+  margin-bottom: 0;+}++.thumbnails {+  margin-left: -20px;+  list-style: none;+  *zoom: 1;+}++.thumbnails:before,+.thumbnails:after {+  display: table;+  content: "";+}++.thumbnails:after {+  clear: both;+}++.row-fluid .thumbnails {+  margin-left: 0;+}++.thumbnails > li {+  float: left;+  margin-bottom: 18px;+  margin-left: 20px;+}++.thumbnail {+  display: block;+  padding: 4px;+  line-height: 1;+  border: 1px solid #ddd;+  -webkit-border-radius: 4px;+     -moz-border-radius: 4px;+          border-radius: 4px;+  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075);+     -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075);+          box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075);+}++a.thumbnail:hover {+  border-color: #0088cc;+  -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);+     -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);+          box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);+}++.thumbnail > img {+  display: block;+  max-width: 100%;+  margin-right: auto;+  margin-left: auto;+}++.thumbnail .caption {+  padding: 9px;+}++.label,+.badge {+  font-size: 10.998px;+  font-weight: bold;+  line-height: 14px;+  color: #ffffff;+  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);+  white-space: nowrap;+  vertical-align: baseline;+  background-color: #999999;+}++.label {+  padding: 1px 4px 2px;+  -webkit-border-radius: 3px;+     -moz-border-radius: 3px;+          border-radius: 3px;+}++.badge {+  padding: 1px 9px 2px;+  -webkit-border-radius: 9px;+     -moz-border-radius: 9px;+          border-radius: 9px;+}++a.label:hover,+a.badge:hover {+  color: #ffffff;+  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: #333333;+}++.label-inverse[href],+.badge-inverse[href] {+  background-color: #1a1a1a;+}++@-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: 18px;+  margin-bottom: 18px;+  overflow: hidden;+  background-color: #f7f7f7;+  background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9);+  background-image: -ms-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(top, #f5f5f5, #f9f9f9);+  background-repeat: repeat-x;+  -webkit-border-radius: 4px;+     -moz-border-radius: 4px;+          border-radius: 4px;+  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#f9f9f9', 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 {+  width: 0;+  height: 18px;+  font-size: 12px;+  color: #ffffff;+  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(top, #149bdf, #0480be);+  background-image: -ms-linear-gradient(top, #149bdf, #0480be);+  background-repeat: repeat-x;+  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#149bdf', endColorstr='#0480be', 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;+      -ms-box-sizing: border-box;+          box-sizing: border-box;+  -webkit-transition: width 0.6s ease;+     -moz-transition: width 0.6s ease;+      -ms-transition: width 0.6s ease;+       -o-transition: width 0.6s ease;+          transition: width 0.6s ease;+}++.progress-striped .bar {+  background-color: #149bdf;+  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: -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: -ms-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: -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: 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 {+  background-color: #dd514c;+  background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);+  background-image: -ms-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(top, #ee5f5b, #c43c35);+  background-repeat: repeat-x;+  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);+}++.progress-danger.progress-striped .bar {+  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: -ms-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 {+  background-color: #5eb95e;+  background-image: -moz-linear-gradient(top, #62c462, #57a957);+  background-image: -ms-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(top, #62c462, #57a957);+  background-repeat: repeat-x;+  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);+}++.progress-success.progress-striped .bar {+  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: -ms-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 {+  background-color: #4bb1cf;+  background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);+  background-image: -ms-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(top, #5bc0de, #339bb9);+  background-repeat: repeat-x;+  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);+}++.progress-info.progress-striped .bar {+  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: -ms-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 {+  background-color: #faa732;+  background-image: -moz-linear-gradient(top, #fbb450, #f89406);+  background-image: -ms-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(top, #fbb450, #f89406);+  background-repeat: repeat-x;+  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0);+}++.progress-warning.progress-striped .bar {+  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: -ms-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: 18px;+}++.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: 18px;+  line-height: 1;+}++.carousel-inner {+  position: relative;+  width: 100%;+  overflow: hidden;+}++.carousel .item {+  position: relative;+  display: none;+  -webkit-transition: 0.6s ease-in-out left;+     -moz-transition: 0.6s ease-in-out left;+      -ms-transition: 0.6s ease-in-out left;+       -o-transition: 0.6s ease-in-out left;+          transition: 0.6s ease-in-out left;+}++.carousel .item > img {+  display: block;+  line-height: 1;+}++.carousel .active,+.carousel .next,+.carousel .prev {+  display: block;+}++.carousel .active {+  left: 0;+}++.carousel .next,+.carousel .prev {+  position: absolute;+  top: 0;+  width: 100%;+}++.carousel .next {+  left: 100%;+}++.carousel .prev {+  left: -100%;+}++.carousel .next.left,+.carousel .prev.right {+  left: 0;+}++.carousel .active.left {+  left: -100%;+}++.carousel .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: #ffffff;+  text-align: center;+  background: #222222;+  border: 3px solid #ffffff;+  -webkit-border-radius: 23px;+     -moz-border-radius: 23px;+          border-radius: 23px;+  opacity: 0.5;+  filter: alpha(opacity=50);+}++.carousel-control.right {+  right: 15px;+  left: auto;+}++.carousel-control:hover {+  color: #ffffff;+  text-decoration: none;+  opacity: 0.9;+  filter: alpha(opacity=90);+}++.carousel-caption {+  position: absolute;+  right: 0;+  bottom: 0;+  left: 0;+  padding: 10px 15px 5px;+  background: #333333;+  background: rgba(0, 0, 0, 0.75);+}++.carousel-caption h4,+.carousel-caption p {+  color: #ffffff;+}++.hero-unit {+  padding: 60px;+  margin-bottom: 30px;+  background-color: #eeeeee;+  -webkit-border-radius: 6px;+     -moz-border-radius: 6px;+          border-radius: 6px;+}++.hero-unit h1 {+  margin-bottom: 0;+  font-size: 60px;+  line-height: 1;+  letter-spacing: -1px;+  color: inherit;+}++.hero-unit p {+  font-size: 18px;+  font-weight: 200;+  line-height: 27px;+  color: inherit;+}++.pull-right {+  float: right;+}++.pull-left {+  float: left;+}++.hide {+  display: none;+}++.show {+  display: block;+}++.invisible {+  visibility: hidden;+}
− static/css/bootstrap-responsive.css
@@ -1,815 +0,0 @@-/*!- * Bootstrap Responsive v2.0.4- *- * Copyright 2012 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 @twitter by @mdo and @fat.- */--.clearfix {-  *zoom: 1;-}--.clearfix:before,-.clearfix:after {-  display: table;-  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: 28px;-  -webkit-box-sizing: border-box;-     -moz-box-sizing: border-box;-      -ms-box-sizing: border-box;-          box-sizing: border-box;-}--.hidden {-  display: none;-  visibility: hidden;-}--.visible-phone {-  display: none !important;-}--.visible-tablet {-  display: none !important;-}--.hidden-desktop {-  display: none !important;-}--@media (max-width: 767px) {-  .visible-phone {-    display: inherit !important;-  }-  .hidden-phone {-    display: none !important;-  }-  .hidden-desktop {-    display: inherit !important;-  }-  .visible-desktop {-    display: none !important;-  }-}--@media (min-width: 768px) and (max-width: 979px) {-  .visible-tablet {-    display: inherit !important;-  }-  .hidden-tablet {-    display: none !important;-  }-  .hidden-desktop {-    display: inherit !important;-  }-  .visible-desktop {-    display: none !important ;-  }-}--@media (max-width: 480px) {-  .nav-collapse {-    -webkit-transform: translate3d(0, 0, 0);-  }-  .page-header h1 small {-    display: block;-    line-height: 18px;-  }-  input[type="checkbox"],-  input[type="radio"] {-    border: 1px solid #ccc;-  }-  .form-horizontal .control-group > label {-    float: none;-    width: auto;-    padding-top: 0;-    text-align: left;-  }-  .form-horizontal .controls {-    margin-left: 0;-  }-  .form-horizontal .control-list {-    padding-top: 0;-  }-  .form-horizontal .form-actions {-    padding-right: 10px;-    padding-left: 10px;-  }-  .modal {-    position: absolute;-    top: 10px;-    right: 10px;-    left: 10px;-    width: auto;-    margin: 0;-  }-  .modal.fade.in {-    top: auto;-  }-  .modal-header .close {-    padding: 10px;-    margin: -10px;-  }-  .carousel-caption {-    position: static;-  }-}--@media (max-width: 767px) {-  body {-    padding-right: 20px;-    padding-left: 20px;-  }-  .navbar-fixed-top,-  .navbar-fixed-bottom {-    margin-right: -20px;-    margin-left: -20px;-  }-  .container-fluid {-    padding: 0;-  }-  .dl-horizontal dt {-    float: none;-    width: auto;-    clear: none;-    text-align: left;-  }-  .dl-horizontal dd {-    margin-left: 0;-  }-  .container {-    width: auto;-  }-  .row-fluid {-    width: 100%;-  }-  .row,-  .thumbnails {-    margin-left: 0;-  }-  [class*="span"],-  .row-fluid [class*="span"] {-    display: block;-    float: none;-    width: auto;-    margin-left: 0;-  }-  .input-large,-  .input-xlarge,-  .input-xxlarge,-  input[class*="span"],-  select[class*="span"],-  textarea[class*="span"],-  .uneditable-input {-    display: block;-    width: 100%;-    min-height: 28px;-    -webkit-box-sizing: border-box;-       -moz-box-sizing: border-box;-        -ms-box-sizing: border-box;-            box-sizing: border-box;-  }-  .input-prepend input,-  .input-append input,-  .input-prepend input[class*="span"],-  .input-append input[class*="span"] {-    display: inline-block;-    width: auto;-  }-}--@media (min-width: 768px) and (max-width: 979px) {-  .row {-    margin-left: -20px;-    *zoom: 1;-  }-  .row:before,-  .row:after {-    display: table;-    content: "";-  }-  .row:after {-    clear: both;-  }-  [class*="span"] {-    float: left;-    margin-left: 20px;-  }-  .container,-  .navbar-fixed-top .container,-  .navbar-fixed-bottom .container {-    width: 724px;-  }-  .span12 {-    width: 724px;-  }-  .span11 {-    width: 662px;-  }-  .span10 {-    width: 600px;-  }-  .span9 {-    width: 538px;-  }-  .span8 {-    width: 476px;-  }-  .span7 {-    width: 414px;-  }-  .span6 {-    width: 352px;-  }-  .span5 {-    width: 290px;-  }-  .span4 {-    width: 228px;-  }-  .span3 {-    width: 166px;-  }-  .span2 {-    width: 104px;-  }-  .span1 {-    width: 42px;-  }-  .offset12 {-    margin-left: 764px;-  }-  .offset11 {-    margin-left: 702px;-  }-  .offset10 {-    margin-left: 640px;-  }-  .offset9 {-    margin-left: 578px;-  }-  .offset8 {-    margin-left: 516px;-  }-  .offset7 {-    margin-left: 454px;-  }-  .offset6 {-    margin-left: 392px;-  }-  .offset5 {-    margin-left: 330px;-  }-  .offset4 {-    margin-left: 268px;-  }-  .offset3 {-    margin-left: 206px;-  }-  .offset2 {-    margin-left: 144px;-  }-  .offset1 {-    margin-left: 82px;-  }-  .row-fluid {-    width: 100%;-    *zoom: 1;-  }-  .row-fluid:before,-  .row-fluid:after {-    display: table;-    content: "";-  }-  .row-fluid:after {-    clear: both;-  }-  .row-fluid [class*="span"] {-    display: block;-    float: left;-    width: 100%;-    min-height: 28px;-    margin-left: 2.762430939%;-    *margin-left: 2.709239449638298%;-    -webkit-box-sizing: border-box;-       -moz-box-sizing: border-box;-        -ms-box-sizing: border-box;-            box-sizing: border-box;-  }-  .row-fluid [class*="span"]:first-child {-    margin-left: 0;-  }-  .row-fluid .span12 {-    width: 99.999999993%;-    *width: 99.9468085036383%;-  }-  .row-fluid .span11 {-    width: 91.436464082%;-    *width: 91.38327259263829%;-  }-  .row-fluid .span10 {-    width: 82.87292817100001%;-    *width: 82.8197366816383%;-  }-  .row-fluid .span9 {-    width: 74.30939226%;-    *width: 74.25620077063829%;-  }-  .row-fluid .span8 {-    width: 65.74585634900001%;-    *width: 65.6926648596383%;-  }-  .row-fluid .span7 {-    width: 57.182320438000005%;-    *width: 57.129128948638304%;-  }-  .row-fluid .span6 {-    width: 48.618784527%;-    *width: 48.5655930376383%;-  }-  .row-fluid .span5 {-    width: 40.055248616%;-    *width: 40.0020571266383%;-  }-  .row-fluid .span4 {-    width: 31.491712705%;-    *width: 31.4385212156383%;-  }-  .row-fluid .span3 {-    width: 22.928176794%;-    *width: 22.874985304638297%;-  }-  .row-fluid .span2 {-    width: 14.364640883%;-    *width: 14.311449393638298%;-  }-  .row-fluid .span1 {-    width: 5.801104972%;-    *width: 5.747913482638298%;-  }-  input,-  textarea,-  .uneditable-input {-    margin-left: 0;-  }-  input.span12,-  textarea.span12,-  .uneditable-input.span12 {-    width: 714px;-  }-  input.span11,-  textarea.span11,-  .uneditable-input.span11 {-    width: 652px;-  }-  input.span10,-  textarea.span10,-  .uneditable-input.span10 {-    width: 590px;-  }-  input.span9,-  textarea.span9,-  .uneditable-input.span9 {-    width: 528px;-  }-  input.span8,-  textarea.span8,-  .uneditable-input.span8 {-    width: 466px;-  }-  input.span7,-  textarea.span7,-  .uneditable-input.span7 {-    width: 404px;-  }-  input.span6,-  textarea.span6,-  .uneditable-input.span6 {-    width: 342px;-  }-  input.span5,-  textarea.span5,-  .uneditable-input.span5 {-    width: 280px;-  }-  input.span4,-  textarea.span4,-  .uneditable-input.span4 {-    width: 218px;-  }-  input.span3,-  textarea.span3,-  .uneditable-input.span3 {-    width: 156px;-  }-  input.span2,-  textarea.span2,-  .uneditable-input.span2 {-    width: 94px;-  }-  input.span1,-  textarea.span1,-  .uneditable-input.span1 {-    width: 32px;-  }-}--@media (min-width: 1200px) {-  .row {-    margin-left: -30px;-    *zoom: 1;-  }-  .row:before,-  .row:after {-    display: table;-    content: "";-  }-  .row:after {-    clear: both;-  }-  [class*="span"] {-    float: left;-    margin-left: 30px;-  }-  .container,-  .navbar-fixed-top .container,-  .navbar-fixed-bottom .container {-    width: 1170px;-  }-  .span12 {-    width: 1170px;-  }-  .span11 {-    width: 1070px;-  }-  .span10 {-    width: 970px;-  }-  .span9 {-    width: 870px;-  }-  .span8 {-    width: 770px;-  }-  .span7 {-    width: 670px;-  }-  .span6 {-    width: 570px;-  }-  .span5 {-    width: 470px;-  }-  .span4 {-    width: 370px;-  }-  .span3 {-    width: 270px;-  }-  .span2 {-    width: 170px;-  }-  .span1 {-    width: 70px;-  }-  .offset12 {-    margin-left: 1230px;-  }-  .offset11 {-    margin-left: 1130px;-  }-  .offset10 {-    margin-left: 1030px;-  }-  .offset9 {-    margin-left: 930px;-  }-  .offset8 {-    margin-left: 830px;-  }-  .offset7 {-    margin-left: 730px;-  }-  .offset6 {-    margin-left: 630px;-  }-  .offset5 {-    margin-left: 530px;-  }-  .offset4 {-    margin-left: 430px;-  }-  .offset3 {-    margin-left: 330px;-  }-  .offset2 {-    margin-left: 230px;-  }-  .offset1 {-    margin-left: 130px;-  }-  .row-fluid {-    width: 100%;-    *zoom: 1;-  }-  .row-fluid:before,-  .row-fluid:after {-    display: table;-    content: "";-  }-  .row-fluid:after {-    clear: both;-  }-  .row-fluid [class*="span"] {-    display: block;-    float: left;-    width: 100%;-    min-height: 28px;-    margin-left: 2.564102564%;-    *margin-left: 2.510911074638298%;-    -webkit-box-sizing: border-box;-       -moz-box-sizing: border-box;-        -ms-box-sizing: border-box;-            box-sizing: border-box;-  }-  .row-fluid [class*="span"]:first-child {-    margin-left: 0;-  }-  .row-fluid .span12 {-    width: 100%;-    *width: 99.94680851063829%;-  }-  .row-fluid .span11 {-    width: 91.45299145300001%;-    *width: 91.3997999636383%;-  }-  .row-fluid .span10 {-    width: 82.905982906%;-    *width: 82.8527914166383%;-  }-  .row-fluid .span9 {-    width: 74.358974359%;-    *width: 74.30578286963829%;-  }-  .row-fluid .span8 {-    width: 65.81196581200001%;-    *width: 65.7587743226383%;-  }-  .row-fluid .span7 {-    width: 57.264957265%;-    *width: 57.2117657756383%;-  }-  .row-fluid .span6 {-    width: 48.717948718%;-    *width: 48.6647572286383%;-  }-  .row-fluid .span5 {-    width: 40.170940171000005%;-    *width: 40.117748681638304%;-  }-  .row-fluid .span4 {-    width: 31.623931624%;-    *width: 31.5707401346383%;-  }-  .row-fluid .span3 {-    width: 23.076923077%;-    *width: 23.0237315876383%;-  }-  .row-fluid .span2 {-    width: 14.529914530000001%;-    *width: 14.4767230406383%;-  }-  .row-fluid .span1 {-    width: 5.982905983%;-    *width: 5.929714493638298%;-  }-  input,-  textarea,-  .uneditable-input {-    margin-left: 0;-  }-  input.span12,-  textarea.span12,-  .uneditable-input.span12 {-    width: 1160px;-  }-  input.span11,-  textarea.span11,-  .uneditable-input.span11 {-    width: 1060px;-  }-  input.span10,-  textarea.span10,-  .uneditable-input.span10 {-    width: 960px;-  }-  input.span9,-  textarea.span9,-  .uneditable-input.span9 {-    width: 860px;-  }-  input.span8,-  textarea.span8,-  .uneditable-input.span8 {-    width: 760px;-  }-  input.span7,-  textarea.span7,-  .uneditable-input.span7 {-    width: 660px;-  }-  input.span6,-  textarea.span6,-  .uneditable-input.span6 {-    width: 560px;-  }-  input.span5,-  textarea.span5,-  .uneditable-input.span5 {-    width: 460px;-  }-  input.span4,-  textarea.span4,-  .uneditable-input.span4 {-    width: 360px;-  }-  input.span3,-  textarea.span3,-  .uneditable-input.span3 {-    width: 260px;-  }-  input.span2,-  textarea.span2,-  .uneditable-input.span2 {-    width: 160px;-  }-  input.span1,-  textarea.span1,-  .uneditable-input.span1 {-    width: 60px;-  }-  .thumbnails {-    margin-left: -30px;-  }-  .thumbnails > li {-    margin-left: 30px;-  }-  .row-fluid .thumbnails {-    margin-left: 0;-  }-}--@media (max-width: 979px) {-  body {-    padding-top: 0;-  }-  .navbar-fixed-top,-  .navbar-fixed-bottom {-    position: static;-  }-  .navbar-fixed-top {-    margin-bottom: 18px;-  }-  .navbar-fixed-bottom {-    margin-top: 18px;-  }-  .navbar-fixed-top .navbar-inner,-  .navbar-fixed-bottom .navbar-inner {-    padding: 5px;-  }-  .navbar .container {-    width: auto;-    padding: 0;-  }-  .navbar .brand {-    padding-right: 10px;-    padding-left: 10px;-    margin: 0 0 0 -5px;-  }-  .nav-collapse {-    clear: both;-  }-  .nav-collapse .nav {-    float: none;-    margin: 0 0 9px;-  }-  .nav-collapse .nav > li {-    float: none;-  }-  .nav-collapse .nav > li > a {-    margin-bottom: 2px;-  }-  .nav-collapse .nav > .divider-vertical {-    display: none;-  }-  .nav-collapse .nav .nav-header {-    color: #999999;-    text-shadow: none;-  }-  .nav-collapse .nav > li > a,-  .nav-collapse .dropdown-menu a {-    padding: 6px 15px;-    font-weight: bold;-    color: #999999;-    -webkit-border-radius: 3px;-       -moz-border-radius: 3px;-            border-radius: 3px;-  }-  .nav-collapse .btn {-    padding: 4px 10px 4px;-    font-weight: normal;-    -webkit-border-radius: 4px;-       -moz-border-radius: 4px;-            border-radius: 4px;-  }-  .nav-collapse .dropdown-menu li + li a {-    margin-bottom: 2px;-  }-  .nav-collapse .nav > li > a:hover,-  .nav-collapse .dropdown-menu a:hover {-    background-color: #222222;-  }-  .nav-collapse.in .btn-group {-    padding: 0;-    margin-top: 5px;-  }-  .nav-collapse .dropdown-menu {-    position: static;-    top: auto;-    left: auto;-    display: block;-    float: none;-    max-width: none;-    padding: 0;-    margin: 0 15px;-    background-color: transparent;-    border: none;-    -webkit-border-radius: 0;-       -moz-border-radius: 0;-            border-radius: 0;-    -webkit-box-shadow: none;-       -moz-box-shadow: none;-            box-shadow: none;-  }-  .nav-collapse .dropdown-menu:before,-  .nav-collapse .dropdown-menu:after {-    display: none;-  }-  .nav-collapse .dropdown-menu .divider {-    display: none;-  }-  .nav-collapse .navbar-form,-  .nav-collapse .navbar-search {-    float: none;-    padding: 9px 15px;-    margin: 9px 0;-    border-top: 1px solid #222222;-    border-bottom: 1px solid #222222;-    -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);-       -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);-            box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);-  }-  .navbar .nav-collapse .nav.pull-right {-    float: none;-    margin-left: 0;-  }-  .nav-collapse,-  .nav-collapse.collapse {-    height: 0;-    overflow: hidden;-  }-  .navbar .btn-navbar {-    display: block;-  }-  .navbar-static .navbar-inner {-    padding-right: 10px;-    padding-left: 10px;-  }-}--@media (min-width: 980px) {-  .nav-collapse.collapse {-    height: auto !important;-    overflow: visible !important;-  }-}
− static/css/bootstrap.css
@@ -1,4983 +0,0 @@-/*!- * Bootstrap v2.0.4- *- * Copyright 2012 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 @twitter by @mdo and @fat.- */--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 {-  max-width: 100%;-  vertical-align: middle;-  border: 0;-  -ms-interpolation-mode: bicubic;-}--#map_canvas 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,-input[type="button"],-input[type="reset"],-input[type="submit"] {-  cursor: pointer;-  -webkit-appearance: button;-}--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;-}--.clearfix {-  *zoom: 1;-}--.clearfix:before,-.clearfix:after {-  display: table;-  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: 28px;-  -webkit-box-sizing: border-box;-     -moz-box-sizing: border-box;-      -ms-box-sizing: border-box;-          box-sizing: border-box;-}--body {-  margin: 0;-  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;-  font-size: 13px;-  line-height: 18px;-  color: #333333;-  background-color: #ffffff;-}--a {-  color: #0088cc;-  text-decoration: none;-}--a:hover {-  color: #005580;-  text-decoration: underline;-}--.row {-  margin-left: -20px;-  *zoom: 1;-}--.row:before,-.row:after {-  display: table;-  content: "";-}--.row:after {-  clear: both;-}--[class*="span"] {-  float: left;-  margin-left: 20px;-}--.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;-  content: "";-}--.row-fluid:after {-  clear: both;-}--.row-fluid [class*="span"] {-  display: block;-  float: left;-  width: 100%;-  min-height: 28px;-  margin-left: 2.127659574%;-  *margin-left: 2.0744680846382977%;-  -webkit-box-sizing: border-box;-     -moz-box-sizing: border-box;-      -ms-box-sizing: border-box;-          box-sizing: border-box;-}--.row-fluid [class*="span"]:first-child {-  margin-left: 0;-}--.row-fluid .span12 {-  width: 99.99999998999999%;-  *width: 99.94680850063828%;-}--.row-fluid .span11 {-  width: 91.489361693%;-  *width: 91.4361702036383%;-}--.row-fluid .span10 {-  width: 82.97872339599999%;-  *width: 82.92553190663828%;-}--.row-fluid .span9 {-  width: 74.468085099%;-  *width: 74.4148936096383%;-}--.row-fluid .span8 {-  width: 65.95744680199999%;-  *width: 65.90425531263828%;-}--.row-fluid .span7 {-  width: 57.446808505%;-  *width: 57.3936170156383%;-}--.row-fluid .span6 {-  width: 48.93617020799999%;-  *width: 48.88297871863829%;-}--.row-fluid .span5 {-  width: 40.425531911%;-  *width: 40.3723404216383%;-}--.row-fluid .span4 {-  width: 31.914893614%;-  *width: 31.8617021246383%;-}--.row-fluid .span3 {-  width: 23.404255317%;-  *width: 23.3510638276383%;-}--.row-fluid .span2 {-  width: 14.89361702%;-  *width: 14.8404255306383%;-}--.row-fluid .span1 {-  width: 6.382978723%;-  *width: 6.329787233638298%;-}--.container {-  margin-right: auto;-  margin-left: auto;-  *zoom: 1;-}--.container:before,-.container:after {-  display: table;-  content: "";-}--.container:after {-  clear: both;-}--.container-fluid {-  padding-right: 20px;-  padding-left: 20px;-  *zoom: 1;-}--.container-fluid:before,-.container-fluid:after {-  display: table;-  content: "";-}--.container-fluid:after {-  clear: both;-}--p {-  margin: 0 0 9px;-}--p small {-  font-size: 11px;-  color: #999999;-}--.lead {-  margin-bottom: 18px;-  font-size: 20px;-  font-weight: 200;-  line-height: 27px;-}--h1,-h2,-h3,-h4,-h5,-h6 {-  margin: 0;-  font-family: inherit;-  font-weight: bold;-  color: inherit;-  text-rendering: optimizelegibility;-}--h1 small,-h2 small,-h3 small,-h4 small,-h5 small,-h6 small {-  font-weight: normal;-  color: #999999;-}--h1 {-  font-size: 30px;-  line-height: 36px;-}--h1 small {-  font-size: 18px;-}--h2 {-  font-size: 24px;-  line-height: 36px;-}--h2 small {-  font-size: 18px;-}--h3 {-  font-size: 18px;-  line-height: 27px;-}--h3 small {-  font-size: 14px;-}--h4,-h5,-h6 {-  line-height: 18px;-}--h4 {-  font-size: 14px;-}--h4 small {-  font-size: 12px;-}--h5 {-  font-size: 12px;-}--h6 {-  font-size: 11px;-  color: #999999;-  text-transform: uppercase;-}--.page-header {-  padding-bottom: 17px;-  margin: 18px 0;-  border-bottom: 1px solid #eeeeee;-}--.page-header h1 {-  line-height: 1;-}--ul,-ol {-  padding: 0;-  margin: 0 0 9px 25px;-}--ul ul,-ul ol,-ol ol,-ol ul {-  margin-bottom: 0;-}--ul {-  list-style: disc;-}--ol {-  list-style: decimal;-}--li {-  line-height: 18px;-}--ul.unstyled,-ol.unstyled {-  margin-left: 0;-  list-style: none;-}--dl {-  margin-bottom: 18px;-}--dt,-dd {-  line-height: 18px;-}--dt {-  font-weight: bold;-  line-height: 17px;-}--dd {-  margin-left: 9px;-}--.dl-horizontal dt {-  float: left;-  width: 120px;-  overflow: hidden;-  clear: left;-  text-align: right;-  text-overflow: ellipsis;-  white-space: nowrap;-}--.dl-horizontal dd {-  margin-left: 130px;-}--hr {-  margin: 18px 0;-  border: 0;-  border-top: 1px solid #eeeeee;-  border-bottom: 1px solid #ffffff;-}--strong {-  font-weight: bold;-}--em {-  font-style: italic;-}--.muted {-  color: #999999;-}--abbr[title] {-  cursor: help;-  border-bottom: 1px dotted #999999;-}--abbr.initialism {-  font-size: 90%;-  text-transform: uppercase;-}--blockquote {-  padding: 0 0 0 15px;-  margin: 0 0 18px;-  border-left: 5px solid #eeeeee;-}--blockquote p {-  margin-bottom: 0;-  font-size: 16px;-  font-weight: 300;-  line-height: 22.5px;-}--blockquote small {-  display: block;-  line-height: 18px;-  color: #999999;-}--blockquote small:before {-  content: '\2014 \00A0';-}--blockquote.pull-right {-  float: right;-  padding-right: 15px;-  padding-left: 0;-  border-right: 5px solid #eeeeee;-  border-left: 0;-}--blockquote.pull-right p,-blockquote.pull-right small {-  text-align: right;-}--q:before,-q:after,-blockquote:before,-blockquote:after {-  content: "";-}--address {-  display: block;-  margin-bottom: 18px;-  font-style: normal;-  line-height: 18px;-}--small {-  font-size: 100%;-}--cite {-  font-style: normal;-}--code,-pre {-  padding: 0 3px 2px;-  font-family: Menlo, Monaco, Consolas, "Courier New", monospace;-  font-size: 12px;-  color: #333333;-  -webkit-border-radius: 3px;-     -moz-border-radius: 3px;-          border-radius: 3px;-}--code {-  padding: 2px 4px;-  color: #d14;-  background-color: #f7f7f9;-  border: 1px solid #e1e1e8;-}--pre {-  display: block;-  padding: 8.5px;-  margin: 0 0 9px;-  font-size: 12.025px;-  line-height: 18px;-  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: 18px;-}--pre code {-  padding: 0;-  color: inherit;-  background-color: transparent;-  border: 0;-}--.pre-scrollable {-  max-height: 340px;-  overflow-y: scroll;-}--form {-  margin: 0 0 18px;-}--fieldset {-  padding: 0;-  margin: 0;-  border: 0;-}--legend {-  display: block;-  width: 100%;-  padding: 0;-  margin-bottom: 27px;-  font-size: 19.5px;-  line-height: 36px;-  color: #333333;-  border: 0;-  border-bottom: 1px solid #e5e5e5;-}--legend small {-  font-size: 13.5px;-  color: #999999;-}--label,-input,-button,-select,-textarea {-  font-size: 13px;-  font-weight: normal;-  line-height: 18px;-}--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: 18px;-  padding: 4px;-  margin-bottom: 9px;-  font-size: 13px;-  line-height: 18px;-  color: #555555;-}--input,-textarea {-  width: 210px;-}--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: #ffffff;-  border: 1px solid #cccccc;-  -webkit-border-radius: 3px;-     -moz-border-radius: 3px;-          border-radius: 3px;-  -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 0.2s, box-shadow linear 0.2s;-     -moz-transition: border linear 0.2s, box-shadow linear 0.2s;-      -ms-transition: border linear 0.2s, box-shadow linear 0.2s;-       -o-transition: border linear 0.2s, box-shadow linear 0.2s;-          transition: border linear 0.2s, box-shadow linear 0.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;-  /* IE6-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: 3px 0;-  *margin-top: 0;-  /* IE7 */--  line-height: normal;-  cursor: pointer;-}--input[type="submit"],-input[type="reset"],-input[type="button"],-input[type="radio"],-input[type="checkbox"] {-  width: auto;-}--.uneditable-textarea {-  width: auto;-  height: auto;-}--select,-input[type="file"] {-  height: 28px;-  /* In IE7, the height of the select element cannot be changed by height, only font-size */--  *margin-top: 4px;-  /* For IE7, add top margin to align select with labels */--  line-height: 28px;-}--select {-  width: 220px;-  border: 1px solid #bbb;-}--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;-}--.radio,-.checkbox {-  min-height: 18px;-  padding-left: 18px;-}--.radio input[type="radio"],-.checkbox input[type="checkbox"] {-  float: left;-  margin-left: -18px;-}--.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-prepend [class*="span"],-.row-fluid .input-append [class*="span"] {-  display: inline-block;-}--input,-textarea,-.uneditable-input {-  margin-left: 0;-}--input.span12,-textarea.span12,-.uneditable-input.span12 {-  width: 930px;-}--input.span11,-textarea.span11,-.uneditable-input.span11 {-  width: 850px;-}--input.span10,-textarea.span10,-.uneditable-input.span10 {-  width: 770px;-}--input.span9,-textarea.span9,-.uneditable-input.span9 {-  width: 690px;-}--input.span8,-textarea.span8,-.uneditable-input.span8 {-  width: 610px;-}--input.span7,-textarea.span7,-.uneditable-input.span7 {-  width: 530px;-}--input.span6,-textarea.span6,-.uneditable-input.span6 {-  width: 450px;-}--input.span5,-textarea.span5,-.uneditable-input.span5 {-  width: 370px;-}--input.span4,-textarea.span4,-.uneditable-input.span4 {-  width: 290px;-}--input.span3,-textarea.span3,-.uneditable-input.span3 {-  width: 210px;-}--input.span2,-textarea.span2,-.uneditable-input.span2 {-  width: 130px;-}--input.span1,-textarea.span1,-.uneditable-input.span1 {-  width: 50px;-}--input[disabled],-select[disabled],-textarea[disabled],-input[readonly],-select[readonly],-textarea[readonly] {-  cursor: not-allowed;-  background-color: #eeeeee;-  border-color: #ddd;-}--input[type="radio"][disabled],-input[type="checkbox"][disabled],-input[type="radio"][readonly],-input[type="checkbox"][readonly] {-  background-color: transparent;-}--.control-group.warning > 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;-  border-color: #c09853;-}--.control-group.warning .checkbox:focus,-.control-group.warning .radio:focus,-.control-group.warning input:focus,-.control-group.warning select:focus,-.control-group.warning textarea:focus {-  border-color: #a47e3c;-  -webkit-box-shadow: 0 0 6px #dbc59e;-     -moz-box-shadow: 0 0 6px #dbc59e;-          box-shadow: 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 > 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;-  border-color: #b94a48;-}--.control-group.error .checkbox:focus,-.control-group.error .radio:focus,-.control-group.error input:focus,-.control-group.error select:focus,-.control-group.error textarea:focus {-  border-color: #953b39;-  -webkit-box-shadow: 0 0 6px #d59392;-     -moz-box-shadow: 0 0 6px #d59392;-          box-shadow: 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 > 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;-  border-color: #468847;-}--.control-group.success .checkbox:focus,-.control-group.success .radio:focus,-.control-group.success input:focus,-.control-group.success select:focus,-.control-group.success textarea:focus {-  border-color: #356635;-  -webkit-box-shadow: 0 0 6px #7aba7b;-     -moz-box-shadow: 0 0 6px #7aba7b;-          box-shadow: 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;-}--input:focus:required:invalid,-textarea:focus:required:invalid,-select:focus:required:invalid {-  color: #b94a48;-  border-color: #ee5f5b;-}--input:focus:required:invalid:focus,-textarea:focus:required:invalid:focus,-select:focus:required:invalid:focus {-  border-color: #e9322d;-  -webkit-box-shadow: 0 0 6px #f8b9b7;-     -moz-box-shadow: 0 0 6px #f8b9b7;-          box-shadow: 0 0 6px #f8b9b7;-}--.form-actions {-  padding: 17px 20px 18px;-  margin-top: 18px;-  margin-bottom: 18px;-  background-color: #f5f5f5;-  border-top: 1px solid #e5e5e5;-  *zoom: 1;-}--.form-actions:before,-.form-actions:after {-  display: table;-  content: "";-}--.form-actions:after {-  clear: both;-}--.uneditable-input {-  overflow: hidden;-  white-space: nowrap;-  cursor: not-allowed;-  background-color: #ffffff;-  border-color: #eee;-  -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);-}--:-moz-placeholder {-  color: #999999;-}--:-ms-input-placeholder {-  color: #999999;-}--::-webkit-input-placeholder {-  color: #999999;-}--.help-block,-.help-inline {-  color: #555555;-}--.help-block {-  display: block;-  margin-bottom: 9px;-}--.help-inline {-  display: inline-block;-  *display: inline;-  padding-left: 5px;-  vertical-align: middle;-  *zoom: 1;-}--.input-prepend,-.input-append {-  margin-bottom: 5px;-}--.input-prepend input,-.input-append input,-.input-prepend select,-.input-append select,-.input-prepend .uneditable-input,-.input-append .uneditable-input {-  position: relative;-  margin-bottom: 0;-  *margin-left: 0;-  vertical-align: middle;-  -webkit-border-radius: 0 3px 3px 0;-     -moz-border-radius: 0 3px 3px 0;-          border-radius: 0 3px 3px 0;-}--.input-prepend input:focus,-.input-append input:focus,-.input-prepend select:focus,-.input-append select:focus,-.input-prepend .uneditable-input:focus,-.input-append .uneditable-input:focus {-  z-index: 2;-}--.input-prepend .uneditable-input,-.input-append .uneditable-input {-  border-left-color: #ccc;-}--.input-prepend .add-on,-.input-append .add-on {-  display: inline-block;-  width: auto;-  height: 18px;-  min-width: 16px;-  padding: 4px 5px;-  font-weight: normal;-  line-height: 18px;-  text-align: center;-  text-shadow: 0 1px 0 #ffffff;-  vertical-align: middle;-  background-color: #eeeeee;-  border: 1px solid #ccc;-}--.input-prepend .add-on,-.input-append .add-on,-.input-prepend .btn,-.input-append .btn {-  margin-left: -1px;-  -webkit-border-radius: 0;-     -moz-border-radius: 0;-          border-radius: 0;-}--.input-prepend .active,-.input-append .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: 3px 0 0 3px;-     -moz-border-radius: 3px 0 0 3px;-          border-radius: 3px 0 0 3px;-}--.input-append input,-.input-append select,-.input-append .uneditable-input {-  -webkit-border-radius: 3px 0 0 3px;-     -moz-border-radius: 3px 0 0 3px;-          border-radius: 3px 0 0 3px;-}--.input-append .uneditable-input {-  border-right-color: #ccc;-  border-left-color: #eee;-}--.input-append .add-on:last-child,-.input-append .btn:last-child {-  -webkit-border-radius: 0 3px 3px 0;-     -moz-border-radius: 0 3px 3px 0;-          border-radius: 0 3px 3px 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 .add-on:first-child,-.input-prepend.input-append .btn:first-child {-  margin-right: -1px;-  -webkit-border-radius: 3px 0 0 3px;-     -moz-border-radius: 3px 0 0 3px;-          border-radius: 3px 0 0 3px;-}--.input-prepend.input-append .add-on:last-child,-.input-prepend.input-append .btn:last-child {-  margin-left: -1px;-  -webkit-border-radius: 0 3px 3px 0;-     -moz-border-radius: 0 3px 3px 0;-          border-radius: 0 3px 3px 0;-}--.search-query {-  padding-right: 14px;-  padding-right: 4px \9;-  padding-left: 14px;-  padding-left: 4px \9;-  /* IE7-8 doesn't have border-radius, so don't indent the padding */--  margin-bottom: 0;-  -webkit-border-radius: 14px;-     -moz-border-radius: 14px;-          border-radius: 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;-  *zoom: 1;-}--.form-search .hide,-.form-inline .hide,-.form-horizontal .hide {-  display: none;-}--.form-search label,-.form-inline label {-  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: 9px;-}--legend + .control-group {-  margin-top: 18px;-  -webkit-margin-top-collapse: separate;-}--.form-horizontal .control-group {-  margin-bottom: 18px;-  *zoom: 1;-}--.form-horizontal .control-group:before,-.form-horizontal .control-group:after {-  display: table;-  content: "";-}--.form-horizontal .control-group:after {-  clear: both;-}--.form-horizontal .control-label {-  float: left;-  width: 140px;-  padding-top: 5px;-  text-align: right;-}--.form-horizontal .controls {-  *display: inline-block;-  *padding-left: 20px;-  margin-left: 160px;-  *margin-left: 0;-}--.form-horizontal .controls:first-child {-  *padding-left: 160px;-}--.form-horizontal .help-block {-  margin-top: 9px;-  margin-bottom: 0;-}--.form-horizontal .form-actions {-  padding-left: 160px;-}--table {-  max-width: 100%;-  background-color: transparent;-  border-collapse: collapse;-  border-spacing: 0;-}--.table {-  width: 100%;-  margin-bottom: 18px;-}--.table th,-.table td {-  padding: 8px;-  line-height: 18px;-  text-align: left;-  vertical-align: top;-  border-top: 1px solid #dddddd;-}--.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 #dddddd;-}--.table-condensed th,-.table-condensed td {-  padding: 4px 5px;-}--.table-bordered {-  border: 1px solid #dddddd;-  border-collapse: separate;-  *border-collapse: collapsed;-  border-left: 0;-  -webkit-border-radius: 4px;-     -moz-border-radius: 4px;-          border-radius: 4px;-}--.table-bordered th,-.table-bordered td {-  border-left: 1px solid #dddddd;-}--.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 {-  -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 {-  -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 {-  -webkit-border-radius: 0 0 0 4px;-     -moz-border-radius: 0 0 0 4px;-          border-radius: 0 0 0 4px;-  -webkit-border-bottom-left-radius: 4px;-          border-bottom-left-radius: 4px;-  -moz-border-radius-bottomleft: 4px;-}--.table-bordered thead:last-child tr:last-child th:last-child,-.table-bordered tbody:last-child tr:last-child td:last-child {-  -webkit-border-bottom-right-radius: 4px;-          border-bottom-right-radius: 4px;-  -moz-border-radius-bottomright: 4px;-}--.table-striped tbody tr:nth-child(odd) td,-.table-striped tbody tr:nth-child(odd) th {-  background-color: #f9f9f9;-}--.table tbody tr:hover td,-.table tbody tr:hover th {-  background-color: #f5f5f5;-}--table .span1 {-  float: none;-  width: 44px;-  margin-left: 0;-}--table .span2 {-  float: none;-  width: 124px;-  margin-left: 0;-}--table .span3 {-  float: none;-  width: 204px;-  margin-left: 0;-}--table .span4 {-  float: none;-  width: 284px;-  margin-left: 0;-}--table .span5 {-  float: none;-  width: 364px;-  margin-left: 0;-}--table .span6 {-  float: none;-  width: 444px;-  margin-left: 0;-}--table .span7 {-  float: none;-  width: 524px;-  margin-left: 0;-}--table .span8 {-  float: none;-  width: 604px;-  margin-left: 0;-}--table .span9 {-  float: none;-  width: 684px;-  margin-left: 0;-}--table .span10 {-  float: none;-  width: 764px;-  margin-left: 0;-}--table .span11 {-  float: none;-  width: 844px;-  margin-left: 0;-}--table .span12 {-  float: none;-  width: 924px;-  margin-left: 0;-}--table .span13 {-  float: none;-  width: 1004px;-  margin-left: 0;-}--table .span14 {-  float: none;-  width: 1084px;-  margin-left: 0;-}--table .span15 {-  float: none;-  width: 1164px;-  margin-left: 0;-}--table .span16 {-  float: none;-  width: 1244px;-  margin-left: 0;-}--table .span17 {-  float: none;-  width: 1324px;-  margin-left: 0;-}--table .span18 {-  float: none;-  width: 1404px;-  margin-left: 0;-}--table .span19 {-  float: none;-  width: 1484px;-  margin-left: 0;-}--table .span20 {-  float: none;-  width: 1564px;-  margin-left: 0;-}--table .span21 {-  float: none;-  width: 1644px;-  margin-left: 0;-}--table .span22 {-  float: none;-  width: 1724px;-  margin-left: 0;-}--table .span23 {-  float: none;-  width: 1804px;-  margin-left: 0;-}--table .span24 {-  float: none;-  width: 1884px;-  margin-left: 0;-}--[class^="icon-"],-[class*=" icon-"] {-  display: inline-block;-  width: 14px;-  height: 14px;-  *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;-}--[class^="icon-"]:last-child,-[class*=" icon-"]:last-child {-  *margin-left: 0;-}--.icon-white {-  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 {-  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 {-  background-position: -384px -120px;-}--.icon-folder-open {-  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 #000000;-  border-right: 4px solid transparent;-  border-left: 4px solid transparent;-  content: "";-  opacity: 0.3;-  filter: alpha(opacity=30);-}--.dropdown .caret {-  margin-top: 8px;-  margin-left: 2px;-}--.dropdown:hover .caret,-.open .caret {-  opacity: 1;-  filter: alpha(opacity=100);-}--.dropdown-menu {-  position: absolute;-  top: 100%;-  left: 0;-  z-index: 1000;-  display: none;-  float: left;-  min-width: 160px;-  padding: 4px 0;-  margin: 1px 0 0;-  list-style: none;-  background-color: #ffffff;-  border: 1px solid #ccc;-  border: 1px solid rgba(0, 0, 0, 0.2);-  *border-right-width: 2px;-  *border-bottom-width: 2px;-  -webkit-border-radius: 5px;-     -moz-border-radius: 5px;-          border-radius: 5px;-  -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: 8px 1px;-  *margin: -5px 0 5px;-  overflow: hidden;-  background-color: #e5e5e5;-  border-bottom: 1px solid #ffffff;-}--.dropdown-menu a {-  display: block;-  padding: 3px 15px;-  clear: both;-  font-weight: normal;-  line-height: 18px;-  color: #333333;-  white-space: nowrap;-}--.dropdown-menu li > a:hover,-.dropdown-menu .active > a,-.dropdown-menu .active > a:hover {-  color: #ffffff;-  text-decoration: none;-  background-color: #0088cc;-}--.open {-  *z-index: 1000;-}--.open > .dropdown-menu {-  display: block;-}--.pull-right > .dropdown-menu {-  right: 0;-  left: auto;-}--.dropup .caret,-.navbar-fixed-bottom .dropdown .caret {-  border-top: 0;-  border-bottom: 4px solid #000000;-  content: "\2191";-}--.dropup .dropdown-menu,-.navbar-fixed-bottom .dropdown .dropdown-menu {-  top: auto;-  bottom: 100%;-  margin-bottom: 1px;-}--.typeahead {-  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 #eee;-  border: 1px solid rgba(0, 0, 0, 0.05);-  -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 0.15s linear;-     -moz-transition: opacity 0.15s linear;-      -ms-transition: opacity 0.15s linear;-       -o-transition: opacity 0.15s linear;-          transition: opacity 0.15s linear;-}--.fade.in {-  opacity: 1;-}--.collapse {-  position: relative;-  height: 0;-  overflow: hidden;-  -webkit-transition: height 0.35s ease;-     -moz-transition: height 0.35s ease;-      -ms-transition: height 0.35s ease;-       -o-transition: height 0.35s ease;-          transition: height 0.35s ease;-}--.collapse.in {-  height: auto;-}--.close {-  float: right;-  font-size: 20px;-  font-weight: bold;-  line-height: 18px;-  color: #000000;-  text-shadow: 0 1px 0 #ffffff;-  opacity: 0.2;-  filter: alpha(opacity=20);-}--.close:hover {-  color: #000000;-  text-decoration: none;-  cursor: pointer;-  opacity: 0.4;-  filter: alpha(opacity=40);-}--button.close {-  padding: 0;-  cursor: pointer;-  background: transparent;-  border: 0;-  -webkit-appearance: none;-}--.btn {-  display: inline-block;-  *display: inline;-  padding: 4px 10px 4px;-  margin-bottom: 0;-  *margin-left: .3em;-  font-size: 13px;-  line-height: 18px;-  *line-height: 20px;-  color: #333333;-  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: -ms-linear-gradient(top, #ffffff, #e6e6e6);-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));-  background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);-  background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);-  background-image: linear-gradient(top, #ffffff, #e6e6e6);-  background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);-  background-repeat: repeat-x;-  border: 1px solid #cccccc;-  *border: 0;-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);-  border-color: #e6e6e6 #e6e6e6 #bfbfbf;-  border-bottom-color: #b3b3b3;-  -webkit-border-radius: 4px;-     -moz-border-radius: 4px;-          border-radius: 4px;-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', 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:active,-.btn.active,-.btn.disabled,-.btn[disabled] {-  background-color: #e6e6e6;-  *background-color: #d9d9d9;-}--.btn:active,-.btn.active {-  background-color: #cccccc \9;-}--.btn:first-child {-  *margin-left: 0;-}--.btn:hover {-  color: #333333;-  text-decoration: none;-  background-color: #e6e6e6;-  *background-color: #d9d9d9;-  /* Buttons in IE7 don't get borders, so darken on hover */--  background-position: 0 -15px;-  -webkit-transition: background-position 0.1s linear;-     -moz-transition: background-position 0.1s linear;-      -ms-transition: background-position 0.1s linear;-       -o-transition: background-position 0.1s linear;-          transition: background-position 0.1s linear;-}--.btn:focus {-  outline: thin dotted #333;-  outline: 5px auto -webkit-focus-ring-color;-  outline-offset: -2px;-}--.btn.active,-.btn:active {-  background-color: #e6e6e6;-  background-color: #d9d9d9 \9;-  background-image: none;-  outline: 0;-  -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 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-color: #e6e6e6;-  background-image: none;-  opacity: 0.65;-  filter: alpha(opacity=65);-  -webkit-box-shadow: none;-     -moz-box-shadow: none;-          box-shadow: none;-}--.btn-large {-  padding: 9px 14px;-  font-size: 15px;-  line-height: normal;-  -webkit-border-radius: 5px;-     -moz-border-radius: 5px;-          border-radius: 5px;-}--.btn-large [class^="icon-"] {-  margin-top: 1px;-}--.btn-small {-  padding: 5px 9px;-  font-size: 11px;-  line-height: 16px;-}--.btn-small [class^="icon-"] {-  margin-top: -1px;-}--.btn-mini {-  padding: 2px 6px;-  font-size: 11px;-  line-height: 14px;-}--.btn-primary,-.btn-primary:hover,-.btn-warning,-.btn-warning:hover,-.btn-danger,-.btn-danger:hover,-.btn-success,-.btn-success:hover,-.btn-info,-.btn-info:hover,-.btn-inverse,-.btn-inverse:hover {-  color: #ffffff;-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);-}--.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 {-  border-color: #ccc;-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);-}--.btn-primary {-  background-color: #0074cc;-  *background-color: #0055cc;-  background-image: -ms-linear-gradient(top, #0088cc, #0055cc);-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0055cc));-  background-image: -webkit-linear-gradient(top, #0088cc, #0055cc);-  background-image: -o-linear-gradient(top, #0088cc, #0055cc);-  background-image: -moz-linear-gradient(top, #0088cc, #0055cc);-  background-image: linear-gradient(top, #0088cc, #0055cc);-  background-repeat: repeat-x;-  border-color: #0055cc #0055cc #003580;-  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='#0088cc', endColorstr='#0055cc', GradientType=0);-  filter: progid:dximagetransform.microsoft.gradient(enabled=false);-}--.btn-primary:hover,-.btn-primary:active,-.btn-primary.active,-.btn-primary.disabled,-.btn-primary[disabled] {-  background-color: #0055cc;-  *background-color: #004ab3;-}--.btn-primary:active,-.btn-primary.active {-  background-color: #004099 \9;-}--.btn-warning {-  background-color: #faa732;-  *background-color: #f89406;-  background-image: -ms-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: -moz-linear-gradient(top, #fbb450, #f89406);-  background-image: linear-gradient(top, #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='#fbb450', endColorstr='#f89406', GradientType=0);-  filter: progid:dximagetransform.microsoft.gradient(enabled=false);-}--.btn-warning:hover,-.btn-warning:active,-.btn-warning.active,-.btn-warning.disabled,-.btn-warning[disabled] {-  background-color: #f89406;-  *background-color: #df8505;-}--.btn-warning:active,-.btn-warning.active {-  background-color: #c67605 \9;-}--.btn-danger {-  background-color: #da4f49;-  *background-color: #bd362f;-  background-image: -ms-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: -moz-linear-gradient(top, #ee5f5b, #bd362f);-  background-image: linear-gradient(top, #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='#ee5f5b', endColorstr='#bd362f', GradientType=0);-  filter: progid:dximagetransform.microsoft.gradient(enabled=false);-}--.btn-danger:hover,-.btn-danger:active,-.btn-danger.active,-.btn-danger.disabled,-.btn-danger[disabled] {-  background-color: #bd362f;-  *background-color: #a9302a;-}--.btn-danger:active,-.btn-danger.active {-  background-color: #942a25 \9;-}--.btn-success {-  background-color: #5bb75b;-  *background-color: #51a351;-  background-image: -ms-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: -moz-linear-gradient(top, #62c462, #51a351);-  background-image: linear-gradient(top, #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='#62c462', endColorstr='#51a351', GradientType=0);-  filter: progid:dximagetransform.microsoft.gradient(enabled=false);-}--.btn-success:hover,-.btn-success:active,-.btn-success.active,-.btn-success.disabled,-.btn-success[disabled] {-  background-color: #51a351;-  *background-color: #499249;-}--.btn-success:active,-.btn-success.active {-  background-color: #408140 \9;-}--.btn-info {-  background-color: #49afcd;-  *background-color: #2f96b4;-  background-image: -ms-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: -moz-linear-gradient(top, #5bc0de, #2f96b4);-  background-image: linear-gradient(top, #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='#5bc0de', endColorstr='#2f96b4', GradientType=0);-  filter: progid:dximagetransform.microsoft.gradient(enabled=false);-}--.btn-info:hover,-.btn-info:active,-.btn-info.active,-.btn-info.disabled,-.btn-info[disabled] {-  background-color: #2f96b4;-  *background-color: #2a85a0;-}--.btn-info:active,-.btn-info.active {-  background-color: #24748c \9;-}--.btn-inverse {-  background-color: #414141;-  *background-color: #222222;-  background-image: -ms-linear-gradient(top, #555555, #222222);-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#555555), to(#222222));-  background-image: -webkit-linear-gradient(top, #555555, #222222);-  background-image: -o-linear-gradient(top, #555555, #222222);-  background-image: -moz-linear-gradient(top, #555555, #222222);-  background-image: linear-gradient(top, #555555, #222222);-  background-repeat: repeat-x;-  border-color: #222222 #222222 #000000;-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#555555', endColorstr='#222222', GradientType=0);-  filter: progid:dximagetransform.microsoft.gradient(enabled=false);-}--.btn-inverse:hover,-.btn-inverse:active,-.btn-inverse.active,-.btn-inverse.disabled,-.btn-inverse[disabled] {-  background-color: #222222;-  *background-color: #151515;-}--.btn-inverse:active,-.btn-inverse.active {-  background-color: #080808 \9;-}--button.btn,-input[type="submit"].btn {-  *padding-top: 2px;-  *padding-bottom: 2px;-}--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-group {-  position: relative;-  *margin-left: .3em;-  *zoom: 1;-}--.btn-group:before,-.btn-group:after {-  display: table;-  content: "";-}--.btn-group:after {-  clear: both;-}--.btn-group:first-child {-  *margin-left: 0;-}--.btn-group + .btn-group {-  margin-left: 5px;-}--.btn-toolbar {-  margin-top: 9px;-  margin-bottom: 9px;-}--.btn-toolbar .btn-group {-  display: inline-block;-  *display: inline;-  /* IE7 inline-block hack */--  *zoom: 1;-}--.btn-group > .btn {-  position: relative;-  float: left;-  margin-left: -1px;-  -webkit-border-radius: 0;-     -moz-border-radius: 0;-          border-radius: 0;-}--.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 > .dropdown-toggle {-  *padding-top: 4px;-  padding-right: 8px;-  *padding-bottom: 4px;-  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-right: 5px;-  padding-left: 5px;-}--.btn-group > .btn-small.dropdown-toggle {-  *padding-top: 4px;-  *padding-bottom: 4px;-}--.btn-group > .btn-large.dropdown-toggle {-  padding-right: 12px;-  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: #0055cc;-}--.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: #222222;-}--.btn .caret {-  margin-top: 7px;-  margin-left: 0;-}--.btn:hover .caret,-.open.btn-group .caret {-  opacity: 1;-  filter: alpha(opacity=100);-}--.btn-mini .caret {-  margin-top: 5px;-}--.btn-small .caret {-  margin-top: 6px;-}--.btn-large .caret {-  margin-top: 6px;-  border-top-width: 5px;-  border-right-width: 5px;-  border-left-width: 5px;-}--.dropup .btn-large .caret {-  border-top: 0;-  border-bottom: 5px solid #000000;-}--.btn-primary .caret,-.btn-warning .caret,-.btn-danger .caret,-.btn-info .caret,-.btn-success .caret,-.btn-inverse .caret {-  border-top-color: #ffffff;-  border-bottom-color: #ffffff;-  opacity: 0.75;-  filter: alpha(opacity=75);-}--.alert {-  padding: 8px 35px 8px 14px;-  margin-bottom: 18px;-  color: #c09853;-  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-heading {-  color: inherit;-}--.alert .close {-  position: relative;-  top: -2px;-  right: -21px;-  line-height: 18px;-}--.alert-success {-  color: #468847;-  background-color: #dff0d8;-  border-color: #d6e9c6;-}--.alert-danger,-.alert-error {-  color: #b94a48;-  background-color: #f2dede;-  border-color: #eed3d7;-}--.alert-info {-  color: #3a87ad;-  background-color: #d9edf7;-  border-color: #bce8f1;-}--.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: 18px;-  margin-left: 0;-  list-style: none;-}--.nav > li > a {-  display: block;-}--.nav > li > a:hover {-  text-decoration: none;-  background-color: #eeeeee;-}--.nav > .pull-right {-  float: right;-}--.nav .nav-header {-  display: block;-  padding: 3px 15px;-  font-size: 11px;-  font-weight: bold;-  line-height: 18px;-  color: #999999;-  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 {-  color: #ffffff;-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);-  background-color: #0088cc;-}--.nav-list [class^="icon-"] {-  margin-right: 2px;-}--.nav-list .divider {-  *width: 100%;-  height: 1px;-  margin: 8px 1px;-  *margin: -5px 0 5px;-  overflow: hidden;-  background-color: #e5e5e5;-  border-bottom: 1px solid #ffffff;-}--.nav-tabs,-.nav-pills {-  *zoom: 1;-}--.nav-tabs:before,-.nav-pills:before,-.nav-tabs:after,-.nav-pills:after {-  display: table;-  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: 18px;-  border: 1px solid transparent;-  -webkit-border-radius: 4px 4px 0 0;-     -moz-border-radius: 4px 4px 0 0;-          border-radius: 4px 4px 0 0;-}--.nav-tabs > li > a:hover {-  border-color: #eeeeee #eeeeee #dddddd;-}--.nav-tabs > .active > a,-.nav-tabs > .active > a:hover {-  color: #555555;-  cursor: default;-  background-color: #ffffff;-  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 {-  color: #ffffff;-  background-color: #0088cc;-}--.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-radius: 4px 4px 0 0;-     -moz-border-radius: 4px 4px 0 0;-          border-radius: 4px 4px 0 0;-}--.nav-tabs.nav-stacked > li:last-child > a {-  -webkit-border-radius: 0 0 4px 4px;-     -moz-border-radius: 0 0 4px 4px;-          border-radius: 0 0 4px 4px;-}--.nav-tabs.nav-stacked > li > a:hover {-  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 5px 5px;-     -moz-border-radius: 0 0 5px 5px;-          border-radius: 0 0 5px 5px;-}--.nav-pills .dropdown-menu {-  -webkit-border-radius: 4px;-     -moz-border-radius: 4px;-          border-radius: 4px;-}--.nav-tabs .dropdown-toggle .caret,-.nav-pills .dropdown-toggle .caret {-  margin-top: 6px;-  border-top-color: #0088cc;-  border-bottom-color: #0088cc;-}--.nav-tabs .dropdown-toggle:hover .caret,-.nav-pills .dropdown-toggle:hover .caret {-  border-top-color: #005580;-  border-bottom-color: #005580;-}--.nav-tabs .active .dropdown-toggle .caret,-.nav-pills .active .dropdown-toggle .caret {-  border-top-color: #333333;-  border-bottom-color: #333333;-}--.nav > .dropdown.active > a:hover {-  color: #000000;-  cursor: pointer;-}--.nav-tabs .open .dropdown-toggle,-.nav-pills .open .dropdown-toggle,-.nav > li.dropdown.open.active > a:hover {-  color: #ffffff;-  background-color: #999999;-  border-color: #999999;-}--.nav li.dropdown.open .caret,-.nav li.dropdown.open.active .caret,-.nav li.dropdown.open a:hover .caret {-  border-top-color: #ffffff;-  border-bottom-color: #ffffff;-  opacity: 1;-  filter: alpha(opacity=100);-}--.tabs-stacked .open > a:hover {-  border-color: #999999;-}--.tabbable {-  *zoom: 1;-}--.tabbable:before,-.tabbable:after {-  display: table;-  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 {-  border-top-color: #ddd;-  border-bottom-color: transparent;-}--.tabs-below > .nav-tabs > .active > a,-.tabs-below > .nav-tabs > .active > a:hover {-  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 {-  border-color: #eeeeee #dddddd #eeeeee #eeeeee;-}--.tabs-left > .nav-tabs .active > a,-.tabs-left > .nav-tabs .active > a:hover {-  border-color: #ddd transparent #ddd #ddd;-  *border-right-color: #ffffff;-}--.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 {-  border-color: #eeeeee #eeeeee #eeeeee #dddddd;-}--.tabs-right > .nav-tabs .active > a,-.tabs-right > .nav-tabs .active > a:hover {-  border-color: #ddd #ddd #ddd transparent;-  *border-left-color: #ffffff;-}--.navbar {-  *position: relative;-  *z-index: 2;-  margin-bottom: 18px;-  overflow: visible;-}--.navbar-inner {-  min-height: 40px;-  padding-right: 20px;-  padding-left: 20px;-  background-color: #2c2c2c;-  background-image: -moz-linear-gradient(top, #333333, #222222);-  background-image: -ms-linear-gradient(top, #333333, #222222);-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));-  background-image: -webkit-linear-gradient(top, #333333, #222222);-  background-image: -o-linear-gradient(top, #333333, #222222);-  background-image: linear-gradient(top, #333333, #222222);-  background-repeat: repeat-x;-  -webkit-border-radius: 4px;-     -moz-border-radius: 4px;-          border-radius: 4px;-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);-  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);-     -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);-          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);-}--.navbar .container {-  width: auto;-}--.nav-collapse.collapse {-  height: auto;-}--.navbar {-  color: #999999;-}--.navbar .brand:hover {-  text-decoration: none;-}--.navbar .brand {-  display: block;-  float: left;-  padding: 8px 20px 12px;-  margin-left: -20px;-  font-size: 20px;-  font-weight: 200;-  line-height: 1;-  color: #999999;-}--.navbar .navbar-text {-  margin-bottom: 0;-  line-height: 40px;-}--.navbar .navbar-link {-  color: #999999;-}--.navbar .navbar-link:hover {-  color: #ffffff;-}--.navbar .btn,-.navbar .btn-group {-  margin-top: 5px;-}--.navbar .btn-group .btn {-  margin: 0;-}--.navbar-form {-  margin-bottom: 0;-  *zoom: 1;-}--.navbar-form:before,-.navbar-form:after {-  display: table;-  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 {-  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: 6px;-  white-space: nowrap;-}--.navbar-form .input-append input,-.navbar-form .input-prepend input {-  margin-top: 0;-}--.navbar-search {-  position: relative;-  float: left;-  margin-top: 6px;-  margin-bottom: 0;-}--.navbar-search .search-query {-  padding: 4px 9px;-  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;-  font-size: 13px;-  font-weight: normal;-  line-height: 1;-  color: #ffffff;-  background-color: #626262;-  border: 1px solid #151515;-  -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;-      -ms-transition: none;-       -o-transition: none;-          transition: none;-}--.navbar-search .search-query:-moz-placeholder {-  color: #cccccc;-}--.navbar-search .search-query:-ms-input-placeholder {-  color: #cccccc;-}--.navbar-search .search-query::-webkit-input-placeholder {-  color: #cccccc;-}--.navbar-search .search-query:focus,-.navbar-search .search-query.focused {-  padding: 5px 10px;-  color: #333333;-  text-shadow: 0 1px 0 #ffffff;-  background-color: #ffffff;-  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-fixed-top,-.navbar-fixed-bottom {-  position: fixed;-  right: 0;-  left: 0;-  z-index: 1030;-  margin-bottom: 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-fixed-top .container,-.navbar-fixed-bottom .container {-  width: 940px;-}--.navbar-fixed-top {-  top: 0;-}--.navbar-fixed-bottom {-  bottom: 0;-}--.navbar .nav {-  position: relative;-  left: 0;-  display: block;-  float: left;-  margin: 0 10px 0 0;-}--.navbar .nav.pull-right {-  float: right;-}--.navbar .nav > li {-  display: block;-  float: left;-}--.navbar .nav > li > a {-  float: none;-  padding: 9px 10px 11px;-  line-height: 19px;-  color: #999999;-  text-decoration: none;-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);-}--.navbar .btn {-  display: inline-block;-  padding: 4px 10px 4px;-  margin: 5px 5px 6px;-  line-height: 18px;-}--.navbar .btn-group {-  padding: 5px 5px 6px;-  margin: 0;-}--.navbar .nav > li > a:hover {-  color: #ffffff;-  text-decoration: none;-  background-color: transparent;-}--.navbar .nav .active > a,-.navbar .nav .active > a:hover {-  color: #ffffff;-  text-decoration: none;-  background-color: #222222;-}--.navbar .divider-vertical {-  width: 1px;-  height: 40px;-  margin: 0 9px;-  overflow: hidden;-  background-color: #222222;-  border-right: 1px solid #333333;-}--.navbar .nav.pull-right {-  margin-right: 0;-  margin-left: 10px;-}--.navbar .btn-navbar {-  display: none;-  float: right;-  padding: 7px 10px;-  margin-right: 5px;-  margin-left: 5px;-  background-color: #2c2c2c;-  *background-color: #222222;-  background-image: -ms-linear-gradient(top, #333333, #222222);-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));-  background-image: -webkit-linear-gradient(top, #333333, #222222);-  background-image: -o-linear-gradient(top, #333333, #222222);-  background-image: linear-gradient(top, #333333, #222222);-  background-image: -moz-linear-gradient(top, #333333, #222222);-  background-repeat: repeat-x;-  border-color: #222222 #222222 #000000;-  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#333333', endColorstr='#222222', 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:active,-.navbar .btn-navbar.active,-.navbar .btn-navbar.disabled,-.navbar .btn-navbar[disabled] {-  background-color: #222222;-  *background-color: #151515;-}--.navbar .btn-navbar:active,-.navbar .btn-navbar.active {-  background-color: #080808 \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 .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 .dropdown-menu:after {-  position: absolute;-  top: -6px;-  left: 10px;-  display: inline-block;-  border-right: 6px solid transparent;-  border-bottom: 6px solid #ffffff;-  border-left: 6px solid transparent;-  content: '';-}--.navbar-fixed-bottom .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 .dropdown-menu:after {-  top: auto;-  bottom: -6px;-  border-top: 6px solid #ffffff;-  border-bottom: 0;-}--.navbar .nav li.dropdown .dropdown-toggle .caret,-.navbar .nav li.dropdown.open .caret {-  border-top-color: #ffffff;-  border-bottom-color: #ffffff;-}--.navbar .nav li.dropdown.active .caret {-  opacity: 1;-  filter: alpha(opacity=100);-}--.navbar .nav li.dropdown.open > .dropdown-toggle,-.navbar .nav li.dropdown.active > .dropdown-toggle,-.navbar .nav li.dropdown.open.active > .dropdown-toggle {-  background-color: transparent;-}--.navbar .nav li.dropdown.active > .dropdown-toggle:hover {-  color: #ffffff;-}--.navbar .pull-right .dropdown-menu,-.navbar .dropdown-menu.pull-right {-  right: 0;-  left: auto;-}--.navbar .pull-right .dropdown-menu:before,-.navbar .dropdown-menu.pull-right:before {-  right: 12px;-  left: auto;-}--.navbar .pull-right .dropdown-menu:after,-.navbar .dropdown-menu.pull-right:after {-  right: 13px;-  left: auto;-}--.breadcrumb {-  padding: 7px 14px;-  margin: 0 0 18px;-  list-style: none;-  background-color: #fbfbfb;-  background-image: -moz-linear-gradient(top, #ffffff, #f5f5f5);-  background-image: -ms-linear-gradient(top, #ffffff, #f5f5f5);-  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f5f5f5));-  background-image: -webkit-linear-gradient(top, #ffffff, #f5f5f5);-  background-image: -o-linear-gradient(top, #ffffff, #f5f5f5);-  background-image: linear-gradient(top, #ffffff, #f5f5f5);-  background-repeat: repeat-x;-  border: 1px solid #ddd;-  -webkit-border-radius: 3px;-     -moz-border-radius: 3px;-          border-radius: 3px;-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0);-  -webkit-box-shadow: inset 0 1px 0 #ffffff;-     -moz-box-shadow: inset 0 1px 0 #ffffff;-          box-shadow: inset 0 1px 0 #ffffff;-}--.breadcrumb li {-  display: inline-block;-  *display: inline;-  text-shadow: 0 1px 0 #ffffff;-  *zoom: 1;-}--.breadcrumb .divider {-  padding: 0 5px;-  color: #999999;-}--.breadcrumb .active a {-  color: #333333;-}--.pagination {-  height: 36px;-  margin: 18px 0;-}--.pagination ul {-  display: inline-block;-  *display: inline;-  margin-bottom: 0;-  margin-left: 0;-  -webkit-border-radius: 3px;-     -moz-border-radius: 3px;-          border-radius: 3px;-  *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 li {-  display: inline;-}--.pagination a {-  float: left;-  padding: 0 14px;-  line-height: 34px;-  text-decoration: none;-  border: 1px solid #ddd;-  border-left-width: 0;-}--.pagination a:hover,-.pagination .active a {-  background-color: #f5f5f5;-}--.pagination .active a {-  color: #999999;-  cursor: default;-}--.pagination .disabled span,-.pagination .disabled a,-.pagination .disabled a:hover {-  color: #999999;-  cursor: default;-  background-color: transparent;-}--.pagination li:first-child a {-  border-left-width: 1px;-  -webkit-border-radius: 3px 0 0 3px;-     -moz-border-radius: 3px 0 0 3px;-          border-radius: 3px 0 0 3px;-}--.pagination li:last-child a {-  -webkit-border-radius: 0 3px 3px 0;-     -moz-border-radius: 0 3px 3px 0;-          border-radius: 0 3px 3px 0;-}--.pagination-centered {-  text-align: center;-}--.pagination-right {-  text-align: right;-}--.pager {-  margin-bottom: 18px;-  margin-left: 0;-  text-align: center;-  list-style: none;-  *zoom: 1;-}--.pager:before,-.pager:after {-  display: table;-  content: "";-}--.pager:after {-  clear: both;-}--.pager li {-  display: inline;-}--.pager a {-  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 a:hover {-  text-decoration: none;-  background-color: #f5f5f5;-}--.pager .next a {-  float: right;-}--.pager .previous a {-  float: left;-}--.pager .disabled a,-.pager .disabled a:hover {-  color: #999999;-  cursor: default;-  background-color: #fff;-}--.modal-open .dropdown-menu {-  z-index: 2050;-}--.modal-open .dropdown.open {-  *z-index: 2050;-}--.modal-open .popover {-  z-index: 2060;-}--.modal-open .tooltip {-  z-index: 2070;-}--.modal-backdrop {-  position: fixed;-  top: 0;-  right: 0;-  bottom: 0;-  left: 0;-  z-index: 1040;-  background-color: #000000;-}--.modal-backdrop.fade {-  opacity: 0;-}--.modal-backdrop,-.modal-backdrop.fade.in {-  opacity: 0.8;-  filter: alpha(opacity=80);-}--.modal {-  position: fixed;-  top: 50%;-  left: 50%;-  z-index: 1050;-  width: 560px;-  margin: -250px 0 0 -280px;-  overflow: auto;-  background-color: #ffffff;-  border: 1px solid #999;-  border: 1px solid rgba(0, 0, 0, 0.3);-  *border: 1px solid #999;-  -webkit-border-radius: 6px;-     -moz-border-radius: 6px;-          border-radius: 6px;-  -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);-     -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);-          box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);-  -webkit-background-clip: padding-box;-     -moz-background-clip: padding-box;-          background-clip: padding-box;-}--.modal.fade {-  top: -25%;-  -webkit-transition: opacity 0.3s linear, top 0.3s ease-out;-     -moz-transition: opacity 0.3s linear, top 0.3s ease-out;-      -ms-transition: opacity 0.3s linear, top 0.3s ease-out;-       -o-transition: opacity 0.3s linear, top 0.3s ease-out;-          transition: opacity 0.3s linear, top 0.3s ease-out;-}--.modal.fade.in {-  top: 50%;-}--.modal-header {-  padding: 9px 15px;-  border-bottom: 1px solid #eee;-}--.modal-header .close {-  margin-top: 2px;-}--.modal-body {-  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 #ffffff;-     -moz-box-shadow: inset 0 1px 0 #ffffff;-          box-shadow: inset 0 1px 0 #ffffff;-}--.modal-footer:before,-.modal-footer:after {-  display: table;-  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;-}--.tooltip {-  position: absolute;-  z-index: 1020;-  display: block;-  padding: 5px;-  font-size: 11px;-  opacity: 0;-  filter: alpha(opacity=0);-  visibility: visible;-}--.tooltip.in {-  opacity: 0.8;-  filter: alpha(opacity=80);-}--.tooltip.top {-  margin-top: -2px;-}--.tooltip.right {-  margin-left: 2px;-}--.tooltip.bottom {-  margin-top: 2px;-}--.tooltip.left {-  margin-left: -2px;-}--.tooltip.top .tooltip-arrow {-  bottom: 0;-  left: 50%;-  margin-left: -5px;-  border-top: 5px solid #000000;-  border-right: 5px solid transparent;-  border-left: 5px solid transparent;-}--.tooltip.left .tooltip-arrow {-  top: 50%;-  right: 0;-  margin-top: -5px;-  border-top: 5px solid transparent;-  border-bottom: 5px solid transparent;-  border-left: 5px solid #000000;-}--.tooltip.bottom .tooltip-arrow {-  top: 0;-  left: 50%;-  margin-left: -5px;-  border-right: 5px solid transparent;-  border-bottom: 5px solid #000000;-  border-left: 5px solid transparent;-}--.tooltip.right .tooltip-arrow {-  top: 50%;-  left: 0;-  margin-top: -5px;-  border-top: 5px solid transparent;-  border-right: 5px solid #000000;-  border-bottom: 5px solid transparent;-}--.tooltip-inner {-  max-width: 200px;-  padding: 3px 8px;-  color: #ffffff;-  text-align: center;-  text-decoration: none;-  background-color: #000000;-  -webkit-border-radius: 4px;-     -moz-border-radius: 4px;-          border-radius: 4px;-}--.tooltip-arrow {-  position: absolute;-  width: 0;-  height: 0;-}--.popover {-  position: absolute;-  top: 0;-  left: 0;-  z-index: 1010;-  display: none;-  padding: 5px;-}--.popover.top {-  margin-top: -5px;-}--.popover.right {-  margin-left: 5px;-}--.popover.bottom {-  margin-top: 5px;-}--.popover.left {-  margin-left: -5px;-}--.popover.top .arrow {-  bottom: 0;-  left: 50%;-  margin-left: -5px;-  border-top: 5px solid #000000;-  border-right: 5px solid transparent;-  border-left: 5px solid transparent;-}--.popover.right .arrow {-  top: 50%;-  left: 0;-  margin-top: -5px;-  border-top: 5px solid transparent;-  border-right: 5px solid #000000;-  border-bottom: 5px solid transparent;-}--.popover.bottom .arrow {-  top: 0;-  left: 50%;-  margin-left: -5px;-  border-right: 5px solid transparent;-  border-bottom: 5px solid #000000;-  border-left: 5px solid transparent;-}--.popover.left .arrow {-  top: 50%;-  right: 0;-  margin-top: -5px;-  border-top: 5px solid transparent;-  border-bottom: 5px solid transparent;-  border-left: 5px solid #000000;-}--.popover .arrow {-  position: absolute;-  width: 0;-  height: 0;-}--.popover-inner {-  width: 280px;-  padding: 3px;-  overflow: hidden;-  background: #000000;-  background: rgba(0, 0, 0, 0.8);-  -webkit-border-radius: 6px;-     -moz-border-radius: 6px;-          border-radius: 6px;-  -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);-     -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);-          box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);-}--.popover-title {-  padding: 9px 15px;-  line-height: 1;-  background-color: #f5f5f5;-  border-bottom: 1px solid #eee;-  -webkit-border-radius: 3px 3px 0 0;-     -moz-border-radius: 3px 3px 0 0;-          border-radius: 3px 3px 0 0;-}--.popover-content {-  padding: 14px;-  background-color: #ffffff;-  -webkit-border-radius: 0 0 3px 3px;-     -moz-border-radius: 0 0 3px 3px;-          border-radius: 0 0 3px 3px;-  -webkit-background-clip: padding-box;-     -moz-background-clip: padding-box;-          background-clip: padding-box;-}--.popover-content p,-.popover-content ul,-.popover-content ol {-  margin-bottom: 0;-}--.thumbnails {-  margin-left: -20px;-  list-style: none;-  *zoom: 1;-}--.thumbnails:before,-.thumbnails:after {-  display: table;-  content: "";-}--.thumbnails:after {-  clear: both;-}--.row-fluid .thumbnails {-  margin-left: 0;-}--.thumbnails > li {-  float: left;-  margin-bottom: 18px;-  margin-left: 20px;-}--.thumbnail {-  display: block;-  padding: 4px;-  line-height: 1;-  border: 1px solid #ddd;-  -webkit-border-radius: 4px;-     -moz-border-radius: 4px;-          border-radius: 4px;-  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075);-     -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075);-          box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075);-}--a.thumbnail:hover {-  border-color: #0088cc;-  -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);-     -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);-          box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);-}--.thumbnail > img {-  display: block;-  max-width: 100%;-  margin-right: auto;-  margin-left: auto;-}--.thumbnail .caption {-  padding: 9px;-}--.label,-.badge {-  font-size: 10.998px;-  font-weight: bold;-  line-height: 14px;-  color: #ffffff;-  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);-  white-space: nowrap;-  vertical-align: baseline;-  background-color: #999999;-}--.label {-  padding: 1px 4px 2px;-  -webkit-border-radius: 3px;-     -moz-border-radius: 3px;-          border-radius: 3px;-}--.badge {-  padding: 1px 9px 2px;-  -webkit-border-radius: 9px;-     -moz-border-radius: 9px;-          border-radius: 9px;-}--a.label:hover,-a.badge:hover {-  color: #ffffff;-  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: #333333;-}--.label-inverse[href],-.badge-inverse[href] {-  background-color: #1a1a1a;-}--@-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: 18px;-  margin-bottom: 18px;-  overflow: hidden;-  background-color: #f7f7f7;-  background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9);-  background-image: -ms-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(top, #f5f5f5, #f9f9f9);-  background-repeat: repeat-x;-  -webkit-border-radius: 4px;-     -moz-border-radius: 4px;-          border-radius: 4px;-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#f9f9f9', 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 {-  width: 0;-  height: 18px;-  font-size: 12px;-  color: #ffffff;-  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(top, #149bdf, #0480be);-  background-image: -ms-linear-gradient(top, #149bdf, #0480be);-  background-repeat: repeat-x;-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#149bdf', endColorstr='#0480be', 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;-      -ms-box-sizing: border-box;-          box-sizing: border-box;-  -webkit-transition: width 0.6s ease;-     -moz-transition: width 0.6s ease;-      -ms-transition: width 0.6s ease;-       -o-transition: width 0.6s ease;-          transition: width 0.6s ease;-}--.progress-striped .bar {-  background-color: #149bdf;-  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: -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: -ms-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: -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: 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 {-  background-color: #dd514c;-  background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);-  background-image: -ms-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(top, #ee5f5b, #c43c35);-  background-repeat: repeat-x;-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);-}--.progress-danger.progress-striped .bar {-  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: -ms-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 {-  background-color: #5eb95e;-  background-image: -moz-linear-gradient(top, #62c462, #57a957);-  background-image: -ms-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(top, #62c462, #57a957);-  background-repeat: repeat-x;-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);-}--.progress-success.progress-striped .bar {-  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: -ms-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 {-  background-color: #4bb1cf;-  background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);-  background-image: -ms-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(top, #5bc0de, #339bb9);-  background-repeat: repeat-x;-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);-}--.progress-info.progress-striped .bar {-  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: -ms-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 {-  background-color: #faa732;-  background-image: -moz-linear-gradient(top, #fbb450, #f89406);-  background-image: -ms-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(top, #fbb450, #f89406);-  background-repeat: repeat-x;-  filter: progid:dximagetransform.microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0);-}--.progress-warning.progress-striped .bar {-  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: -ms-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: 18px;-}--.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: 18px;-  line-height: 1;-}--.carousel-inner {-  position: relative;-  width: 100%;-  overflow: hidden;-}--.carousel .item {-  position: relative;-  display: none;-  -webkit-transition: 0.6s ease-in-out left;-     -moz-transition: 0.6s ease-in-out left;-      -ms-transition: 0.6s ease-in-out left;-       -o-transition: 0.6s ease-in-out left;-          transition: 0.6s ease-in-out left;-}--.carousel .item > img {-  display: block;-  line-height: 1;-}--.carousel .active,-.carousel .next,-.carousel .prev {-  display: block;-}--.carousel .active {-  left: 0;-}--.carousel .next,-.carousel .prev {-  position: absolute;-  top: 0;-  width: 100%;-}--.carousel .next {-  left: 100%;-}--.carousel .prev {-  left: -100%;-}--.carousel .next.left,-.carousel .prev.right {-  left: 0;-}--.carousel .active.left {-  left: -100%;-}--.carousel .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: #ffffff;-  text-align: center;-  background: #222222;-  border: 3px solid #ffffff;-  -webkit-border-radius: 23px;-     -moz-border-radius: 23px;-          border-radius: 23px;-  opacity: 0.5;-  filter: alpha(opacity=50);-}--.carousel-control.right {-  right: 15px;-  left: auto;-}--.carousel-control:hover {-  color: #ffffff;-  text-decoration: none;-  opacity: 0.9;-  filter: alpha(opacity=90);-}--.carousel-caption {-  position: absolute;-  right: 0;-  bottom: 0;-  left: 0;-  padding: 10px 15px 5px;-  background: #333333;-  background: rgba(0, 0, 0, 0.75);-}--.carousel-caption h4,-.carousel-caption p {-  color: #ffffff;-}--.hero-unit {-  padding: 60px;-  margin-bottom: 30px;-  background-color: #eeeeee;-  -webkit-border-radius: 6px;-     -moz-border-radius: 6px;-          border-radius: 6px;-}--.hero-unit h1 {-  margin-bottom: 0;-  font-size: 60px;-  line-height: 1;-  letter-spacing: -1px;-  color: inherit;-}--.hero-unit p {-  font-size: 18px;-  font-weight: 200;-  line-height: 27px;-  color: inherit;-}--.pull-right {-  float: right;-}--.pull-left {-  float: left;-}--.hide {-  display: none;-}--.show {-  display: block;-}--.invisible {-  visibility: hidden;-}
+ static/glyphicons-halflings-white.png view

binary file changed (absent → 4352 bytes)

+ static/glyphicons-halflings.png view

binary file changed (absent → 4352 bytes)

− static/img/glyphicons-halflings-white.png

binary file changed (4352 → absent bytes)

− static/img/glyphicons-halflings.png

binary file changed (4352 → absent bytes)

− static/js/bootstrap-collapse.js
@@ -1,138 +0,0 @@-/* =============================================================- * bootstrap-collapse.js v2.0.2- * http://twitter.github.com/bootstrap/javascript.html#collapse- * =============================================================- * Copyright 2012 Twitter, Inc.- *- * Licensed under the Apache License, Version 2.0 (the "License");- * you may not use this file except in compliance with the License.- * You may obtain a copy of the License at- *- * http://www.apache.org/licenses/LICENSE-2.0- *- * Unless required by applicable law or agreed to in writing, software- * distributed under the License is distributed on an "AS IS" BASIS,- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.- * See the License for the specific language governing permissions and- * limitations under the License.- * ============================================================ */--!function( $ ){--  "use strict"--  var Collapse = function ( element, options ) {-  	this.$element = $(element)-    this.options = $.extend({}, $.fn.collapse.defaults, options)--    if (this.options["parent"]) {-      this.$parent = $(this.options["parent"])-    }--    this.options.toggle && this.toggle()-  }--  Collapse.prototype = {--    constructor: Collapse--  , dimension: function () {-      var hasWidth = this.$element.hasClass('width')-      return hasWidth ? 'width' : 'height'-    }--  , show: function () {-      var dimension = this.dimension()-        , scroll = $.camelCase(['scroll', dimension].join('-'))-        , actives = this.$parent && this.$parent.find('.in')-        , hasData--      if (actives && actives.length) {-        hasData = actives.data('collapse')-        actives.collapse('hide')-        hasData || actives.data('collapse', null)-      }--      this.$element[dimension](0)-      this.transition('addClass', 'show', 'shown')-      this.$element[dimension](this.$element[0][scroll])--    }--  , hide: function () {-      var dimension = this.dimension()-      this.reset(this.$element[dimension]())-      this.transition('removeClass', 'hide', 'hidden')-      this.$element[dimension](0)-    }--  , reset: function ( size ) {-      var dimension = this.dimension()--      this.$element-        .removeClass('collapse')-        [dimension](size || 'auto')-        [0].offsetWidth--      this.$element[size ? 'addClass' : 'removeClass']('collapse')--      return this-    }--  , transition: function ( method, startEvent, completeEvent ) {-      var that = this-        , complete = function () {-            if (startEvent == 'show') that.reset()-            that.$element.trigger(completeEvent)-          }--      this.$element-        .trigger(startEvent)-        [method]('in')--      $.support.transition && this.$element.hasClass('collapse') ?-        this.$element.one($.support.transition.end, complete) :-        complete()-  	}--  , toggle: function () {-      this[this.$element.hasClass('in') ? 'hide' : 'show']()-  	}--  }--  /* COLLAPSIBLE PLUGIN DEFINITION-  * ============================== */--  $.fn.collapse = function ( option ) {-    return this.each(function () {-      var $this = $(this)-        , data = $this.data('collapse')-        , options = typeof option == 'object' && option-      if (!data) $this.data('collapse', (data = new Collapse(this, options)))-      if (typeof option == 'string') data[option]()-    })-  }--  $.fn.collapse.defaults = {-    toggle: true-  }--  $.fn.collapse.Constructor = Collapse--- /* COLLAPSIBLE DATA-API-  * ==================== */--  $(function () {-    $('body').on('click.collapse.data-api', '[data-toggle=collapse]', function ( e ) {-      var $this = $(this), href-        , target = $this.attr('data-target')-          || e.preventDefault()-          || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7-        , option = $(target).data('collapse') ? 'toggle' : $this.data()-      $(target).collapse(option)-    })-  })--}( window.jQuery );
− static/js/bootstrap-dropdown.js
@@ -1,92 +0,0 @@-/* ============================================================- * bootstrap-dropdown.js v2.0.2- * http://twitter.github.com/bootstrap/javascript.html#dropdowns- * ============================================================- * Copyright 2012 Twitter, Inc.- *- * Licensed under the Apache License, Version 2.0 (the "License");- * you may not use this file except in compliance with the License.- * You may obtain a copy of the License at- *- * http://www.apache.org/licenses/LICENSE-2.0- *- * Unless required by applicable law or agreed to in writing, software- * distributed under the License is distributed on an "AS IS" BASIS,- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.- * See the License for the specific language governing permissions and- * limitations under the License.- * ============================================================ */---!function( $ ){--  "use strict"-- /* DROPDOWN CLASS DEFINITION-  * ========================= */--  var toggle = '[data-toggle="dropdown"]'-    , Dropdown = function ( element ) {-        var $el = $(element).on('click.dropdown.data-api', this.toggle)-        $('html').on('click.dropdown.data-api', function () {-          $el.parent().removeClass('open')-        })-      }--  Dropdown.prototype = {--    constructor: Dropdown--  , toggle: function ( e ) {-      var $this = $(this)-        , selector = $this.attr('data-target')-        , $parent-        , isActive--      if (!selector) {-        selector = $this.attr('href')-        selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7-      }--      $parent = $(selector)-      $parent.length || ($parent = $this.parent())--      isActive = $parent.hasClass('open')--      clearMenus()-      !isActive && $parent.toggleClass('open')--      return false-    }--  }--  function clearMenus() {-    $(toggle).parent().removeClass('open')-  }---  /* DROPDOWN PLUGIN DEFINITION-   * ========================== */--  $.fn.dropdown = function ( option ) {-    return this.each(function () {-      var $this = $(this)-        , data = $this.data('dropdown')-      if (!data) $this.data('dropdown', (data = new Dropdown(this)))-      if (typeof option == 'string') data[option].call($this)-    })-  }--  $.fn.dropdown.Constructor = Dropdown---  /* APPLY TO STANDARD DROPDOWN ELEMENTS-   * =================================== */--  $(function () {-    $('html').on('click.dropdown.data-api', clearMenus)-    $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle)-  })--}( window.jQuery );
− static/js/bootstrap-modal.js
@@ -1,210 +0,0 @@-/* =========================================================- * bootstrap-modal.js v2.0.2- * http://twitter.github.com/bootstrap/javascript.html#modals- * =========================================================- * Copyright 2012 Twitter, Inc.- *- * Licensed under the Apache License, Version 2.0 (the "License");- * you may not use this file except in compliance with the License.- * You may obtain a copy of the License at- *- * http://www.apache.org/licenses/LICENSE-2.0- *- * Unless required by applicable law or agreed to in writing, software- * distributed under the License is distributed on an "AS IS" BASIS,- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.- * See the License for the specific language governing permissions and- * limitations under the License.- * ========================================================= */---!function( $ ){--  "use strict"-- /* MODAL CLASS DEFINITION-  * ====================== */--  var Modal = function ( content, options ) {-    this.options = options-    this.$element = $(content)-      .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))-  }--  Modal.prototype = {--      constructor: Modal--    , toggle: function () {-        return this[!this.isShown ? 'show' : 'hide']()-      }--    , show: function () {-        var that = this--        if (this.isShown) return--        $('body').addClass('modal-open')--        this.isShown = true-        this.$element.trigger('show')--        escape.call(this)-        backdrop.call(this, function () {-          var transition = $.support.transition && that.$element.hasClass('fade')--          !that.$element.parent().length && that.$element.appendTo(document.body) //don't move modals dom position--          that.$element-            .show()--          if (transition) {-            that.$element[0].offsetWidth // force reflow-          }--          that.$element.addClass('in')--          transition ?-            that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :-            that.$element.trigger('shown')--        })-      }--    , hide: function ( e ) {-        e && e.preventDefault()--        if (!this.isShown) return--        var that = this-        this.isShown = false--        $('body').removeClass('modal-open')--        escape.call(this)--        this.$element-          .trigger('hide')-          .removeClass('in')--        $.support.transition && this.$element.hasClass('fade') ?-          hideWithTransition.call(this) :-          hideModal.call(this)-      }--  }--- /* MODAL PRIVATE METHODS-  * ===================== */--  function hideWithTransition() {-    var that = this-      , timeout = setTimeout(function () {-          that.$element.off($.support.transition.end)-          hideModal.call(that)-        }, 500)--    this.$element.one($.support.transition.end, function () {-      clearTimeout(timeout)-      hideModal.call(that)-    })-  }--  function hideModal( that ) {-    this.$element-      .hide()-      .trigger('hidden')--    backdrop.call(this)-  }--  function backdrop( callback ) {-    var that = this-      , animate = this.$element.hasClass('fade') ? 'fade' : ''--    if (this.isShown && this.options.backdrop) {-      var doAnimate = $.support.transition && animate--      this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')-        .appendTo(document.body)--      if (this.options.backdrop != 'static') {-        this.$backdrop.click($.proxy(this.hide, this))-      }--      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow--      this.$backdrop.addClass('in')--      doAnimate ?-        this.$backdrop.one($.support.transition.end, callback) :-        callback()--    } else if (!this.isShown && this.$backdrop) {-      this.$backdrop.removeClass('in')--      $.support.transition && this.$element.hasClass('fade')?-        this.$backdrop.one($.support.transition.end, $.proxy(removeBackdrop, this)) :-        removeBackdrop.call(this)--    } else if (callback) {-      callback()-    }-  }--  function removeBackdrop() {-    this.$backdrop.remove()-    this.$backdrop = null-  }--  function escape() {-    var that = this-    if (this.isShown && this.options.keyboard) {-      $(document).on('keyup.dismiss.modal', function ( e ) {-        e.which == 27 && that.hide()-      })-    } else if (!this.isShown) {-      $(document).off('keyup.dismiss.modal')-    }-  }--- /* MODAL PLUGIN DEFINITION-  * ======================= */--  $.fn.modal = function ( option ) {-    return this.each(function () {-      var $this = $(this)-        , data = $this.data('modal')-        , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)-      if (!data) $this.data('modal', (data = new Modal(this, options)))-      if (typeof option == 'string') data[option]()-      else if (options.show) data.show()-    })-  }--  $.fn.modal.defaults = {-      backdrop: true-    , keyboard: true-    , show: true-  }--  $.fn.modal.Constructor = Modal--- /* MODAL DATA-API-  * ============== */--  $(function () {-    $('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {-      var $this = $(this), href-        , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7-        , option = $target.data('modal') ? 'toggle' : $.extend({}, $target.data(), $this.data())--      e.preventDefault()-      $target.modal(option)-    })-  })--}( window.jQuery );
static/longpolling.js view
@@ -16,7 +16,11 @@ 		}, 		'error': function(jqxhr, msg, e) { 			connfails=connfails+1;-			if (connfails > 3) {+			// It's normal to get 1 failure per longpolling+			// element when navigating away from a page.+			// So 12 allows up to 4 longpolling elements per+			// page.+			if (connfails > 12) { 				fail(); 			} 			else {
templates/page.hamlet view
@@ -10,8 +10,9 @@               #{name}       $maybe reldir <- relDir webapp         <ul .nav .pull-right>-          <li>-            ^{actionButton FileBrowserR (Just "Files") (Just "Click to open a file browser") "" "icon-folder-open icon-white"}+          $if hasFileBrowser+            <li>+              ^{actionButton FileBrowserR (Just "Files") (Just "Click to open a file browser") "" "icon-folder-open icon-white"}           <li .dropdown #menu1>             <a .dropdown-toggle data-toggle="dropdown" href="#menu1">               Repository: #{reldir}