text:
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE ViewPatterns #-}
module IRTS.CodegenJava (codegenJava) where

import           Idris.Core.TT             hiding (mkApp)
import           IRTS.CodegenCommon
import           IRTS.Java.ASTBuilding
import           IRTS.Java.JTypes
import           IRTS.Java.Mangling
import           IRTS.Java.Pom (pomString)
import           IRTS.Lang
import           IRTS.Simplified
import           IRTS.System
import           Util.System

import           Control.Applicative       hiding (Const)
import           Control.Arrow
import           Control.Monad
import           Control.Monad.Except
import qualified Control.Monad.Trans       as T
import           Control.Monad.Trans.State
import           Data.List                 (foldl', isSuffixOf)
import qualified Data.Text                 as T
import qualified Data.Text.IO              as TIO
import qualified Data.Vector.Unboxed       as V
import           Language.Java.Parser
import           Language.Java.Pretty
import           Language.Java.Syntax      hiding (Name)
import qualified Language.Java.Syntax      as J
import           System.Directory
import           System.Exit
import           System.FilePath
import           System.IO
import           System.Process

-----------------------------------------------------------------------
-- Main function
codegenJava :: CodeGenerator
codegenJava cg = codegenJava' [] (simpleDecls cg) (outputFile cg)
                                 (includes cg) (compileLibs cg)
                                 (outputType cg)

codegenJava' :: [(Name, SExp)] -> -- initialization of globals
                [(Name, SDecl)] -> -- decls
                FilePath -> -- output file name
                [String] -> -- headers
                [String] -> -- libs
                OutputType ->
                IO ()
codegenJava' globalInit defs out hdrs libs exec = do
  withTgtDir exec out (codegenJava' exec)
  where
    codegenJava' :: OutputType -> FilePath -> IO ()
    codegenJava' Raw tgtDir = do
        srcDir <- prepareSrcDir exec tgtDir
        generateJavaFile globalInit defs hdrs srcDir out
    codegenJava' MavenProject tgtDir = do
      codegenJava' Raw tgtDir
      generatePom tgtDir out libs
    codegenJava' Object tgtDir = do
      codegenJava' MavenProject tgtDir
      invokeMvn tgtDir "compile"
      copyClassFiles tgtDir out
      cleanUpTmp tgtDir
    codegenJava' Executable  tgtDir = do
        codegenJava' MavenProject tgtDir
        invokeMvn tgtDir "package";
        copyJar tgtDir out
        makeJarExecutable out
        cleanUpTmp tgtDir

-----------------------------------------------------------------------
-- Compiler IO

withTgtDir :: OutputType -> FilePath -> (FilePath -> IO ()) -> IO ()
withTgtDir Raw out action = action (dropFileName out)
withTgtDir MavenProject out action = createDirectoryIfMissing False out >> action out
withTgtDir _ out action = withTempdir (takeBaseName out) action

prepareSrcDir :: OutputType -> FilePath -> IO FilePath
prepareSrcDir Raw tgtDir = return tgtDir
prepareSrcDir _ tgtDir = do
  let srcDir = (tgtDir </> "src" </> "main" </> "java")
  createDirectoryIfMissing True srcDir
  return srcDir

javaFileName :: FilePath -> FilePath -> FilePath
javaFileName srcDir out =
  either error (\ (Ident clsName) -> srcDir </> clsName <.> "java") (mkClassName out)

generateJavaFile :: [(Name, SExp)] -> -- initialization of globals
                    [(Name, SDecl)] -> -- definitions
                    [String] -> -- headers
                    FilePath -> -- Source dir
                    FilePath -> -- output target
                    IO ()
generateJavaFile globalInit defs hdrs srcDir out = do
    let code = either error
                      (prettyPrint)-- flatIndent . prettyPrint)
                      (evalStateT (mkCompilationUnit globalInit defs hdrs out) mkCodeGenEnv)
    writeFile (javaFileName srcDir out) code
--    writeFile (javaFileName "/Users/br-gaster/dev/" out) code

pomFileName :: FilePath -> FilePath
pomFileName tgtDir = tgtDir </> "pom.xml"

generatePom :: FilePath -> -- tgt dir
               FilePath -> -- output target
               [String] -> -- libs
               IO ()
generatePom tgtDir out libs =
  do writeFile (pomFileName tgtDir) execPom
     --writeFile (pomFileName "/Users/br-gaster/dev/") execPom
  where
    (Ident clsName) = either error id (mkClassName out)
    execPom = pomString clsName (takeBaseName out) libs

invokeMvn :: FilePath -> String -> IO ()
invokeMvn tgtDir command = do
   mvnCmd <- getMvn
   let args = ["-f", pomFileName tgtDir]
   (exit, mvout, err) <- readProcessWithExitCode mvnCmd (args ++ [command]) ""
   when (exit /= ExitSuccess) $
     error ("FAILURE: " ++ mvnCmd ++ " " ++ command ++ "\n" ++ err ++ mvout)

classFileDir :: FilePath -> FilePath
classFileDir tgtDir = tgtDir </> "target" </> "classes"

copyClassFiles :: FilePath -> FilePath -> IO ()
copyClassFiles tgtDir out = do
  classFiles <- map (\ clsFile -> classFileDir tgtDir </> clsFile)
                . filter ((".class" ==) . takeExtension)
                <$> getDirectoryContents (classFileDir tgtDir)
  mapM_ (\ clsFile -> copyFile clsFile (takeDirectory out </> takeFileName clsFile)) classFiles

jarFileName :: FilePath -> FilePath -> FilePath
jarFileName tgtDir out = tgtDir </> "target" </> (takeBaseName out) <.> "jar"

copyJar :: FilePath -> FilePath -> IO ()
copyJar tgtDir out =
  copyFile (jarFileName tgtDir out) out

makeJarExecutable :: FilePath -> IO ()
makeJarExecutable out = do
  handle <- openBinaryFile out ReadMode
  contents <- TIO.hGetContents handle
  hClose handle
  handle <- openBinaryFile out WriteMode
  TIO.hPutStr handle (T.append (T.pack jarHeader) contents)
  hFlush handle
  hClose handle
  perms <- getPermissions out
  setPermissions out (setOwnerExecutable True perms)

removePom :: FilePath -> IO ()
removePom tgtDir = removeFile (pomFileName tgtDir)

cleanUpTmp :: FilePath -> IO ()
cleanUpTmp tgtDir = do
  invokeMvn tgtDir "clean"
  removePom tgtDir

-----------------------------------------------------------------------
-- Jar and Pom infrastructure

jarHeader :: String
jarHeader =
  "#!/usr/bin/env sh\n"
  ++ "MYSELF=`which \"$0\" 2>/dev/null`\n"
  ++ "[ $? -gt 0 -a -f \"$0\" ] && MYSELF=\"./$0\"\n"
  ++ "java=java\n"
  ++ "if test -n \"$JAVA_HOME\"; then\n"
  ++ "  java=\"$JAVA_HOME/bin/java\"\n"
  ++ "fi\n"
  ++ "exec \"$java\" $java_args -jar $MYSELF \"$@\"\n"
  ++ "exit 1\n"

-----------------------------------------------------------------------
-- Code generation environment

data CodeGenerationEnv
  = CodeGenerationEnv
  { globalVariables :: [(Name, ArrayIndex)]
  , localVariables  :: [[(Int, Ident)]]
  , localVarCounter :: Int
  }

type CodeGeneration = StateT (CodeGenerationEnv) (Either String)

mkCodeGenEnv :: CodeGenerationEnv
mkCodeGenEnv = CodeGenerationEnv [] [] 0

varPos :: LVar -> CodeGeneration (Either ArrayIndex Ident)
varPos (Loc i) = do
  vars <- (concat . localVariables) <$> get
  case lookup i vars of
    (Just varName) -> return (Right varName)
    Nothing -> throwError $ "Invalid local variable id: " ++ show i
varPos (Glob name) = do
  vars <- globalVariables <$> get
  case lookup name vars of
    (Just varIdx) -> return (Left varIdx)
    Nothing -> throwError $ "Invalid global variable id: " ++ show name

pushScope :: CodeGeneration ()
pushScope =
  modify (\ env -> env { localVariables = []:(localVariables env) })

popScope :: CodeGeneration ()
popScope = do
  env <- get
  let lVars = tail $ localVariables env
  let vC = if null lVars then 0 else localVarCounter env
  put $ env { localVariables = tail (localVariables env)
            , localVarCounter = vC }

setVariable :: LVar -> CodeGeneration (Either ArrayIndex Ident)
setVariable (Loc i) = do
  env <- get
  let lVars = localVariables env
  let getter = localVar $ localVarCounter env
  let lVars' = ((i, getter) : head lVars) : tail lVars
  put $ env { localVariables = lVars'
            , localVarCounter = 1 + localVarCounter env}
  return (Right getter)
setVariable (Glob n) = do
  env <- get
  let gVars = globalVariables env
  let getter = globalContext @! length gVars
  let gVars' = (n, getter):gVars
  put (env { globalVariables = gVars' })
  return (Left getter)

pushParams :: [Ident] -> CodeGeneration ()
pushParams paramNames =
  let varMap = zipWith (flip (,)) paramNames [0..] in
  modify (\ env -> env { localVariables = varMap:(localVariables env)
                       , localVarCounter = (length varMap) + (localVarCounter env) })

flatIndent :: String -> String
flatIndent (' ' : ' ' : xs) = flatIndent xs
flatIndent (x:xs) = x:flatIndent xs
flatIndent [] = []

-----------------------------------------------------------------------
-- Maintaining control structures over code blocks

data BlockPostprocessor
  = BlockPostprocessor
  { ppInnerBlock :: [BlockStmt] -> Exp -> CodeGeneration [BlockStmt]
  , ppOuterBlock :: [BlockStmt] -> CodeGeneration [BlockStmt]
  }

ppExp :: BlockPostprocessor -> Exp -> CodeGeneration [BlockStmt]
ppExp pp exp = ((ppInnerBlock pp) [] exp) >>= ppOuterBlock pp

addReturn :: BlockPostprocessor
addReturn =
  BlockPostprocessor
  { ppInnerBlock = (\ block exp -> return $ block ++ [jReturn exp])
  , ppOuterBlock = return
  }

ignoreResult :: BlockPostprocessor
ignoreResult =
  BlockPostprocessor
  { ppInnerBlock = (\ block exp -> return block)
  , ppOuterBlock = return
  }

ignoreOuter :: BlockPostprocessor -> BlockPostprocessor
ignoreOuter pp = pp { ppOuterBlock = return }

throwRuntimeException :: BlockPostprocessor -> BlockPostprocessor
throwRuntimeException pp =
  pp
  { ppInnerBlock =
       (\ blk exp -> return $
         blk ++ [ BlockStmt $ Throw
                    ( InstanceCreation
                      []
                      (toClassType runtimeExceptionType)
                      [exp]
                      Nothing
                    )
                ]
       )
  }

rethrowAsRuntimeException :: BlockPostprocessor -> BlockPostprocessor
rethrowAsRuntimeException pp =
  pp
  { ppOuterBlock =
      (\ blk -> do
          ex <- ppInnerBlock (throwRuntimeException pp) [] (ExpName $ J.Name [Ident "ex"])
          ppOuterBlock pp
            $ [ BlockStmt $ Try
                  (Block blk)
                  [Catch (FormalParam [] exceptionType False (VarId (Ident "ex"))) $
                    Block ex
                  ]
                  Nothing
              ]
      )
  }

-----------------------------------------------------------------------
-- File structure

mkCompilationUnit :: [(Name, SExp)] -> [(Name, SDecl)] -> [String] -> FilePath -> CodeGeneration CompilationUnit
mkCompilationUnit globalInit defs hdrs out = do
  clsName <- mkClassName out
  CompilationUnit Nothing ( [ ImportDecl False idrisRts True
                            , ImportDecl True idrisPrelude True
                            , ImportDecl False bigInteger False
                            , ImportDecl False runtimeException False
                            , ImportDecl False byteBuffer False
                            ] ++ otherHdrs
                          )
                          <$> mkTypeDecl clsName globalInit defs
  where
    idrisRts = J.Name $ map Ident ["org", "idris", "rts"]
    idrisPrelude = J.Name $ map Ident ["org", "idris", "rts", "Prelude"]
    bigInteger = J.Name $ map Ident ["java", "math", "BigInteger"]
    runtimeException = J.Name $ map Ident ["java", "lang", "RuntimeException"]
    byteBuffer = J.Name $ map Ident ["java", "nio", "ByteBuffer"]
    otherHdrs = map ( (\ name -> ImportDecl False name False)
                      . J.Name
                      . map (Ident . T.unpack)
                      . T.splitOn (T.pack ".")
                      . T.pack)
                $ filter (not . isSuffixOf ".h") hdrs

-----------------------------------------------------------------------
-- Main class

mkTypeDecl :: Ident -> [(Name, SExp)] -> [(Name, SDecl)] -> CodeGeneration [TypeDecl]
mkTypeDecl name globalInit defs =
  (\ body -> [ClassTypeDecl $ ClassDecl [ Public
                                        ,  Annotation $ SingleElementAnnotation
                                           (jName "SuppressWarnings")
                                           (EVVal . InitExp $ jString "unchecked")
                                        ]
              name
              []
              Nothing
              []
              body])
  <$> mkClassBody globalInit (map (second (prefixCallNamespaces name)) defs)

mkClassBody :: [(Name, SExp)] -> [(Name, SDecl)] -> CodeGeneration ClassBody
mkClassBody globalInit defs =
  (\ globals defs -> ClassBody . (globals++) . addMainMethod . mergeInnerClasses $ defs)
  <$> mkGlobalContext globalInit
  <*> mapM mkDecl defs

mkGlobalContext :: [(Name, SExp)] -> CodeGeneration [Decl]
mkGlobalContext [] = return []
mkGlobalContext initExps = do
  pushScope
  varInit <-
    mapM (\ (name, exp) -> do
           pos <- setVariable (Glob name)
           mkUpdate ignoreResult (Glob name) exp
         ) initExps
  popScope
  return [ MemberDecl $ FieldDecl [Private, Static, Final]
                                      (array objectType)
                                      [ VarDecl (VarId $ globalContextID). Just . InitExp
                                        $ ArrayCreate objectType [jInt $ length initExps] 0
                                      ]
         , InitDecl True (Block $ concat varInit)
         ]

addMainMethod :: [Decl] -> [Decl]
addMainMethod decls
  | findMainMethod decls = mkMainMethod : decls
  | otherwise = decls
  where
    findMainMethod ((MemberDecl (MethodDecl _ _ _ name [] _ _)):_)
      | name == mangle' (sMN 0 "runMain") = True
    findMainMethod (_:decls) = findMainMethod decls
    findMainMethod [] = False

mkMainMethod :: Decl
mkMainMethod =
  simpleMethod
    [Public, Static]
    Nothing
    "main"
    [FormalParam [] (array stringType) False (VarId $ Ident "args")]
    $ Block [ BlockStmt . ExpStmt
              $ call "idris_initArgs" [ jConst "args" ]
            , BlockStmt . ExpStmt $ call (mangle' (sMN 0 "runMain")) []
            ]

-----------------------------------------------------------------------
-- Inner classes (idris namespaces)

mergeInnerClasses :: [Decl] -> [Decl]
mergeInnerClasses = foldl' mergeInner []
  where
    mergeInner ((decl@(MemberDecl (MemberClassDecl (ClassDecl priv name targs ext imp (ClassBody body))))):decls)
               decl'@(MemberDecl (MemberClassDecl (ClassDecl _ name' _ ext' imp' (ClassBody body'))))
      | name == name' =
        (MemberDecl $ MemberClassDecl $
                    ClassDecl priv
                              name
                              targs
                              (mplus ext ext')
                              (imp ++ imp')
                              (ClassBody $ mergeInnerClasses (body ++ body')))
        : decls
      | otherwise = decl:(mergeInner decls decl')
    mergeInner (decl:decls) decl' = decl:(mergeInner decls decl')
    mergeInner [] decl' = [decl']

mkDecl :: (Name, SDecl) -> CodeGeneration Decl
mkDecl ((NS n (ns:nss)), decl) =
  (\ name body ->
    MemberDecl $ MemberClassDecl $ ClassDecl [Public, Static] name [] Nothing [] body)
  <$> mangle (UN ns)
  <*> mkClassBody [] [(NS n nss, decl)]
mkDecl (_, SFun name params stackSize body) = do
  (Ident methodName) <- mangle name
  methodParams <- mapM mkFormalParam params
  paramNames <- mapM mangle params
  pushParams paramNames
  methodBody <- mkExp addReturn body
  popScope
  return $
    simpleMethod [Public, Static] (Just objectType) methodName methodParams
      (Block methodBody)

mkFormalParam :: Name -> CodeGeneration FormalParam
mkFormalParam name =
  (\ name -> FormalParam [Final] objectType False (VarId name))
  <$> mangle name

-----------------------------------------------------------------------
-- Expressions

-- | Compile a simple expression and use the given continuation to postprocess
-- the resulting value.
mkExp :: BlockPostprocessor -> SExp -> CodeGeneration [BlockStmt]
-- Variables
mkExp pp (SV var) =
  (Nothing <>@! var) >>= ppExp pp

-- Applications
mkExp pp (SApp pushTail name args) =
  mkApp pushTail name args >>= ppExp pp

-- Bindings
mkExp pp (SLet    var newExp inExp) =
  mkLet pp var newExp inExp
mkExp pp (SUpdate var@(Loc i) newExp) = -- can only update locals
  mkUpdate pp var newExp
mkExp pp (SUpdate var newExp) =
  mkExp pp newExp

-- Objects
mkExp pp (SCon _ conId _ args) =
  mkIdrisObject conId args >>= ppExp pp

-- Case expressions
mkExp pp (SCase up var alts) = mkCase pp True var alts
mkExp pp (SChkCase var alts) = mkCase pp False var alts

-- Projections
mkExp pp (SProj var i) =
  mkProjection var i >>= ppExp pp

-- Constants
mkExp pp (SConst c) =
  ppExp pp $ mkConstant c

-- Foreign function calls
mkExp pp f@(SForeign t fname args) = mkForeign pp t fname args

-- Primitive functions
mkExp pp (SOp LFork [arg]) =
  (mkThread arg) >>= ppExp pp
mkExp pp (SOp LPar [arg]) =
  (Nothing <>@! arg) >>= ppExp pp
mkExp pp (SOp LNoOp args) =
  (Nothing <>@! (last args)) >>= ppExp pp

mkExp pp (SOp op args) =
  (mkPrimitiveFunction op args) >>= ppExp pp

-- Empty expressions
mkExp pp (SNothing) = ppExp pp $ Lit Null

-- Errors
mkExp pp (SError err) = ppExp (throwRuntimeException pp) (jString err)

-----------------------------------------------------------------------
-- Variable access

(<>@!) :: Maybe J.Type -> LVar -> CodeGeneration Exp
(<>@!) Nothing var =
  either ArrayAccess (\ n -> ExpName $ J.Name [n]) <$> varPos var
(<>@!) (Just castTo) var =
  (castTo <>) <$> (Nothing <>@! var)

-----------------------------------------------------------------------
-- Application (wrap method calls in tail call closures)

mkApp :: Bool -> Name -> [LVar] -> CodeGeneration Exp
mkApp False name args =
  (\ methodName params ->
    (idrisClosureType ~> "unwrapTailCall") [call methodName params]
  )
  <$> mangleFull name
  <*> mapM (Nothing <>@!) args
mkApp True name args = mkMethodCallClosure name args

mkMethodCallClosure :: Name -> [LVar] -> CodeGeneration Exp
mkMethodCallClosure name args =
  (\ name args -> closure (call name args))
  <$> mangleFull name
  <*> mapM (Nothing <>@!) args

-----------------------------------------------------------------------
-- Updates (change context array) and Let bindings (Update, execute)

mkUpdate :: BlockPostprocessor -> LVar -> SExp -> CodeGeneration [BlockStmt]
mkUpdate pp var exp =
  mkExp
    ( pp
      { ppInnerBlock =
           (\ blk rhs -> do
               pos <- setVariable var
               vExp <- Nothing <>@! var
               ppInnerBlock pp (blk ++ [pos @:= rhs]) vExp
           )
      }
    ) exp

mkLet :: BlockPostprocessor -> LVar -> SExp -> SExp -> CodeGeneration [BlockStmt]
mkLet pp var@(Loc pos) newExp inExp =
  mkUpdate (pp { ppInnerBlock =
                    (\ blk _ -> do
                        inBlk <- mkExp pp inExp
                        return (blk ++ inBlk)
                    )
               }
           ) var newExp
mkLet _ (Glob _) _ _ = T.lift $ Left "Cannot let bind to global variable"

-----------------------------------------------------------------------
-- Object creation

mkIdrisObject :: Int -> [LVar] -> CodeGeneration Exp
mkIdrisObject conId args =
  (\ args ->
    InstanceCreation [] (toClassType idrisObjectType) ((jInt conId):args) Nothing
  )
  <$> mapM (Nothing <>@!) args

-----------------------------------------------------------------------
-- Case expressions

mkCase :: BlockPostprocessor -> Bool -> LVar -> [SAlt] -> CodeGeneration [BlockStmt]
mkCase pp checked var cases
  | isDefaultOnlyCase cases = mkDefaultMatch pp cases
  | isConstCase cases = do
    ifte <- mkConstMatch (ignoreOuter pp) (\ pp -> mkDefaultMatch pp cases) var cases
    ppOuterBlock pp [BlockStmt ifte]
  | otherwise = do
    switchExp <- mkGetConstructorId checked var
    matchBlocks <- mkConsMatch (ignoreOuter pp) (\ pp -> mkDefaultMatch pp cases) var cases
    ppOuterBlock pp [BlockStmt $ Switch switchExp matchBlocks]

isConstCase :: [SAlt] -> Bool
isConstCase ((SConstCase _ _):_) = True
isConstCase ((SDefaultCase _):cases) = isConstCase cases
isConstCase _ = False

isDefaultOnlyCase :: [SAlt] -> Bool
isDefaultOnlyCase [SDefaultCase _] = True
isDefaultOnlyCase [] = True
isDefaultOnlyCase _ = False

mkDefaultMatch :: BlockPostprocessor -> [SAlt] -> CodeGeneration [BlockStmt]
mkDefaultMatch pp (x@(SDefaultCase branchExpression):_) =
  do pushScope
     stmt <- mkExp pp branchExpression
     popScope
     return stmt
mkDefaultMatch pp (x:xs) = mkDefaultMatch pp xs
mkDefaultMatch pp [] =
  ppExp (throwRuntimeException pp) (jString "Non-exhaustive pattern")

mkMatchConstExp :: LVar -> Const -> CodeGeneration Exp
mkMatchConstExp var c
  | isPrimitive cty =
    (\ var -> (primFnType ~> opName (LEq undefined)) [var, jc] ~==~ jInt 1)
    <$> (Just cty <>@! var)
  | isArray cty =
    (\ var -> (arraysType ~> "equals") [var, jc])
    <$> (Just cty <>@! var)
  | isString cty =
    (\ var -> ((primFnType ~> opName (LStrEq)) [var, jc] ~==~ jInt 1))
    <$> (Just cty <>@! var)
  | otherwise =
    (\ var -> (var ~> "equals") [jc])
    <$> (Just cty <>@! var)
  where
    cty = constType c
    jc = mkConstant c

mkConstMatch :: BlockPostprocessor ->
                (BlockPostprocessor -> CodeGeneration [BlockStmt]) ->
                LVar ->
                [SAlt] ->
                CodeGeneration Stmt
mkConstMatch pp getDefaultStmts var ((SConstCase constant branchExpression):cases) = do
  matchExp <- mkMatchConstExp var constant
  pushScope
  branchBlock <- mkExp pp branchExpression
  popScope
  otherBranches <- mkConstMatch pp getDefaultStmts var cases
  return
    $ IfThenElse matchExp (StmtBlock $ Block branchBlock) otherBranches
mkConstMatch pp getDefaultStmts var (c:cases) = mkConstMatch pp getDefaultStmts var cases
mkConstMatch pp getDefaultStmts _ [] = do
  defaultBlock <- getDefaultStmts pp
  return $ StmtBlock (Block defaultBlock)

mkGetConstructorId :: Bool -> LVar -> CodeGeneration Exp
mkGetConstructorId True var =
  (\ var -> ((idrisObjectType <> var) ~> "getConstructorId") [])
  <$> (Nothing <>@! var)
mkGetConstructorId False var =
  (\ var match ->
    Cond (InstanceOf var (toRefType idrisObjectType)) match (jInt (-1))
  )
  <$> (Nothing <>@! var)
  <*> mkGetConstructorId True var

mkConsMatch :: BlockPostprocessor ->
               (BlockPostprocessor -> CodeGeneration [BlockStmt]) ->
               LVar ->
               [SAlt] ->
               CodeGeneration [SwitchBlock]
mkConsMatch pp getDefaultStmts var ((SConCase parentStackPos consIndex _ params branchExpression):cases) = do
  pushScope
  caseBranch <- mkCaseBinding pp var parentStackPos params branchExpression
  popScope
  otherBranches <- mkConsMatch pp getDefaultStmts var cases
  return $
    (SwitchBlock (SwitchCase $ jInt consIndex) caseBranch):otherBranches
mkConsMatch pp getDefaultStmts var (c:cases)  = mkConsMatch pp getDefaultStmts var cases
mkConsMatch pp getDefaultStmts _ [] = do
  defaultBlock <- getDefaultStmts pp
  return $
    [SwitchBlock Default defaultBlock]

mkCaseBinding :: BlockPostprocessor -> LVar -> Int -> [Name] -> SExp -> CodeGeneration [BlockStmt]
mkCaseBinding pp var stackStart params branchExpression =
  mkExp pp (toLetIn var stackStart params branchExpression)
  where
    toLetIn :: LVar -> Int -> [Name] -> SExp -> SExp
    toLetIn var stackStart members start =
      foldr
        (\ pos inExp -> SLet (Loc (stackStart + pos)) (SProj var pos) inExp)
        start
        [0.. (length members - 1)]

-----------------------------------------------------------------------
-- Projection (retrieve the n-th field of an object)

mkProjection :: LVar -> Int -> CodeGeneration Exp
mkProjection var memberNr =
  (\ var -> ArrayAccess $ ((var ~> "getData") []) @! memberNr)
  <$> (Just idrisObjectType <>@! var)

-----------------------------------------------------------------------
-- Constants

mkConstantArray :: (V.Unbox a) => J.Type -> (a -> Const) -> V.Vector a -> Exp
mkConstantArray cty elemToConst elems =
  ArrayCreateInit
    cty
    0
    (ArrayInit . map (InitExp . mkConstant . elemToConst) $ V.toList elems)

mkConstant :: Const -> Exp
mkConstant c@(I        x) = constType c <> (Lit . Word $ toInteger x)
mkConstant c@(BI       x) = bigInteger (show x)
mkConstant c@(Fl       x) = constType c <> (Lit . Double $ x)
mkConstant c@(Ch       x) = constType c <> (Lit . Char $ x)
mkConstant c@(Str      x) = constType c <> (Lit . String $ x)
mkConstant c@(B8       x) = constType c <> (Lit . Word $ toInteger x)
mkConstant c@(B16      x) = constType c <> (Lit . Word $ toInteger x)
mkConstant c@(B32      x) = constType c <> (Lit . Word $ toInteger x)
mkConstant c@(B64      x) = (bigInteger (show c) ~> "longValue") []
mkConstant c@(AType    x) = ClassLit (Just $ box (constType c))
mkConstant c@(StrType   ) = ClassLit (Just $ stringType)
mkConstant c@(VoidType  ) = ClassLit (Just $ voidType)
mkConstant c@(WorldType ) = ClassLit (Just $ worldType)
mkConstant c@(TheWorld  ) = worldType <> (Lit . Word $ toInteger 0)
mkConstant c@(Forgot    ) = ClassLit (Just $ objectType)

-----------------------------------------------------------------------
-- Foreign function calls

-- TODO: @bgaster add support for calling C (via Java's JNI)
mkForeign :: BlockPostprocessor -> FDesc -> FDesc -> [(FDesc, LVar)] -> CodeGeneration [BlockStmt]
mkForeign pp resTy@(FCon t) fname params
  | isCType t = error ("Java backend does not (currently) support calling C")
  | isJavaType t = mkForeignJava pp resTy fname params
  | otherwise = error (show t ++ " " ++ show fname ++ " " ++ show params)

mkForeign pp resTy@(FApp t args) fname params
  | isCType t = error ("Java backend does not (currently) support calling C")
  | isJavaType t = mkForeignJava pp resTy fname params
  | otherwise = error (show t ++ " " ++ show fname ++ " " ++ show params)

mkForeign pp t fname args = error (show t ++ " " ++ show fname ++ " " ++ show args)

mkForeignJava :: BlockPostprocessor ->
                 FDesc ->
                 FDesc ->
                 [(FDesc, LVar)] ->
                 CodeGeneration [BlockStmt]

mkForeignJava pp resTy (FApp (UN (T.unpack -> "JavaInvoke")) [FStr fname]) params = do
  method <- liftParsed (parser name fname)
  args <- foreignVarAccess params
  wrapReturn pp resTy (call method args)

mkForeignJava pp resTy (FCon (UN (T.unpack -> "JavaNew"))) params = do
  clsTy <- liftParsed (parser classType (nameFromReturnType resTy))
  args <- foreignVarAccess params
  wrapReturn pp resTy (InstanceCreation [] clsTy args Nothing)

mkForeignJava pp
              resTy
              (FApp (UN (T.unpack -> "JavaInvokeDyn")) [FStr mname])
              params = do
  method <- liftParsed (parser ident mname)
  (tgt:args) <- foreignVarAccess params
  wrapReturn pp resTy ((tgt ~> (show $ pretty method)) args)

mkForeignJava pp resTy fdesc params =
  error ("mkFJava " ++ show resTy ++ " " ++ show fdesc ++ " " ++ show params)

-- Some helpers
foreignVarAccess = mapM (\(fty, var) -> (foreignType fty <>@! var))

wrapReturn pp (FCon t) exp
  | sUN "Java_Unit" == t = ((ppInnerBlock pp') [BlockStmt $ ExpStmt exp] (Lit Null)) >>= ppOuterBlock pp'
  | otherwise            = ((ppInnerBlock pp') [] exp) >>= ppOuterBlock pp'
  where
    pp' = rethrowAsRuntimeException pp

wrapReturn pp (FApp t args) exp = ((ppInnerBlock pp') [] exp) >>= ppOuterBlock pp'
  where
    pp' = rethrowAsRuntimeException pp

-----------------------------------------------------------------------
-- Primitive functions

mkPrimitiveFunction :: PrimFn -> [LVar] -> CodeGeneration Exp
mkPrimitiveFunction op args =
  (\ args -> (primFnType ~> opName op) (endiannessArguments op ++ args))
  <$> sequence (zipWith (\ a t -> (Just t) <>@! a) args (sourceTypes op))

mkThread :: LVar -> CodeGeneration Exp
mkThread arg =
  (\ closure -> (closure ~> "fork") []) <$> mkMethodCallClosure (sMN 0 "EVAL") [arg]


text:
package com.example.android.explicitintent;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class ChildActivity extends AppCompatActivity {

    private TextView displayText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_child);

        displayText = (TextView) findViewById(R.id.tv_display);
    }
}

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE html>

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>kicost.log__ — kicost 1.1.13 documentation</title>
    <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
    <link rel="stylesheet" href="../../_static/classic.css" type="text/css" />

    <link rel="index" title="Index" href="../../genindex.html" />
    <link rel="search" title="Search" href="../../search.html" />

Navigation

          index

          modules |

kicost 1.1.13 documentation »

Module code »

kicost.log__

Source code for kicost.log__

# -*- coding: utf-8 -*-
# MIT license
#
# Copyright (C) 2022 by Salvador E. Tropea / Instituto Nacional de Tecnologia Industrial
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

# Simple wrappers for the log functions in the main module

import logging

DEBUG_OVERVIEW = logging.DEBUG
DEBUG_DETAILED = logging.DEBUG-1
DEBUG_OBSESSIVE = logging.DEBUG-2
DEBUG_HTTP_HEADERS = logging.DEBUG-3
DEBUG_HTTP_RESPONSES = logging.DEBUG-4
DEBUG_FULL = logging.DEBUG-9
# Minimum possible log level is logging.DEBUG-9 !

# The root logger of the application. This has to be the root logger to catch
# output from libraries (e.g. requests) as well.
main_logger = None

[docs]def debug(*args):
    main_logger.log(*args)

[docs]def debug_detailed(*args):
    main_logger.log(DEBUG_DETAILED, *args)

[docs]def is_debug_detailed():
    return main_logger.getEffectiveLevel() <= DEBUG_DETAILED

[docs]def debug_overview(*args):
    main_logger.log(DEBUG_OVERVIEW, *args)

[docs]def is_debug_overview():
    return main_logger.getEffectiveLevel() <= DEBUG_OVERVIEW

[docs]def debug_obsessive(*args):
    main_logger.log(DEBUG_OBSESSIVE, *args)

[docs]def is_debug_obsessive():
    return main_logger.getEffectiveLevel() <= DEBUG_OBSESSIVE

[docs]def debug_full(*args):
    main_logger.log(DEBUG_FULL, *args)

[docs]def debug_general(*args):
    main_logger.debug(*args)

[docs]def info(*args):
    main_logger.info(*args)

[docs]def warning(code, msg):
    main_logger.warning(code + msg)

[docs]def error(*args):
    main_logger.error(*args)

[docs]def get_logger():
    global main_logger
    return main_logger

[docs]def set_logger(logger):
    global main_logger
    main_logger = logger

Quick search

    <form class="search" action="../../search.html" method="get">
      <input type="text" name="q" aria-labelledby="searchlabel" />
      <input type="submit" value="Go" />
    </form>

Navigation

          index

          modules |

kicost 1.1.13 documentation »

Module code »

kicost.log__

        © Copyright 2015, XESS Corporation.
      Created using Sphinx 3.4.3.


text:
declare namespace com {
  namespace sun {
    namespace nio {
      namespace sctp {

        interface Notification$$lambda {
          (): com.sun.nio.sctp.Association
        }

        interface Notification {
          association(): com.sun.nio.sctp.Association
        }

      }
    }
  }
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

namespace AutoGrid
{
    /// <summary>
    /// A grid control that automatically lays out children so you don't need to specify grid.row and grid.column
    /// You can specify row and or column definitions as normal or using a string like "auto,auto,10*,50,10*".
    /// If no column definitions are given you can set NumColumns and that many will be auto-created.
    /// You can also set default row height and column width.
    /// Children are then inserted into cells one row at a time from left to right. New rows are created as required.
    /// Handles colspan and rowspanned children.
    /// </summary>
    public class AutoGrid : Grid
    {
        private bool _hasLoaded;

        public override void EndInit()
        {
            Initialize();
            base.EndInit();
        }

        private void Initialize()
        {
            if (!_hasLoaded && !String.IsNullOrWhiteSpace(Rows))
            {
                var heights = GridLengthParser.FromString(Rows);
                foreach (var height in heights)
                {
                    RowDefinitions.Add(new RowDefinition { Height = height });
                }
            }

            if (!_hasLoaded && !String.IsNullOrWhiteSpace(Columns))
            {
                var widths = GridLengthParser.FromString(Columns);
                foreach (var width in widths)
                {
                    ColumnDefinitions.Add(new ColumnDefinition { Width = width });
                }
            }

            _hasLoaded = true;

            for (int i = ColumnDefinitions.Count; i < NumColumns; i++)
            {
                ColumnDefinitions.Add(new ColumnDefinition { Width = ColumnWidth });
            }

            if (RowDefinitions.Count == 0)
            {
                RowDefinitions.Add(new RowDefinition { Height = RowHeight });
            }

            var currentColumn = 0;
            var currentRow = 0;
            var columnCount = ColumnDefinitions.Count == 0 ? 1 : ColumnDefinitions.Count; //if we have no col defs we have one col.

            foreach (var child in Children)
            {
                if (!GetAutoplace((UIElement)child)) continue;

                var childColumnSpan = GetColumnSpan((FrameworkElement)child);
                var childRowSpan = GetRowSpan((FrameworkElement)child);
                var placed = false;

                while (!placed)
                {
                    var cellsLeft = columnCount - currentColumn;

                    if (currentColumn != 0 && cellsLeft < childColumnSpan) //can't fit this row
                    {
                        currentRow = GetNextRowAndAddIfRequired(currentRow);
                        currentColumn = 0;
                        continue;
                    }

                    if (IsFull(currentRow, currentColumn, childColumnSpan))
                    {
                        currentColumn++;
                        continue;
                    }

                    SetColumn((FrameworkElement)child, currentColumn);
                    SetRow((FrameworkElement)child, currentRow);
                    AddSpannedCells(currentRow, currentColumn, childRowSpan, childColumnSpan);
                    currentColumn += childColumnSpan;
                    placed = true;
                }
            }

            if (StretchLastRow)
            {
                RowDefinitions.Last().Height = new GridLength(1, GridUnitType.Star);
            }
        }

        private bool IsFull(int row, int col, int childColumnSpan)
        {

            for (var i = col; i < col + childColumnSpan; i++)
            {
                if (_spannedCells.Contains(new Tuple<int, int>(row, i))) return true;
            }
            return false;
        }

        private void AddSpannedCells(int currentRow, int currentColumn, int rowSpan, int columnSpan)
        {
            for (var i = currentRow; i < currentRow + rowSpan; i++)
            {
                for (var j = currentColumn; j < currentColumn + columnSpan; j++)
                {
                    _spannedCells.Add(new Tuple<int, int>(i, j));
                }
            }
        }

        private readonly HashSet<Tuple<int, int>> _spannedCells = new HashSet<Tuple<int, int>>();

        private int GetNextRowAndAddIfRequired(int currentRow)
        {
            if (RowDefinitions.Count <= currentRow + 1)
            {
                RowDefinitions.Add(new RowDefinition { Height = RowHeight });
                return RowDefinitions.Count - 1;
            }
            return currentRow + 1;
        }

        #region Dependency Properties

        public static readonly DependencyProperty NumColumnsProperty =
            DependencyProperty.Register("NumColumns", typeof(int), typeof(AutoGrid), new PropertyMetadata(default(int)));

        public static readonly DependencyProperty ColumnWidthProperty =
            DependencyProperty.Register("ColumnWidth", typeof(GridLength), typeof(AutoGrid), new PropertyMetadata(default(GridLength)));

        public static readonly DependencyProperty RowHeightProperty =
            DependencyProperty.Register("RowHeight", typeof(GridLength), typeof(AutoGrid), new PropertyMetadata(default(GridLength)));

        public static readonly DependencyProperty StretchLastRowProperty =
            DependencyProperty.Register("StretchLastRow", typeof(bool), typeof(AutoGrid), new PropertyMetadata(default(bool)));

        public static readonly DependencyProperty RowsProperty =
            DependencyProperty.Register("Rows", typeof(string), typeof(AutoGrid), new PropertyMetadata(default(string)));

        public static readonly DependencyProperty ColumnsProperty =
            DependencyProperty.Register("Columns", typeof(string), typeof(AutoGrid), new PropertyMetadata(default(string)));

        #endregion

        /// <summary>
        /// Set the height of the last row *
        /// </summary>
        public bool StretchLastRow
        {
            get { return (bool)GetValue(StretchLastRowProperty); }
            set { SetValue(StretchLastRowProperty, value); }
        }

        /// <summary>
        /// The number of columns in the grid
        /// </summary>
        public int NumColumns
        {
            get { return (int)GetValue(NumColumnsProperty); }
            set { SetValue(NumColumnsProperty, value); }
        }

        /// <summary>
        /// The width of each column, can be *, auto or a pixel number
        /// </summary>
        public GridLength ColumnWidth
        {
            get { return (GridLength)GetValue(ColumnWidthProperty); }
            set { SetValue(ColumnWidthProperty, value); }
        }

        /// <summary>
        /// The height of each row, can be *, auto or a pixel number
        /// </summary>
        public GridLength RowHeight
        {
            get { return (GridLength)GetValue(RowHeightProperty); }
            set { SetValue(RowHeightProperty, value); }
        }

        /// <summary>
        /// Used to manually define rows using a string like "auto,auto,*,10"
        /// </summary>
        public string Rows
        {
            get { return (string)GetValue(RowsProperty); }
            set { SetValue(RowsProperty, value); }
        }

        /// <summary>
        /// Used to manually define columns using a string like "auto,auto,*,10"
        /// </summary>
        public string Columns
        {
            get { return (string)GetValue(ColumnsProperty); }
            set { SetValue(ColumnsProperty, value); }
        }

        /// <summary>
        /// Use to grid.row and grid.column from being ignored to manually layout a child element. (set autogrid.autoplace="false" on the child)
        /// </summary>
        public static readonly DependencyProperty AutoplaceProperty =
            DependencyProperty.RegisterAttached("Autoplace", typeof (bool), typeof (AutoGrid), new PropertyMetadata(true));

        public static void SetAutoplace(UIElement element, bool value)
        {
            element.SetValue(AutoplaceProperty, value);
        }

        public static bool GetAutoplace(UIElement element)
        {
            return (bool) element.GetValue(AutoplaceProperty);
        }
    }
}


text:
<?php

/**
 * Reports Product Index Abstract Model
 *
 * @category   Mage
 * @package    Mage_Reports
 * @author     Magento Core Team <core@magentocommerce.com>
 */
abstract class Mage_Reports_Model_Product_Index_Abstract extends Mage_Core_Model_Abstract
{
    /**
     * Cache key name for Count of product index
     *
     * @var string
     */
    protected $_countCacheKey;

    /**
     * Prepare customer/visitor, store data before save
     *
     * @return Mage_Reports_Model_Product_Index_Abstract
     */
    protected function _beforeSave()
    {
        parent::_beforeSave();

        if (!$this->hasVisitorId()) {
            $this->setVisitorId($this->getVisitorId());
        }
        if (!$this->hasCustomerId()) {
            $this->setCustomerId($this->getCustomerId());
        }
        if (!$this->hasStoreId()) {
            $this->setStoreId($this->getStoreId());
        }
        if (!$this->hasAddedAt()) {
            $this->setAddedAt(now());
        }

        return $this;
    }

    /**
     * Retrieve visitor id
     *
     * if don't exists return current visitor id
     *
     * @return int
     */
    public function getVisitorId()
    {
        if ($this->hasData('visitor_id')) {
            return $this->getData('visitor_id');
        }
        return Mage::getSingleton('log/visitor')->getId();
    }

    /**
     * Retrieve customer id
     *
     * if customer don't logged in return null
     *
     * @return int
     */
    public function getCustomerId()
    {
        if ($this->hasData('customer_id')) {
            return $this->getData('customer_id');
        }
        return Mage::getSingleton('customer/session')->getCustomerId();
    }

    /**
     * Retrieve store id
     *
     * default return current store id
     *
     * @return int
     */
    public function getStoreId()
    {
        if ($this->hasData('store_id')) {
            return $this->getData('store_id');
        }
        return Mage::app()->getStore()->getId();
    }

    /**
     * Retrieve resource instance wrapper
     *
     * @return Mage_Reports_Model_Mysql4_Product_Index_Abstract
     */
    protected function _getResource()
    {
        return parent::_getResource();
    }

    /**
     * On customer loggin merge visitor/customer index
     *
     * @return Mage_Reports_Model_Product_Index_Abstract
     */
    public function updateCustomerFromVisitor()
    {
        $this->_getResource()->updateCustomerFromVisitor($this);
        return $this;
    }

    /**
     * Purge visitor data by customer (logout)
     *
     * @return Mage_Reports_Model_Product_Index_Abstract
     */
    public function purgeVisitorByCustomer()
    {
        $this->_getResource()->purgeVisitorByCustomer($this);
        return $this;
    }

    /**
     * Retrieve Reports Session instance
     *
     * @return Mage_Reports_Model_Session
     */
    protected function _getSession()
    {
        return Mage::getSingleton('reports/session');
    }

    /**
     * Calculate count of product index items cache
     *
     * @return Mage_Reports_Model_Product_Index_Abstract
     */
    public function calculate()
    {
        $collection = $this->getCollection()
            ->setCustomerId($this->getCustomerId())
            ->addIndexFilter();

        Mage::getSingleton('catalog/product_visibility')
            ->addVisibleInSiteFilterToCollection($collection);

        $count = $collection->getSize();
        $this->_getSession()->setData($this->_countCacheKey, $count);
        return $this;
    }

    /**
     * Retrieve Exclude Product Ids List for Collection
     *
     * @return array
     */
    public function getExcludeProductIds()
    {
        return array();
    }

    /**
     * Retrieve count of product index items
     *
     * @return int
     */
    public function getCount()
    {
        if (!$this->_countCacheKey) {
            return 0;
        }

        if (!$this->_getSession()->hasData($this->_countCacheKey)) {
            $this->calculate();
        }

        return $this->_getSession()->getData($this->_countCacheKey);
    }

    /**
     * Clean index (visitors)
     *
     * @return Mage_Reports_Model_Product_Index_Abstract
     */
    public function clean()
    {
        $this->_getResource()->clean($this);
        return $this;
    }

    /**
     * Add product ids to current visitor/customer log
     * @param array $productIds
     * @return Mage_Reports_Model_Product_Index_Abstract
     */
    public function registerIds($productIds)
    {
        $this->_getResource()->registerIds($this, $productIds);
        $this->_getSession()->unsData($this->_countCacheKey);
        return $this;
    }
}


text:
import { test } from 'ember-qunit';
import moduleFor from 'open-event-frontend/tests/helpers/unit-helper';

moduleFor('route:settings/password', 'Unit | Route | settings/password', []);

test('it exists', function(assert) {
  let route = this.subject();
  assert.ok(route);
});


text:
using namespace llvm;

Comdat::Comdat(Comdat &&C) : Name(C.Name), SK(C.SK) {}

Comdat::Comdat() = default;

StringRef Comdat::getName() const { return Name->first(); }

LLVMComdatRef LLVMGetOrInsertComdat(LLVMModuleRef M, const char *Name) {
  return wrap(unwrap(M)->getOrInsertComdat(Name));
}

LLVMComdatRef LLVMGetComdat(LLVMValueRef V) {
  GlobalObject *G = unwrap<GlobalObject>(V);
  return wrap(G->getComdat());
}

void LLVMSetComdat(LLVMValueRef V, LLVMComdatRef C) {
  GlobalObject *G = unwrap<GlobalObject>(V);
  G->setComdat(unwrap(C));
}

LLVMComdatSelectionKind LLVMGetComdatSelectionKind(LLVMComdatRef C) {
  switch (unwrap(C)->getSelectionKind()) {
  case Comdat::Any:
    return LLVMAnyComdatSelectionKind;
  case Comdat::ExactMatch:
    return LLVMExactMatchComdatSelectionKind;
  case Comdat::Largest:
    return LLVMLargestComdatSelectionKind;
  case Comdat::NoDuplicates:
    return LLVMNoDuplicatesComdatSelectionKind;
  case Comdat::SameSize:
    return LLVMSameSizeComdatSelectionKind;
  }
  llvm_unreachable("Invalid Comdat SelectionKind!");
}

void LLVMSetComdatSelectionKind(LLVMComdatRef C, LLVMComdatSelectionKind kind) {
  Comdat *Cd = unwrap(C);
  switch (kind) {
  case LLVMAnyComdatSelectionKind:
    Cd->setSelectionKind(Comdat::Any);
    break;
  case LLVMExactMatchComdatSelectionKind:
    Cd->setSelectionKind(Comdat::ExactMatch);
    break;
  case LLVMLargestComdatSelectionKind:
    Cd->setSelectionKind(Comdat::Largest);
    break;
  case LLVMNoDuplicatesComdatSelectionKind:
    Cd->setSelectionKind(Comdat::NoDuplicates);
    break;
  case LLVMSameSizeComdatSelectionKind:
    Cd->setSelectionKind(Comdat::SameSize);
    break;
  }
}


text:
Connecting to Office 365 is the first step every app must take to start working with Office 365 services and data. This sample shows how to connect and then call the Microsoft Graph API (previously called Office 365 unified API), and uses the Office Fabric UI to create an Office 365 experience.

> Note: Try out the [Get started with Office 365 APIs](http://dev.office.com/getting-started/office365apis?platform=option-angular#setup) page which simplifies registration so you can get this sample running faster.

![Office 365 Angular Connect sample screenshot](./README assets/screenshot.png)

## Prerequisites

To use the Office 365 Angular Connect sample, you need the following:
* [Node.js](https://nodejs.org/). Node is required to run the sample on a development server and to install dependencies.
* An Office 365 account. You can sign up for [an Office 365 Developer subscription](https://portal.office.com/Signup/Signup.aspx?OfferId=6881A1CB-F4EB-4db3-9F18-388898DAF510&DL=DEVELOPERPACK&ali=1#0) that includes the resources that you need to start building Office 365 apps.

     > Note: If you already have a subscription, the previous link sends you to a page with the message *Sorry, you can't add that to your current account*. In that case use an account from your current Office 365 subscription.
* A Microsoft Azure tenant to register your application. Azure Active Directory (AD) provides identity services that applications use for authentication and authorization. A trial subscription can be acquired here: [Microsoft Azure](https://account.windowsazure.com/SignUp).

     > Important: You also need to make sure your Azure subscription is bound to your Office 365 tenant. To do this, see the Active Directory team's blog post, [Creating and Managing Multiple Windows Azure Active Directories](http://blogs.technet.com/b/ad/archive/2013/11/08/creating-and-managing-multiple-windows-azure-active-directories.aspx). The section **Adding a new directory** will explain how to do this. You can also see [Set up your Office 365 development environment](https://msdn.microsoft.com/office/office365/howto/setup-development-environment#bk_CreateAzureSubscription) and the section **Associate your Office 365 account with Azure AD to create and manage apps** for more information.
* A client ID of an application registered in Azure. This sample application must be granted the **Send mail as signed-in user** and **Send mail as signed-in user** permissions for the **Microsoft Graph** application. [Add a web application in Azure](https://msdn.microsoft.com/office/office365/HowTo/add-common-consent-manually#bk_RegisterWebApp) and [grant the proper permissions](https://github.com/OfficeDev/O365-Angular-Microsoft-Graph-Connect/wiki/Grant-permissions-to-the-Connect-application-in-Azure) to it.

     > Note: During the app registration process, make sure to specify **http://localhost:8080/** as the **Sign-on URL**.

## Configure and run the app

1. Using your favorite IDE, open **config.js** in *public/scripts*.
2. Replace *ENTER_YOUR_CLIENT_ID* with the client ID of your registered Azure application.
3. Install project dependencies with Node's package manager (npm) by running ```npm install``` in the project's root directory on the command line.
4. Start the development server by running ```node server.js``` in the project's root directory.
5. Navigate to ```http://localhost:8080/``` in your web browser.

To learn more about the sample, visit the [Angular walkthrough on graph.microsoft.io.](http://graph.microsoft.io/docs/platform/angular).

## Register your application with Azure Active Directory
	1. Sign into the Azure Management Portal using your Office 365 Tenant Administrator credentials.
	2. Click Active Directory on the left menu, then click on the directory for your Office 365 developer site.

![Office 365 Angular Connect sample screenshot2](/README assets/screenshot1.png)

	3. On the top menu, click Applications.
	4. Click Add from the bottom menu.

![Office 365 Angular Connect sample screenshot](./README assets/screenshot2.png)

	5. On the What do you want to do page, click Add an application my organization is developing.
	6. On the Tell us about your application page, specify any name [Add2Calendar] for the application name and select NATIVE CLIENT APPLICATION [in this case you want web application] for Type.
	7. Click the arrow icon on the bottom-right corner of the page.
	8. On the Application information page, specify a Redirect URI, for this example, you can specify http://localhost:8080.   Click the checkbox in the bottom right corner of the page.
	9. Once the application has been successfully added, you will be taken to the Quick Start page for the application. From here, click Configure in the top menu.
	10. In permissions to other applications, click Add application.
	11. Click Microsoft Graph, and then click the check mark icon.
	12. Under permissions to other applications, click the Delegated Permissions column for Microsoft Graph.  Select Have Full Access to User's Calendars. These are the permissions that will be displayed to your app user when Azure prompts them to consent to your app's permission request. In general, request only the services your app actually requires, and specify the least level of permissions in each service that still enable your app to perform its functions.

![Office 365 Angular Connect sample screenshot](./README assets/screenshot3.png)

	13. Select Yes for Application is Multi-Tenant.  This will allow the application to read from any Tenant in O365 if the user gives permission.

![Office 365 Angular Connect sample screenshot](./README assets/screenshot4.png)

	14. Copy the value specified for Client ID; you will need to paste this into the config.js file in the project.

![Office 365 Angular Connect sample screenshot](./README assets/screenshot5.png)

	15. Click Save in the bottom menu.

## Questions and comments

We'd love to get your feedback about the Office 365 Calendar sample. You can send your questions and suggestions to us in the [Issues](https://github.com/chadbrooks/Add2Calendar/issues) section of this repository.

Your feedback is important to us. Connect with us on [Stack Overflow](http://stackoverflow.com/questions/tagged/office365+or+microsoftgraph). Tag your questions with [MicrosoftGraph] and [office365].

## Additional resources

* [Office Dev Center](http://dev.office.com/)
* [Microsoft Graph API](http://graph.microsoft.io)
* [Office 365 Profile sample for Angular](https://github.com/OfficeDev/O365-Angular-Profile)
* [Office UI Fabric](http://dev.office.com/fabric)

## Copyright
Copyright (c) 2015 Microsoft. All rights reserved.


text:
/* TEMPLATE GENERATED TESTCASE FILE
Filename: CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_72a.cpp
Label Definition File: CWE121_Stack_Based_Buffer_Overflow__CWE193.label.xml
Template File: sources-sink-72a.tmpl.cpp
*/
/*
 * @description
 * CWE: 121 Stack Based Buffer Overflow
 * BadSource:  Point data to a buffer that does not have space for a NULL terminator
 * GoodSource: Point data to a buffer that includes space for a NULL terminator
 * Sinks: memmove
 *    BadSink : Copy string to data using memmove()
 * Flow Variant: 72 Data flow: data passed in a vector from one function to another in different source files
 *
 * */

#include "std_testcase.h"
#include <vector>

#ifndef _WIN32
#include <wchar.h>
#endif

/* MAINTENANCE NOTE: The length of this string should equal the 10 */
#define SRC_STRING L"AAAAAAAAAA"

using namespace std;

namespace CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_72
{

#ifndef OMITBAD

/* bad function declaration */
void badSink(vector<wchar_t *> dataVector);

void bad()
{
    wchar_t * data;
    vector<wchar_t *> dataVector;
    wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t));
    wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t));
    /* FLAW: Set a pointer to a buffer that does not leave room for a NULL terminator when performing
     * string copies in the sinks  */
    data = dataBadBuffer;
    data[0] = L'\0'; /* null terminate */
    /* Put data in a vector */
    dataVector.insert(dataVector.end(), 1, data);
    dataVector.insert(dataVector.end(), 1, data);
    dataVector.insert(dataVector.end(), 1, data);
    badSink(dataVector);
}

#endif /* OMITBAD */

#ifndef OMITGOOD

/* good function declarations */

/* goodG2B uses the GoodSource with the BadSink */
void goodG2BSink(vector<wchar_t *> dataVector);

static void goodG2B()
{
    wchar_t * data;
    vector<wchar_t *> dataVector;
    wchar_t * dataBadBuffer = (wchar_t *)ALLOCA((10)*sizeof(wchar_t));
    wchar_t * dataGoodBuffer = (wchar_t *)ALLOCA((10+1)*sizeof(wchar_t));
    /* FIX: Set a pointer to a buffer that leaves room for a NULL terminator when performing
     * string copies in the sinks  */
    data = dataGoodBuffer;
    data[0] = L'\0'; /* null terminate */
    /* Put data in a vector */
    dataVector.insert(dataVector.end(), 1, data);
    dataVector.insert(dataVector.end(), 1, data);
    dataVector.insert(dataVector.end(), 1, data);
    goodG2BSink(dataVector);
}

void good()
{
    goodG2B();
}

#endif /* OMITGOOD */

} /* close namespace */

/* Below is the main(). It is only used when building this testcase on
 * its own for testing or for building a binary to use in testing binary
 * analysis tools. It is not used when compiling all the testcases as one
 * application, which is how source code analysis tools are tested.
 */

#ifdef INCLUDEMAIN

using namespace CWE121_Stack_Based_Buffer_Overflow__CWE193_wchar_t_alloca_memmove_72; /* so that we can use good and bad easily */

int main(int argc, char * argv[])
{
    /* seed randomness */
    srand( (unsigned)time(NULL) );
#ifndef OMITGOOD
    printLine("Calling good()...");
    good();
    printLine("Finished good()");
#endif /* OMITGOOD */
#ifndef OMITBAD
    printLine("Calling bad()...");
    bad();
    printLine("Finished bad()");
#endif /* OMITBAD */
    return 0;
}

#endif


text:
package cn.fmachine.lintcode.medium;

import cn.fmachine.lintcode.util.UndirectedGraphNode;

import java.util.*;

/**
 * Find the number connected component in the undirected graph. Each node in the graph contains a label and a list of its neighbors. (a connected component (or just component) of an undirected graph is a subgraph in which any two vertices are connected to each other by paths, and which is connected to no additional vertices in the supergraph.)
 *

 * Notice
 *

 * Each connected component should sort by label.
 *

 * Have you met this question in a real interview? Yes
 * Clarification
 * Learn more about representation of graphs
 *

 * Example
 * Given graph:
 *

 * A------B  C
 * \     |  |
 * \    |  |
 * \   |  |
 * \  |  |
 * D   E
 * Return {A,B,D}, {C,E}. Since there are two connected component which is {A,B,D}, {C,E}
 *

 * Tags
 * Breadth First Search Union Find
 * Related Problems
 * Medium Graph Valid Tree 24 %
 * Medium Find the Weak Connected Component in the Directed Graph
 *

 * algorithm
 * Author: XIN MING
 * Date: 11/1/16
 * time O(n)
 * TODO Union Find
 */
public class FindTheConnectedComponentInTheUndirectedGraph {

    /**
     * @param nodes a array of Undirected graph node
     * @return a connected set of a Undirected graph
     */
    public List<List<Integer>> connectedSet(ArrayList<UndirectedGraphNode> nodes) {
        Map<UndirectedGraphNode, Boolean> visited = new HashMap<>();

        for (UndirectedGraphNode node : nodes) {
            visited.put(node, false);
        }
        List<List<Integer>> result = new ArrayList<>();
        for (UndirectedGraphNode node : nodes) {
            if (visited.get(node) == false) {
                bfs(result, visited, node);
            }
        }
        return result;
    }

    // bfs
    // only when we have to print result level by level
    // we will save size of each level , o/w we don't need to save size
    private void bfs(List<List<Integer>> result, Map<UndirectedGraphNode, Boolean> visited, UndirectedGraphNode node) {

        List<Integer> subset = new ArrayList<>();
        Queue<UndirectedGraphNode> q = new LinkedList<>();
        q.offer(node);
        visited.put(node, true);

        while (!q.isEmpty()) {
            UndirectedGraphNode cur = q.poll();
            subset.add(cur.label);

            for (UndirectedGraphNode neighbor : cur.neighbors) {
                if (!visited.get(neighbor)) {
                    visited.put(neighbor, true);
                    q.offer(neighbor);
                }
            }
        }
        Collections.sort(subset);//Each connected component should sort by label
        result.add(subset);
    }
}


text:
<?php

namespace Magento\Checkout\Test\Constraint;

use Magento\Checkout\Test\Page\CheckoutOnepage;
use Magento\Mtf\Constraint\AbstractConstraint;

/**
 * Assert that Order Subtotal is correct on Order Review page.
 */
class AssertSubTotalOrderReview extends AbstractConstraint
{
    /**
     * Assert that Order Subtotal is correct on Review page.
     *
     * @param CheckoutOnepage $checkoutOnepage
     * @param string $subTotal
     * @return void
     */
    public function processAssert(CheckoutOnepage $checkoutOnepage, $subTotal)
    {
        $reviewSubTotal = $checkoutOnepage->getReviewBlock()->getSubtotal();

        \PHPUnit_Framework_Assert::assertEquals(
            $reviewSubTotal,
            number_format($subTotal, 2),
            'Subtotal price: \'' . $reviewSubTotal
            . '\' not equals with price from data set: \'' . $reviewSubTotal . '\''
        );
    }

    /**
     * Returns a string representation of the object.
     *
     * @return string
     */
    public function toString()
    {
        return 'Subtotal price equals to price from data set.';
    }
}


text:
Contents
========

.. toctree::
   :maxdepth: 2
   :caption: Overview

   index
   carnivora-conventions
   dev

.. toctree::
   :maxdepth: 1
   :caption: Default Schemas
   :glob:

   schemas/*

.. toctree::
   :maxdepth: 2
   :caption: Buildins

   postgres-buildins
   yamsql-buildins


text:
<!DOCTYPE html>

  <meta charset="utf-8">
  <title>Redirecting...</title>

Please wait...


text:
<?php
namespace Tests\Http\Controllers;

use Illuminate\Support\Facades\Hash;
use Tests\TestCase;
use Xetaravel\Models\User;

class UserControllerTest extends TestCase
{
    /**
     * testIndexSuccess method
     *
     * @return void
     */
    public function testIndexSuccess()
    {
        $user = User::find(1);
        $this->be($user);

        $response = $this->get('/users');
        $response->assertSuccessful();
    }

    /**
     * testShowSuccess method
     *
     * @return void
     */
    public function testShowSuccess()
    {
        $user = User::find(1);
        $this->be($user);

        $response = $this->get('/users/profile/@admin');
        $response->assertSuccessful();
    }

    /**
     * testShowUserNotFound method
     *
     * @return void
     */
    public function testShowUserNotFound()
    {
        $response = $this->get('/users/profile/@admin1337');
        $response->assertSessionHas('danger');
        $response->assertStatus(302);
        $response->assertRedirect('/');
    }

    /**
     * testShowSettingsForm method
     *
     * @return void
     */
    public function testShowSettingsForm()
    {
        $user = User::find(1);
        $this->be($user);

        $response = $this->get('/users/settings');
        $response->assertSuccessful();
    }

    /**
     * testUpdateInvalidType method
     *
     * @return void
     */
    public function testUpdateInvalidType()
    {
        $user = User::find(1);
        $this->be($user);

        $response = $this->put('/users/settings', ['type' => 'unknown']);
        $response->assertSessionHas('danger');
        $response->assertStatus(302);
    }

    /**
     * testUpdateEmailSuccess method
     *
     * @return void
     */
    public function testUpdateEmailSuccess()
    {
        $user = User::find(1);
        $this->be($user);
        $this->assertSame('admin@xetaravel.io', $user->email);

        $response = $this->put('/users/settings', ['type' => 'email', 'email' => 'newadmin@xetaravel.io']);
        $response->assertSessionHas('success');
        $response->assertStatus(302);
        $response->assertRedirect('/users/settings');

        $user = User::find(1);
        $this->assertSame('newadmin@xetaravel.io', $user->email);
    }

    /**
     * testUpdateEmailAlreadyTakenFailed method
     *
     * @return void
     */
    public function testUpdateEmailAlreadyTakenFailed()
    {
        $user = User::find(1);
        $this->be($user);

        $response = $this->put('/users/settings', ['type' => 'email', 'email' => 'admin@xetaravel.io']);
        $response->assertSessionHasErrors(['email']);
        $response->assertStatus(302);
    }

    /**
     * testUpdatePasswordSuccess method
     *
     * @return void
     */
    public function testUpdatePasswordSuccess()
    {
        $user = User::find(1);
        $this->be($user);
        $this->assertTrue(Hash::check('admin', $user->password));

        $response = $this->put('/users/settings', [
            'type' => 'password',
            'oldpassword' => 'admin',
            'password' => 'adminmodified',
            'password_confirmation' => 'adminmodified'
        ]);
        $response->assertSessionHas('success');
        $response->assertStatus(302);
        $response->assertRedirect('/users/settings');

        $user = User::find(1);
        $this->assertTrue(Hash::check('adminmodified', $user->password));
    }

    /**
     * testUpdatePasswordNotMatchOldPasswordFailed method
     *
     * @return void
     */
    public function testUpdatePasswordNotMatchOldPasswordFailed()
    {
        $user = User::find(1);
        $this->be($user);

        $response = $this->put('/users/settings', [
            'type' => 'password',
            'oldpassword' => 'NOT MATCH',
            'password' => 'adminmodified',
            'password_confirmation' => 'adminmodified'
        ]);
        $response->assertSessionHas('danger');
        $response->assertStatus(302);
        $response->assertRedirect('/users/settings');
    }

    /**
     * testUpdatePasswordNotMatchFailed method
     *
     * @return void
     */
    public function testUpdatePasswordNotMatchFailed()
    {
        $user = User::find(1);
        $this->be($user);

        $response = $this->put('/users/settings', [
            'type' => 'password',
            'oldpassword' => 'admin',
            'password' => 'NOT MATCH',
            'password_confirmation' => 'adminmodified'
        ]);
        $response->assertSessionHasErrors(['password']);
        $response->assertStatus(302);
    }

    /**
     * testDeleteSuccess method
     *
     * @return void
     */
    public function testDeleteSuccess()
    {
        $user = User::find(1);
        $this->be($user);

        $response = $this->delete('/users/delete', ['password' => 'admin']);
        $response->assertSessionHas('success');
        $response->assertStatus(302);
        $response->assertRedirect('/');

        $response = $this->get('/users/profile/@admin');
        $response->assertSessionHas('danger'); // That mean the user does not exist or has been deleted.
        $response->assertStatus(302);

        $response = $this->get('/discuss/conversation/this-is-an-announcement.1');
        $response->assertSee('Deleted'); // Deleted Users must be displayed with Deleted username.
    }

    /**
     * testDeleteWrongPasswordFailed method
     *
     * @return void
     */
    public function testDeleteWrongPasswordFailed()
    {
        $user = User::find(1);
        $this->be($user);

        $response = $this->delete('/users/delete', ['password' => 'WRONG PASSWORD']);
        $response->assertSessionHas('danger');
        $response->assertStatus(302);
    }
}


text:
<?php

namespace	cs;
Event::instance()->on(
	'System/User/construct/after',
	function () {
		switch (Config::instance()->components['modules']['HybridAuth']['active']) {
			case 1:
				require __DIR__.'/events/enabled.php';
				require_once __DIR__.'/events/enabled/functions.php';
		}
	}
);
Event::instance()->on(
	'System/Index/construct',
	function () {
		if (!admin_path()) {
			return;
		}
		switch (Config::instance()->components['modules']['HybridAuth']['active']) {
			case -1:
				require __DIR__.'/events/uninstalled.php';
			break;
		}
	}
);


text:
namespace device {

extern const char kDeviceServiceName[];

}  // namespace device

#endif  // SERVICES_DEVICE_PUBLIC_CPP_CONSTANTS_H_


text:
CREATE SEQUENCE IF NOT EXISTS credentials_id_seq START WITH 1 INCREMENT BY 1;
CREATE SEQUENCE IF NOT EXISTS account_id_seq START WITH 1 INCREMENT BY 1;
CREATE SEQUENCE IF NOT EXISTS usuario_id_seq START WITH 1 INCREMENT BY 1;
CREATE SEQUENCE IF NOT EXISTS app_user_id_seq START WITH 1 INCREMENT BY 1;
CREATE SEQUENCE IF NOT EXISTS imagen_id_seq START WITH 1 INCREMENT BY 1;
/*==============================================================*/
/*Table: data_store_type                                        */
/*==============================================================*/
create table data_store_type(
   id                 INT,
   name               VARCHAR(10),
   description        VARCHAR(50)
);
/*==============================================================*/
/*Table: data_store                                             */
/*==============================================================*/
create table data_store(
   id                 SERIAL DEFAULT nextval('credentials_id_seq'),
   data_store_type_id INT,
   url                VARCHAR(100) null,
   driver_class       VARCHAR(50)  null,
   username           VARCHAR(20)  null,
   password           VARCHAR(20)  null,
   table_types        VARCHAR(20)  null,
   constraint pk_data_store primary key (id),
   constraint fk_data_store_type foreign key (data_store_type_id) references data_store_type (id)
);
/*==============================================================*/
/*Table: account                                                */
/*==============================================================*/
create table account(
   username       VARCHAR(100) null,
   password       VARCHAR(100) null
);
/*==============================================================*/
/*Table: perfil                                                 */
/*==============================================================*/
CREATE TABLE IF NOT EXISTS perfil (
  id INT NOT NULL COMMENT 'id de la tabla perfil',
  codigo_perfil VARCHAR(40) NOT NULL,
  descripcion_perfil VARCHAR(200) NOT NULL,
  habilitado TINYINT(1) NOT NULL DEFAULT 1,
  constraint pk_perfil primary key (id)
);
/*==============================================================*/
/*Table: usuario                                                */
/*==============================================================*/
CREATE TABLE IF NOT EXISTS usuario (
  id    				NUMBER(20,7) DEFAULT nextval('usuario_id_seq'),
  username 				VARCHAR(50) NOT NULL,
  password 				VARCHAR(128) NOT NULL,
  correo 				VARCHAR(254) NOT NULL,
  fecha_creacion 		TIMESTAMP NOT NULL,
  cuenta_no_expirada 	BIT NOT NULL DEFAULT true,
  cuenta_no_bloqueada 	BIT NOT NULL DEFAULT true,
  credencial_no_expirada BIT NOT NULL DEFAULT true,
  habilitado 			BIT NOT NULL DEFAULT true,
  contador_intentos_fallidos INT(11) NOT NULL DEFAULT true,
  pregunta_secreta 		VARCHAR(200) NOT NULL,
  respuesta_secreta 	VARCHAR(200) NOT NULL,
  id_de_seguridad 		VARCHAR(50) NULL DEFAULT NULL,
  instante_de_bloqueo 	TIME NULL DEFAULT NULL,
  ventana_para_id_seguridad DATE NULL DEFAULT NULL,
  fecha_ultimo_acceso 	TIMESTAMP NULL DEFAULT NULL,
  fecha_ultimo_cambio_clave TIMESTAMP NULL DEFAULT NULL,
  constraint pk_usuario primary key (id)
);
CREATE INDEX IDXCORREO ON usuario(correo);

/*==============================================================*/
/*Table: usuario_detalle                                        */
/*==============================================================*/
CREATE TABLE IF NOT EXISTS usuario_detalle (
  usuario_id 			NUMBER NOT NULL,
  nombres 				VARCHAR(100) NOT NULL,
  primer_apellido  		VARCHAR(80) NOT NULL,
  segundo_apellido 		VARCHAR(80) NULL,
  telefono 				VARCHAR(22) NULL,
  direccion 			VARCHAR(350) NULL,
  constraint fk_usuario foreign key (usuario_id) references usuario (id)
 );

 CREATE TABLE IF NOT EXISTS imagen (
  imagen_id             SERIAL NOT NULL,
  nombre                VARCHAR(150) NOT NULL,
  mime_type             VARCHAR(20) NOT NULL,
  contenido             longblob NOT NULL,
  blob                  blob NOT NULL,
  clob                  clob NOT NULL,
  sha256sum             VARCHAR(64) NOT NULL,
  constraint pk_imagen primary key (imagen_id)
);
/*==============================================================*/
/*Table: usuario_perfil                                         */
/*==============================================================*/
 CREATE TABLE IF NOT EXISTS usuario_perfil (
  usuario_id 			INT NOT NULL,
  perfil_id 			INT NOT NULL,
  constraint pk_usuario_perfil primary key (usuario_id, perfil_id),
  constraint fk_usuario_id foreign key (usuario_id) references usuario (id),
  constraint fk_perfil_id foreign key (perfil_id) references perfil (id)
);
/*==============================================================*/
/*Table: tipo_bitacora                                          */
/*==============================================================*/
CREATE TABLE IF NOT EXISTS tipo_bitacora (
  id                 	INT,
  codigo 				VARCHAR(30) NOT NULL,
  descripcion 			VARCHAR(150) NULL,
  constraint pk_tipo_bitacora primary key (id)
);

/*==============================================================*/
/*Table: bitacora                                         		*/
/*==============================================================*/
CREATE TABLE IF NOT EXISTS bitacora (
  id                 	SERIAL DEFAULT nextval('bitacora_id_seq'),
  tipo_bitacora_id  	INT NOT NULL,
  ip 					VARCHAR(45) NOT NULL,
  fecha		 			TIMESTAMP NOT NULL,
  username 				VARCHAR(25) NULL DEFAULT NULL,
  detalle	 			VARCHAR(1500) NULL DEFAULT NULL,
  constraint pk_bitacora primary key (id),
  constraint fk_tipo_bitacora_id foreign key (tipo_bitacora_id) references tipo_bitacora (id)
);
/*==============================================================*/
/*Table: app_user                                         		*/
/*==============================================================*/
CREATE TABLE IF NOT EXISTS app_user (
  id                 	SERIAL DEFAULT nextval('app_user_id_seq'),
  password 				VARCHAR(60) NOT NULL,
  username 				VARCHAR(45) NOT NULL,
  constraint pk_bitacora primary key (id)
);
/*==============================================================*/
/*Table: user_role                                         		*/
/*==============================================================*/
CREATE TABLE IF NOT EXISTS user_role (
  role  				VARCHAR(45) NOT NULL,
  app_user_id 			int,
  constraint fk_app_id foreign key (app_user_id) references app_user (id)
);


text:
#include "QmitkIGTPlayerWidget.h"

//mitk headers
#include "mitkTrackingTypes.h"
#include <mitkSurface.h>
#include <mitkNavigationToolReader.h>
#include <mitkNavigationToolWriter.h>
#include <mitkNavigationToolStorage.h>
#include <mitkNavigationToolStorageDeserializer.h>
#include <mitkNavigationToolStorageSerializer.h>
#include <mitkIGTException.h>
#include <mitkIOUtil.h>
#include <QmitkIGTCommonHelper.h>

//qt headers
#include <qfiledialog.h>
#include <qmessagebox.h>
#include <qtimer.h>

QmitkIGTPlayerWidget::QmitkIGTPlayerWidget(QWidget* parent, Qt::WindowFlags f)
  : QWidget(parent, f),
  m_RealTimePlayer(mitk::NavigationDataPlayer::New()),
  m_SequentialPlayer(mitk::NavigationDataSequentialPlayer::New()),
  m_StartTime(-1.0),
  m_CurrentSequentialPointNumber(0),
  m_Controls(new Ui::QmitkIGTPlayerWidgetControls)
{
  m_Controls->setupUi(this);
  m_PlayingTimer = new QTimer(this); // initialize update timer

  CreateConnections();

  m_Controls->samplePositionHorizontalSlider->setVisible(false);

  this->ResetLCDNumbers(); // reset lcd numbers at start
}

QmitkIGTPlayerWidget::~QmitkIGTPlayerWidget()
{
  m_PlayingTimer->stop();

  delete m_Controls;
}

void QmitkIGTPlayerWidget::CreateConnections()
{
  connect( (QObject*)(m_Controls->playPushButton), SIGNAL(clicked(bool)), this, SLOT(OnPlayButtonClicked(bool)) ); // play button
  connect( (QObject*)(m_PlayingTimer), SIGNAL(timeout()), this, SLOT(OnPlaying()) ); // update timer
  connect( (QObject*) (m_Controls->beginPushButton), SIGNAL(clicked()), this, SLOT(OnGoToBegin()) ); // reset player and go to begin
  connect( (QObject*) (m_Controls->stopPushButton), SIGNAL(clicked()), this, SLOT(OnGoToEnd()) ); // reset player
  // pass this widgets protected combobox signal to public signal
  connect( (QObject*) (m_Controls->trajectorySelectComboBox), SIGNAL(currentIndexChanged(int)), this, SIGNAL(SignalCurrentTrajectoryChanged(int)) );
  // pass this widgets protected checkbox signal to public signal
  connect( m_Controls->splineModeCheckBox, SIGNAL(toggled(bool)), this, SIGNAL(SignalSplineModeToggled(bool)) );
  //connect( m_Controls->sequencialModeCheckBox, SIGNAL(toggled(bool)), this, SLOT(OnSequencialModeToggled(bool)) );

  connect( m_Controls->samplePositionHorizontalSlider, SIGNAL(sliderPressed()), this, SLOT(OnSliderPressed()) );
  connect( m_Controls->samplePositionHorizontalSlider, SIGNAL(sliderReleased()), this, SLOT(OnSliderReleased()) );

  connect( m_Controls->m_OpenFileButton, SIGNAL(clicked()), this, SLOT(OnOpenFileButtonPressed()) );
}

bool QmitkIGTPlayerWidget::IsTrajectoryInSplineMode()
{
  return m_Controls->splineModeCheckBox->isChecked();
}

bool QmitkIGTPlayerWidget::CheckInputFileValid()
{
  QFile file(m_CmpFilename);

  // check if file exists
  if(!file.exists())
  {
    QMessageBox::warning(nullptr, "IGTPlayer: Error", "No valid input file was loaded. Please load input file first!");
    return false;
  }

  return true;
}

unsigned int QmitkIGTPlayerWidget::GetNumberOfTools()
{
  unsigned int result = 0;

  if(this->GetCurrentPlaybackMode() == RealTimeMode)
  {
    if(m_RealTimePlayer.IsNotNull())
      result = m_RealTimePlayer->GetNumberOfOutputs();
  }

  else if(this->GetCurrentPlaybackMode() == SequentialMode)
  {
    if(m_SequentialPlayer.IsNotNull())
      result = m_SequentialPlayer->GetNumberOfOutputs();
  }

  // at the moment this works only if player is initialized
  return result;
}

void QmitkIGTPlayerWidget::SetUpdateRate(unsigned int msecs)
{
  m_PlayingTimer->setInterval((int) msecs); // set update timer update rate
}

void QmitkIGTPlayerWidget::OnPlayButtonClicked(bool checked)
{
  if ( ! checked )
  {
    if ( this->GetCurrentPlaybackMode() == RealTimeMode )
    {
      m_RealTimePlayer->StopPlaying();
    }
    else if ( this->GetCurrentPlaybackMode() == SequentialMode )
    {
      //      m_SequentialPlayer->
    }
  }

  if(CheckInputFileValid())  // no playing possible without valid input file
  {
    switch ( this->GetCurrentPlaybackMode() )
    {
    case RealTimeMode:
      {
        break;
      }
    case SequentialMode:
      {
        break;
      }
    }

    PlaybackMode currentMode = this->GetCurrentPlaybackMode();
    bool isRealTimeMode = currentMode == RealTimeMode;
    bool isSequentialMode = currentMode == SequentialMode;

    if(checked) // play
    {
      if( (isRealTimeMode && m_RealTimePlayer.IsNull()) || (isSequentialMode && m_SequentialPlayer.IsNull()))  // start play
      {
        mitk::NavigationDataSet::Pointer navigationDataSet;
        try
        {
          navigationDataSet = dynamic_cast<mitk::NavigationDataSet*> (mitk::IOUtil::Load(m_CmpFilename.toStdString())[0].GetPointer());
        }
        catch(const mitk::IGTException&)
        {
          std::string errormessage = "Error during start playing. Invalid or wrong file?";
          QMessageBox::warning(nullptr, "IGTPlayer: Error", errormessage.c_str());
          m_Controls->playPushButton->setChecked(false);
          m_RealTimePlayer = nullptr;
          return;
        }

        if(isRealTimeMode)
        {
          m_RealTimePlayer = mitk::NavigationDataPlayer::New();
          m_RealTimePlayer->SetNavigationDataSet(navigationDataSet);
          try
          {
            m_RealTimePlayer->StartPlaying();
          }
          catch(const mitk::IGTException&)
          {
            std::string errormessage = "Error during start playing. Invalid or wrong file?";
            QMessageBox::warning(nullptr, "IGTPlayer: Error", errormessage.c_str());
            m_Controls->playPushButton->setChecked(false);
            m_RealTimePlayer = nullptr;
            return;
          }
        }
        else if(isSequentialMode)
        {
          m_SequentialPlayer = mitk::NavigationDataSequentialPlayer::New();
          try
          {
            m_SequentialPlayer->SetNavigationDataSet(navigationDataSet);
          }
          catch(const mitk::IGTException&)
          {
            std::string errormessage = "Error during start playing. Invalid or wrong file type?";
            QMessageBox::warning(nullptr, "IGTPlayer: Error", errormessage.c_str());
            m_Controls->playPushButton->setChecked(false);
            m_RealTimePlayer = nullptr;
            return;
          }

          m_Controls->samplePositionHorizontalSlider->setMinimum(0);

          m_Controls->samplePositionHorizontalSlider->setMaximum(m_SequentialPlayer->GetNumberOfSnapshots());

          m_Controls->samplePositionHorizontalSlider->setEnabled(true);
        }

        m_PlayingTimer->start(100);

        emit SignalPlayingStarted();
      }
      else // resume play
      {
        if(isRealTimeMode)
          m_RealTimePlayer->Resume();

        m_PlayingTimer->start(100);
        emit SignalPlayingResumed();
      }
    }

    else // pause
    {
      if(isRealTimeMode)
        m_RealTimePlayer->Pause();

      m_PlayingTimer->stop();
      emit SignalPlayingPaused();
    }
  }

  else
  {
    m_Controls->playPushButton->setChecked(false); // uncheck play button if file unvalid
  }
}

QmitkIGTPlayerWidget::PlaybackMode QmitkIGTPlayerWidget::GetCurrentPlaybackMode()
{
  /*if(m_Controls->sequencialModeCheckBox->isChecked())
  return SequentialMode;
  else*/
  return RealTimeMode;
}

QTimer*  QmitkIGTPlayerWidget::GetPlayingTimer()
{
  return m_PlayingTimer;
}

void QmitkIGTPlayerWidget::OnStopPlaying()
{
  this->StopPlaying();
}

void QmitkIGTPlayerWidget::StopPlaying()
{
  m_PlayingTimer->stop();
  emit SignalPlayingStopped();

  if(m_RealTimePlayer.IsNotNull())
    m_RealTimePlayer->StopPlaying();

  m_StartTime = -1;  // set starttime back
  m_CurrentSequentialPointNumber = 0;
  m_Controls->samplePositionHorizontalSlider->setSliderPosition(m_CurrentSequentialPointNumber);
  m_Controls->sampleLCDNumber->display(static_cast<int>(m_CurrentSequentialPointNumber));

  this->ResetLCDNumbers();
  m_Controls->playPushButton->setChecked(false); // set play button unchecked
}

void QmitkIGTPlayerWidget::OnPlaying()
{
  switch ( this->GetCurrentPlaybackMode() )
  {
  case RealTimeMode:
    {
      if ( m_RealTimePlayer.IsNull() ) { return; }

      if ( m_StartTime < 0 )
      {
        // get playback start time
        m_StartTime = m_RealTimePlayer->GetOutput()->GetTimeStamp();
      }

      if( ! m_RealTimePlayer->IsAtEnd() )
      {
        m_RealTimePlayer->Update(); // update player

        int msc = (int) (m_RealTimePlayer->GetOutput()->GetTimeStamp() - m_StartTime);

        // calculation for playing time display
        int ms = msc % 1000;
        msc = (msc - ms) / 1000;
        int s = msc % 60;
        int min = (msc-s) / 60;

        // set lcd numbers
        m_Controls->msecLCDNumber->display(ms);
        m_Controls->secLCDNumber->display(s);
        m_Controls->minLCDNumber->display(min);

        emit SignalPlayerUpdated(); // player successfully updated
      }
      else
      {
        this->StopPlaying(); // if player is at EOF
      }

      break;
    }
  case SequentialMode:
    {
      if ( m_SequentialPlayer.IsNull() ) { return; }

      if ( m_CurrentSequentialPointNumber < m_SequentialPlayer->GetNumberOfSnapshots() )
      {
        m_SequentialPlayer->Update(); // update sequential player

        m_Controls->samplePositionHorizontalSlider->setSliderPosition(m_CurrentSequentialPointNumber++); // refresh slider position
        m_Controls->sampleLCDNumber->display(static_cast<int>(m_CurrentSequentialPointNumber));

        //for debugging purposes
        //std::cout << "Sample: " << m_CurrentSequentialPointNumber << " X: " << m_SequentialPlayer->GetOutput()->GetPosition()[0] << " Y: " << m_SequentialPlayer->GetOutput()->GetPosition()[1] << " Y: " << m_SequentialPlayer->GetOutput()->GetPosition()[2] << std::endl;

        emit SignalPlayerUpdated(); // player successfully updated
      }
      else
      {
        this->StopPlaying(); // if player is at EOF
      }

      break;
    }
  }
}

const std::vector<mitk::NavigationData::Pointer> QmitkIGTPlayerWidget::GetNavigationDatas()
{
  std::vector<mitk::NavigationData::Pointer> navDatas;

  if(this->GetCurrentPlaybackMode() == RealTimeMode && m_RealTimePlayer.IsNotNull())
  {
    for(unsigned int i=0; i < m_RealTimePlayer->GetNumberOfOutputs(); ++i)
    {
      navDatas.push_back(m_RealTimePlayer->GetOutput(i)); // push back current navigation data for each tool
    }
  }

  else if(this->GetCurrentPlaybackMode() == SequentialMode && m_SequentialPlayer.IsNotNull())
  {
    for(unsigned int i=0; i < m_SequentialPlayer->GetNumberOfOutputs(); ++i)
    {
      navDatas.push_back(m_SequentialPlayer->GetOutput(i)); // push back current navigation data for each tool
    }
  }

  return navDatas;
}

const mitk::PointSet::Pointer QmitkIGTPlayerWidget::GetNavigationDatasPointSet()
{
  mitk::PointSet::Pointer result = mitk::PointSet::New();

  mitk::PointSet::PointType pointType;

  PlaybackMode currentMode = this->GetCurrentPlaybackMode();
  bool isRealTimeMode = currentMode == RealTimeMode;
  bool isSequentialMode = currentMode == SequentialMode;

  if( (isRealTimeMode && m_RealTimePlayer.IsNotNull()) || (isSequentialMode && m_SequentialPlayer.IsNotNull()))
  {
    for(unsigned int i=0; i < m_RealTimePlayer->GetNumberOfOutputs(); ++i)
    {
      mitk::NavigationData::PositionType position;

      if(isRealTimeMode)
        position = m_RealTimePlayer->GetOutput(i)->GetPosition();
      else if(isSequentialMode)
        position = m_SequentialPlayer->GetOutput(i)->GetPosition();

      pointType[0] = position[0];
      pointType[1] = position[1];
      pointType[2] = position[2];

      result->InsertPoint(i,pointType);  // insert current ND as Pointtype in PointSet for return
    }
  }

  return result;
}

const mitk::PointSet::PointType QmitkIGTPlayerWidget::GetNavigationDataPoint(unsigned int index)
{
  if( index > this->GetNumberOfTools() )
    throw std::out_of_range("Tool Index out of range!");

  PlaybackMode currentMode = this->GetCurrentPlaybackMode();
  bool isRealTimeMode = currentMode == RealTimeMode;
  bool isSequentialMode = currentMode == SequentialMode;

  // create return PointType from current ND for tool index
  mitk::PointSet::PointType result;

  if( (isRealTimeMode && m_RealTimePlayer.IsNotNull()) || (isSequentialMode && m_SequentialPlayer.IsNotNull()))
  {
    mitk::NavigationData::PositionType position;

    if(isRealTimeMode)
      position = m_RealTimePlayer->GetOutput(index)->GetPosition();
    else if(isSequentialMode)
      position = m_SequentialPlayer->GetOutput(index)->GetPosition();

    result[0] = position[0];
    result[1] = position[1];
    result[2] = position[2];
  }

  return result;
}

/*void QmitkIGTPlayerWidget::SetRealTimePlayer( mitk::NavigationDataPlayer::Pointer player )
{
if(player.IsNotNull())
m_RealTimePlayer = player;
}

void QmitkIGTPlayerWidget::SetSequentialPlayer( mitk::NavigationDataSequentialPlayer::Pointer player )
{
if(player.IsNotNull())
m_SequentialPlayer = player;
}*/

void QmitkIGTPlayerWidget::OnOpenFileButtonPressed()
{
  QString filename = QFileDialog::getOpenFileName(this, "Load tracking data", QmitkIGTCommonHelper::GetLastFileLoadPath(),"XML files (*.xml)");
  QFile file(filename);

  QmitkIGTCommonHelper::SetLastFileLoadPathByFileName(filename);
  // if something went wrong or user pressed cancel in the save dialog
  if ( filename.isEmpty()  || ! file.exists() )
  {
    QMessageBox::warning(nullptr, "Warning", QString("Please enter valid path. Using previous path again."));
    return;
  }

  m_CmpFilename = filename;

  this->OnGoToEnd(); /// stops playing and resets lcd numbers

  m_Controls->m_ActiveFileLabel->setText(m_CmpFilename);

  emit SignalInputFileChanged();

  mitk::NavigationDataSet::Pointer navigationDataSet = dynamic_cast<mitk::NavigationDataSet*> (mitk::IOUtil::Load(m_CmpFilename.toStdString())[0].GetPointer());
  m_RealTimePlayer->SetNavigationDataSet(navigationDataSet);
  m_SequentialPlayer->SetNavigationDataSet(navigationDataSet);

  m_Controls->m_PlayerControlsGroupBox->setEnabled(true);
}

void QmitkIGTPlayerWidget::OnGoToEnd()
{
  this->StopPlaying();

  // reset lcd numbers
  this->ResetLCDNumbers();
}

void QmitkIGTPlayerWidget::OnGoToBegin()
{
  // stop player manual so no PlayingStopped()
  m_PlayingTimer->stop();

  if(this->GetCurrentPlaybackMode() == RealTimeMode && m_RealTimePlayer.IsNotNull())
  {
    m_RealTimePlayer->StopPlaying();
    m_RealTimePlayer = nullptr;  // set player to nullptr so it can be initialized again if playback is called afterwards
  }

  m_StartTime = -1;  // set starttime back

  //reset view elements
  m_Controls->playPushButton->setChecked(false);
  this->ResetLCDNumbers();
}

void QmitkIGTPlayerWidget::ResetLCDNumbers()
{
  m_Controls->minLCDNumber->display(QString("00"));
  m_Controls->secLCDNumber->display(QString("00"));
  m_Controls->msecLCDNumber->display(QString("000"));
}

void QmitkIGTPlayerWidget::SetTrajectoryNames(const QStringList toolNames)
{
  QComboBox* cBox = m_Controls->trajectorySelectComboBox;

  if(cBox->count() > 0)
    this->ClearTrajectorySelectCombobox();

  // before making changed to QComboBox it is recommended to disconnet it's SIGNALS and SLOTS
  disconnect( (QObject*) (m_Controls->trajectorySelectComboBox), SIGNAL(currentIndexChanged(int)), this, SIGNAL(SignalCurrentTrajectoryChanged(int)) );

  if(!toolNames.isEmpty())
    m_Controls->trajectorySelectComboBox->insertItems(0, toolNames); // adding current tool names to combobox

  // reconnect after performed changes
  connect( (QObject*) (m_Controls->trajectorySelectComboBox), SIGNAL(currentIndexChanged(int)), this, SIGNAL(SignalCurrentTrajectoryChanged(int)) );
}

int QmitkIGTPlayerWidget::GetResolution()
{
  return m_Controls->resolutionSpinBox->value();  // return currently selected trajectory resolution
}

void QmitkIGTPlayerWidget::ClearTrajectorySelectCombobox()
{
  // before making changed to QComboBox it is recommended to disconnet it's SIGNALS and SLOTS
  disconnect( (QObject*) (m_Controls->trajectorySelectComboBox), SIGNAL(currentIndexChanged(int)), this, SIGNAL(SignalCurrentTrajectoryChanged(int)) );

  m_Controls->trajectorySelectComboBox->clear();

  // reconnect after performed changes
  connect( (QObject*) (m_Controls->trajectorySelectComboBox), SIGNAL(currentIndexChanged(int)), this, SIGNAL(SignalCurrentTrajectoryChanged(int)) );
}

void QmitkIGTPlayerWidget::OnSequencialModeToggled(bool toggled)
{
  this->StopPlaying(); // stop playing when mode is changed

  if(toggled)
  {
    m_Controls->samplePositionHorizontalSlider->setEnabled(true); // enable slider if sequential mode
  }
  else if(!toggled)
  {
    m_Controls->samplePositionHorizontalSlider->setSliderPosition(0); // set back and disable slider
    m_Controls->samplePositionHorizontalSlider->setDisabled(true);
  }
}

void QmitkIGTPlayerWidget::OnSliderReleased()
{
  int currentSliderValue = m_Controls->samplePositionHorizontalSlider->value(); // current slider value selected through user movement

  if(currentSliderValue > static_cast<int>(m_CurrentSequentialPointNumber)) // at the moment only forward scrolling is possible
  {
    auto snapshotNumber = static_cast<unsigned int>(currentSliderValue);
    m_SequentialPlayer->GoToSnapshot(snapshotNumber); // move player to selected snapshot
    m_CurrentSequentialPointNumber = currentSliderValue;
    m_Controls->sampleLCDNumber->display(currentSliderValue); // update lcdnumber in widget
  }
  else
    m_Controls->samplePositionHorizontalSlider->setValue(m_CurrentSequentialPointNumber);
}

void QmitkIGTPlayerWidget::OnSliderPressed()
{
  if(m_Controls->playPushButton->isChecked())  // check if widget is playing
    m_Controls->playPushButton->click(); // perform click to pause the play
}


text:
#ifndef Magnum_SceneGraph_Camera3D_h
#define Magnum_SceneGraph_Camera3D_h

/** @file
 * @deprecated Use @ref Magnum/SceneGraph/Camera.h instead.
 */

#include "Magnum/configure.h"

#ifdef MAGNUM_BUILD_DEPRECATED
#include "Magnum/SceneGraph/Camera.h"
CORRADE_DEPRECATED_FILE("use Magnum/SceneGraph/Camera.h instead")
#else
#error use Magnum/SceneGraph/Camera.h instead
#endif

#endif


text:
var util = {}

util.getFilename = function (path) {
  var split = path.split('/')
  return split[split.length - 1]
}

util.getExtension = function (path) {
  path = util.getFilename(path)
  var split = path.split('.')
  return split[split.length - 1]
}

var CM_MAPPINGS = {
  'js': 'javascript',
  'coffee': 'javascript',
  'ts': 'javascript',
  'json': 'javascript',
  'css': 'css',
  'sass': 'css',
  'less': 'css',
  'html': 'htmlmixed',
  'xml': 'xml',
  'php': 'application/x-httpd-php'
}
util.pathToMode = function (path) {
  return {
    name: CM_MAPPINGS[util.getExtension(path)],
    globalVars: true
  }
}

var VIEW_MAPPINGS = {
  'png': 'image',
  'jpg': 'image',
  'jpeg': 'image',
  'jpeg2000': 'image',
  'tif': 'image',
  'tiff': 'image',
  'gif': 'image',
  'bmp': 'image',
  'ico': 'image'
}
util.getViewMapping = function (path) {
  return VIEW_MAPPINGS[util.getExtension(path)] || 'text'
}
util.getLoadMode = function (path) {
  switch (util.getViewMapping(path)) {
    case 'image':
      return 'base64'
    default:
      return 'string'
  }
}

// Creates a zip archive from a file tree
util.zipTree = function (zip, nodeList) {
  console.log(nodeList)
  for (var i = 0; i < nodeList.length; i++) {
 // Iterate children

    if (nodeList[i].isDir) {
      util.zipTree(zip, nodeList[i].nodes)
    } else {
      zip.file(nodeList[i].path.slice(1), nodeList[i].content)
    }
  }
}

util.getParameterByName = function (name) {
  var url = window.location.href
  name = name.replace(/[[\]]/g, '\\$&')
  var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)')
  var results = regex.exec(url)
  if (!results) return null
  if (!results[2]) return ''
  return decodeURIComponent(results[2].replace(/\+/g, ' '))
}

module.exports = util


text:
{% extends "base.html" %}
{% block title %}Settings{% endblock title %}

{% block content %}

Settings

                    Feeds

                        {% for feed in nav_feeds %}

{{ feed.title }}

                                Delete
                                Edit

                        {% endfor %}

                    <form method="POST" action="{{ url_for('add_entity') }}">

                            <input type="hidden" name="entity" value="feed">

Add Feed

                        {% if nav_categories %}

                            Categories

                            {% for c in nav_categories %}

                                <input type="checkbox" name="category" value="{{ c.id }}">{{ c.title }}

                            {% endfor %}

                        {% endif %}

                            Feed Address

                                <input type="url" class="form-control" name="url" id="feed-input" placeholder="http://">

                                    <input class="btn btn-default" type="submit" value="Add">

                    </form>

                    Categories

                        {% for category in nav_categories %}

{{ category.title }}

                                Delete
                                Edit

                        {% endfor %}

                    <form method="POST" action="{{ url_for('add_entity') }}">

                            <input type="hidden" name="entity" value="category">

Add Category

                        {% if nav_feeds %}

                            Feeds

                            {% for f in nav_feeds %}

                                <input type="checkbox" name="feed" value="{{ f.id }}">{{ f.title }}

                            {% endfor %}

                        {% endif %}

                            Category Name

                                <input type="text" class="form-control" name="category" id="category-input">

                                    <input class="btn btn-default" type="submit" value="Add">

                    </form>

                    Bulk Actions

Import Feed List

                        <form method="POST" action="{{ url_for('opml') }}" enctype="multipart/form-data" class="pull-right">
                            <input type="hidden" name="action" value="import">

                                    Browse<input type="file" name="file">

                                <input type="submit" value="Upload" class="btn btn-default">

                        </form>

Export Feed List

                        <form method="POST" action="{{ url_for('opml') }}" enctype="multipart/form-data" class="pull-right">
                            <input type="hidden" name="action" value="export">
                            <input type="submit" value="Download" class="btn btn-default pull-right">
                        </form>

Delete All

                            Feeds
                            Categories
                            Both

Remove Articles Older Than

                        <form method="POST" action=" {{ url_for('del_all') }}">

                                <input type="number" class="form-control" name="prune" placeholder="days">

                                    <input class="btn btn-default" type="submit" value="Delete">

                        </form>

                    User

                            <form method="POST" action="{{ url_for('edit_user') }}">

                                    Username

                                    <input type="text" class="form-control" name="username" id="username-input" value="{{ user.username }}">

                                        <input class="btn btn-default" type="submit" value="Change">

                            </form>

                            <form method="POST" action="{{ url_for('edit_user') }}">

                                    Password

                                    <input type="password" class="form-control" name="password" id="password-input" placeholder="******">

                                        <input class="btn btn-default" type="submit" value="Change">

                            </form>

                            <form method="POST" action="{{ url_for('edit_user') }}">

                                    Page Length

                                    <input type="text" class="form-control" name="page_length" id="page_length-input" value="{{ user.page_length }}">

                                        <input class="btn btn-default" type="submit" value="Change">

                            </form>

                            <form method="POST" action="{{ url_for('edit_user') }}">

                                    <input type="hidden" name="delete" value="delete">

Delete all user information. You will be logged out.

                                    <input class="btn btn-default pull-right" type="submit" value="Delete">

                            </form>

{% endblock content %}