    {-# LANGUAGE ViewPatterns, TupleSections, ScopedTypeVariables, DeriveDataTypeable, PatternGuards, GADTs #-}

    module Output.Tags(writeTags, completionTags, applyTags) where

    import Data.Bifunctor
    import Data.Function
    import Data.List.Extra
    import Data.Tuple.Extra
    import Data.Maybe
    import Foreign.Storable.Tuple()
    import qualified Data.Map as Map
    import qualified Data.Set as Set
    import qualified Data.Vector.Storable as V
    import qualified Data.ByteString.Char8 as BS

    import Input.Item
    import Query
    import General.Util
    import General.Store
    import General.Str

    ---------------------------------------------------------------------
    -- DATA TYPE

    -- matches (a,b) if i >= a && i <= b

    data Packages a where Packages :: Packages (BStr0, V.Vector (TargetId, TargetId)) deriving Typeable
        -- list of packages, sorted by popularity, lowercase, interspersed with \0
        -- for each index in PackageNames, the first is the module item, any in the bounds are in that package

    data Modules a where Modules :: Modules (BStr0, V.Vector (TargetId, TargetId)) deriving Typeable
        -- list of modules, sorted by popularity, not unique, lowercase, interspersed with \0
        -- for each index in ModuleNames, the first is the module item, any in the bounds are in that module

    data Categories a where Categories :: Categories (BStr0, Jagged (TargetId, TargetId)) deriving Typeable
        -- list of categories, sorted by name, interspersed with \0
        -- for each index in CategoryNames, a range of items containing a category, first item is a package

    data Completions a where Completions :: Completions BStr0 deriving Typeable
        -- a list of things to complete to, interspersed with \0

    writeTags :: StoreWrite -> (PkgName -> Bool) -> (PkgName -> [(String,String)]) -> [(Maybe TargetId, Item)] -> IO ()
    writeTags :: StoreWrite
    -> (PkgName -> Bool)
    -> (PkgName -> [(String, String)])
    -> [(Maybe TargetId, Item)]
    -> IO ()
    writeTags store :: StoreWrite
    store keep :: PkgName -> Bool
    keep extra :: PkgName -> [(String, String)]
    extra xs :: [(Maybe TargetId, Item)]
    xs = do
        let splitPkg :: [(PkgName, [(Maybe TargetId, Item)])]
    splitPkg = [(Maybe TargetId, Item)] -> [(PkgName, [(Maybe TargetId, Item)])]
    forall a. [(a, Item)] -> [(PkgName, [(a, Item)])]
    splitIPackage [(Maybe TargetId, Item)]
    xs
        let packages :: [(PkgName, (TargetId, TargetId))]
    packages = [(PkgName, [(Maybe TargetId, Item)])]
    -> [(PkgName, (TargetId, TargetId))]
    forall a.
    [(PkgName, [(Maybe TargetId, a)])]
    -> [(PkgName, (TargetId, TargetId))]
    addRange [(PkgName, [(Maybe TargetId, Item)])]
    splitPkg
        StoreWrite
    -> Packages (BStr0, Vector (TargetId, TargetId))
    -> (BStr0, Vector (TargetId, TargetId))
    -> IO ()
    forall (t :: * -> *) a.
    (Typeable (t a), Typeable a, Stored a) =>
    StoreWrite -> t a -> a -> IO ()
    storeWrite StoreWrite
    store Packages (BStr0, Vector (TargetId, TargetId))
    Packages ([String] -> BStr0
    bstr0Join ([String] -> BStr0) -> [String] -> BStr0
    forall a b. (a -> b) -> a -> b
    $ ((PkgName, (TargetId, TargetId)) -> String)
    -> [(PkgName, (TargetId, TargetId))] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (PkgName -> String
    strUnpack (PkgName -> String)
    -> ((PkgName, (TargetId, TargetId)) -> PkgName)
    -> (PkgName, (TargetId, TargetId))
    -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (PkgName, (TargetId, TargetId)) -> PkgName
    forall a b. (a, b) -> a
    fst) [(PkgName, (TargetId, TargetId))]
    packages, [(TargetId, TargetId)] -> Vector (TargetId, TargetId)
    forall a. Storable a => [a] -> Vector a
    V.fromList ([(TargetId, TargetId)] -> Vector (TargetId, TargetId))
    -> [(TargetId, TargetId)] -> Vector (TargetId, TargetId)
    forall a b. (a -> b) -> a -> b
    $ ((PkgName, (TargetId, TargetId)) -> (TargetId, TargetId))
    -> [(PkgName, (TargetId, TargetId))] -> [(TargetId, TargetId)]
    forall a b. (a -> b) -> [a] -> [b]
    map (PkgName, (TargetId, TargetId)) -> (TargetId, TargetId)
    forall a b. (a, b) -> b
    snd [(PkgName, (TargetId, TargetId))]
    packages)

        let categories :: [(String, [(TargetId, TargetId)])]
    categories = ((((Double, (String, String)), String), [(TargetId, TargetId)])
     -> (String, [(TargetId, TargetId)]))
    -> [(((Double, (String, String)), String), [(TargetId, TargetId)])]
    -> [(String, [(TargetId, TargetId)])]
    forall a b. (a -> b) -> [a] -> [b]
    map ((((Double, (String, String)), String) -> String)
    -> ([(TargetId, TargetId)] -> [(TargetId, TargetId)])
    -> (((Double, (String, String)), String), [(TargetId, TargetId)])
    -> (String, [(TargetId, TargetId)])
    forall (p :: * -> * -> *) a b c d.
    Bifunctor p =>
    (a -> b) -> (c -> d) -> p a c -> p b d
    bimap ((Double, (String, String)), String) -> String
    forall a b. (a, b) -> b
    snd [(TargetId, TargetId)] -> [(TargetId, TargetId)]
    forall a. [a] -> [a]
    reverse) ([(((Double, (String, String)), String), [(TargetId, TargetId)])]
     -> [(String, [(TargetId, TargetId)])])
    -> [(((Double, (String, String)), String), [(TargetId, TargetId)])]
    -> [(String, [(TargetId, TargetId)])]
    forall a b. (a -> b) -> a -> b
    $ Map ((Double, (String, String)), String) [(TargetId, TargetId)]
    -> [(((Double, (String, String)), String), [(TargetId, TargetId)])]
    forall k a. Map k a -> [(k, a)]
    Map.toList (Map ((Double, (String, String)), String) [(TargetId, TargetId)]
     -> [(((Double, (String, String)), String),
          [(TargetId, TargetId)])])
    -> Map ((Double, (String, String)), String) [(TargetId, TargetId)]
    -> [(((Double, (String, String)), String), [(TargetId, TargetId)])]
    forall a b. (a -> b) -> a -> b
    $ ([(TargetId, TargetId)]
     -> [(TargetId, TargetId)] -> [(TargetId, TargetId)])
    -> [(((Double, (String, String)), String), [(TargetId, TargetId)])]
    -> Map ((Double, (String, String)), String) [(TargetId, TargetId)]
    forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
    Map.fromListWith [(TargetId, TargetId)]
    -> [(TargetId, TargetId)] -> [(TargetId, TargetId)]
    forall a. [a] -> [a] -> [a]
    (++)
                [((((String, String) -> Double
    forall p. Fractional p => (String, String) -> p
    weightTag (String, String)
    ex, (String -> String) -> (String, String) -> (String, String)
    forall a b. (a -> b) -> (a, a) -> (b, b)
    both String -> String
    lower (String, String)
    ex), String -> (String, String) -> String
    forall a. [a] -> ([a], [a]) -> [a]
    joinPair ":" (String, String)
    ex),[(TargetId, TargetId)
    rng]) | (p :: PkgName
    p,rng :: (TargetId, TargetId)
    rng) <- [(PkgName, (TargetId, TargetId))]
    packages, (String, String)
    ex <- PkgName -> [(String, String)]
    extra PkgName
    p]
        StoreWrite
    -> Categories (BStr0, Jagged (TargetId, TargetId))
    -> (BStr0, Jagged (TargetId, TargetId))
    -> IO ()
    forall (t :: * -> *) a.
    (Typeable (t a), Typeable a, Stored a) =>
    StoreWrite -> t a -> a -> IO ()
    storeWrite StoreWrite
    store Categories (BStr0, Jagged (TargetId, TargetId))
    Categories ([String] -> BStr0
    bstr0Join ([String] -> BStr0) -> [String] -> BStr0
    forall a b. (a -> b) -> a -> b
    $ ((String, [(TargetId, TargetId)]) -> String)
    -> [(String, [(TargetId, TargetId)])] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (String, [(TargetId, TargetId)]) -> String
    forall a b. (a, b) -> a
    fst [(String, [(TargetId, TargetId)])]
    categories, [[(TargetId, TargetId)]] -> Jagged (TargetId, TargetId)
    forall a. Storable a => [[a]] -> Jagged a
    jaggedFromList ([[(TargetId, TargetId)]] -> Jagged (TargetId, TargetId))
    -> [[(TargetId, TargetId)]] -> Jagged (TargetId, TargetId)
    forall a b. (a -> b) -> a -> b
    $ ((String, [(TargetId, TargetId)]) -> [(TargetId, TargetId)])
    -> [(String, [(TargetId, TargetId)])] -> [[(TargetId, TargetId)]]
    forall a b. (a -> b) -> [a] -> [b]
    map (String, [(TargetId, TargetId)]) -> [(TargetId, TargetId)]
    forall a b. (a, b) -> b
    snd [(String, [(TargetId, TargetId)])]
    categories)

        let modules :: [(PkgName, (TargetId, TargetId))]
    modules = [(PkgName, [(Maybe TargetId, Item)])]
    -> [(PkgName, (TargetId, TargetId))]
    forall a.
    [(PkgName, [(Maybe TargetId, a)])]
    -> [(PkgName, (TargetId, TargetId))]
    addRange ([(PkgName, [(Maybe TargetId, Item)])]
     -> [(PkgName, (TargetId, TargetId))])
    -> [(PkgName, [(Maybe TargetId, Item)])]
    -> [(PkgName, (TargetId, TargetId))]
    forall a b. (a -> b) -> a -> b
    $ ((PkgName, [(Maybe TargetId, Item)])
     -> [(PkgName, [(Maybe TargetId, Item)])])
    -> [(PkgName, [(Maybe TargetId, Item)])]
    -> [(PkgName, [(Maybe TargetId, Item)])]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap ([(Maybe TargetId, Item)] -> [(PkgName, [(Maybe TargetId, Item)])]
    forall a. [(a, Item)] -> [(PkgName, [(a, Item)])]
    splitIModule ([(Maybe TargetId, Item)] -> [(PkgName, [(Maybe TargetId, Item)])])
    -> ((PkgName, [(Maybe TargetId, Item)])
        -> [(Maybe TargetId, Item)])
    -> (PkgName, [(Maybe TargetId, Item)])
    -> [(PkgName, [(Maybe TargetId, Item)])]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (PkgName, [(Maybe TargetId, Item)]) -> [(Maybe TargetId, Item)]
    forall a b. (a, b) -> b
    snd) [(PkgName, [(Maybe TargetId, Item)])]
    splitPkg
        StoreWrite
    -> Modules (BStr0, Vector (TargetId, TargetId))
    -> (BStr0, Vector (TargetId, TargetId))
    -> IO ()
    forall (t :: * -> *) a.
    (Typeable (t a), Typeable a, Stored a) =>
    StoreWrite -> t a -> a -> IO ()
    storeWrite StoreWrite
    store Modules (BStr0, Vector (TargetId, TargetId))
    Modules ([String] -> BStr0
    bstr0Join ([String] -> BStr0) -> [String] -> BStr0
    forall a b. (a -> b) -> a -> b
    $ ((PkgName, (TargetId, TargetId)) -> String)
    -> [(PkgName, (TargetId, TargetId))] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (String -> String
    lower (String -> String)
    -> ((PkgName, (TargetId, TargetId)) -> String)
    -> (PkgName, (TargetId, TargetId))
    -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PkgName -> String
    strUnpack (PkgName -> String)
    -> ((PkgName, (TargetId, TargetId)) -> PkgName)
    -> (PkgName, (TargetId, TargetId))
    -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (PkgName, (TargetId, TargetId)) -> PkgName
    forall a b. (a, b) -> a
    fst) [(PkgName, (TargetId, TargetId))]
    modules, [(TargetId, TargetId)] -> Vector (TargetId, TargetId)
    forall a. Storable a => [a] -> Vector a
    V.fromList ([(TargetId, TargetId)] -> Vector (TargetId, TargetId))
    -> [(TargetId, TargetId)] -> Vector (TargetId, TargetId)
    forall a b. (a -> b) -> a -> b
    $ ((PkgName, (TargetId, TargetId)) -> (TargetId, TargetId))
    -> [(PkgName, (TargetId, TargetId))] -> [(TargetId, TargetId)]
    forall a b. (a -> b) -> [a] -> [b]
    map (PkgName, (TargetId, TargetId)) -> (TargetId, TargetId)
    forall a b. (a, b) -> b
    snd [(PkgName, (TargetId, TargetId))]
    modules)

        StoreWrite -> Completions BStr0 -> BStr0 -> IO ()
    forall (t :: * -> *) a.
    (Typeable (t a), Typeable a, Stored a) =>
    StoreWrite -> t a -> a -> IO ()
    storeWrite StoreWrite
    store Completions BStr0
    Completions (BStr0 -> IO ()) -> BStr0 -> IO ()
    forall a b. (a -> b) -> a -> b
    $ [String] -> BStr0
    bstr0Join ([String] -> BStr0) -> [String] -> BStr0
    forall a b. (a -> b) -> a -> b
    $
            (String -> Bool) -> [String] -> [String]
    forall a. (a -> Bool) -> [a] -> [a]
    takeWhile ("set:" String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isPrefixOf`) (((String, [(TargetId, TargetId)]) -> String)
    -> [(String, [(TargetId, TargetId)])] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (String, [(TargetId, TargetId)]) -> String
    forall a b. (a, b) -> a
    fst [(String, [(TargetId, TargetId)])]
    categories) [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++
            (String -> String) -> [String] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map ("package:"String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++) ((String -> String) -> [String] -> [String]
    forall b a. Ord b => (a -> b) -> [a] -> [a]
    sortOn String -> String
    lower ([String] -> [String]) -> [String] -> [String]
    forall a b. (a -> b) -> a -> b
    $ (PkgName -> String) -> [PkgName] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map PkgName -> String
    strUnpack ([PkgName] -> [String]) -> [PkgName] -> [String]
    forall a b. (a -> b) -> a -> b
    $ [PkgName] -> [PkgName]
    forall a. Ord a => [a] -> [a]
    nubOrd ([PkgName] -> [PkgName]) -> [PkgName] -> [PkgName]
    forall a b. (a -> b) -> a -> b
    $ (PkgName -> Bool) -> [PkgName] -> [PkgName]
    forall a. (a -> Bool) -> [a] -> [a]
    filter PkgName -> Bool
    keep ([PkgName] -> [PkgName]) -> [PkgName] -> [PkgName]
    forall a b. (a -> b) -> a -> b
    $ ((PkgName, (TargetId, TargetId)) -> PkgName)
    -> [(PkgName, (TargetId, TargetId))] -> [PkgName]
    forall a b. (a -> b) -> [a] -> [b]
    map (PkgName, (TargetId, TargetId)) -> PkgName
    forall a b. (a, b) -> a
    fst [(PkgName, (TargetId, TargetId))]
    packages) [String] -> [String] -> [String]
    forall a. [a] -> [a] -> [a]
    ++
            ((String, String) -> String) -> [(String, String)] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (String -> (String, String) -> String
    forall a. [a] -> ([a], [a]) -> [a]
    joinPair ":") (((String, String) -> (Double, (String, String)))
    -> [(String, String)] -> [(String, String)]
    forall b a. Ord b => (a -> b) -> [a] -> [a]
    sortOn ((String, String) -> Double
    forall p. Fractional p => (String, String) -> p
    weightTag ((String, String) -> Double)
    -> ((String, String) -> (String, String))
    -> (String, String)
    -> (Double, (String, String))
    forall a b c. (a -> b) -> (a -> c) -> a -> (b, c)
    &&& (String -> String) -> (String, String) -> (String, String)
    forall a b. (a -> b) -> (a, a) -> (b, b)
    both String -> String
    lower) ([(String, String)] -> [(String, String)])
    -> [(String, String)] -> [(String, String)]
    forall a b. (a -> b) -> a -> b
    $ [(String, String)] -> [(String, String)]
    forall a. Ord a => [a] -> [a]
    nubOrd [(String, String)
    ex | (p :: PkgName
    p,_) <- [(PkgName, (TargetId, TargetId))]
    packages, PkgName -> Bool
    keep PkgName
    p, (String, String)
    ex <- PkgName -> [(String, String)]
    extra PkgName
    p, (String, String) -> String
    forall a b. (a, b) -> a
    fst (String, String)
    ex String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "set"])
        where
            addRange :: [(Str, [(Maybe TargetId,a)])] -> [(Str, (TargetId, TargetId))]
            addRange :: [(PkgName, [(Maybe TargetId, a)])]
    -> [(PkgName, (TargetId, TargetId))]
    addRange xs :: [(PkgName, [(Maybe TargetId, a)])]
    xs = [(PkgName
    a, ([TargetId] -> TargetId
    forall a. Ord a => [a] -> a
    minimum' [TargetId]
    is, [TargetId] -> TargetId
    forall a. Ord a => [a] -> a
    maximum' [TargetId]
    is)) | (a :: PkgName
    a,b :: [(Maybe TargetId, a)]
    b) <- [(PkgName, [(Maybe TargetId, a)])]
    xs, let is :: [TargetId]
    is = ((Maybe TargetId, a) -> Maybe TargetId)
    -> [(Maybe TargetId, a)] -> [TargetId]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe (Maybe TargetId, a) -> Maybe TargetId
    forall a b. (a, b) -> a
    fst [(Maybe TargetId, a)]
    b, Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ PkgName -> Bool
    strNull PkgName
    a, [TargetId]
    is [TargetId] -> [TargetId] -> Bool
    forall a. Eq a => a -> a -> Bool
    /= []]

            weightTag :: (String, String) -> p
    weightTag ("set",x :: String
    x) = p -> Maybe p -> p
    forall a. a -> Maybe a -> a
    fromMaybe 0.9 (Maybe p -> p) -> Maybe p -> p
    forall a b. (a -> b) -> a -> b
    $ String -> [(String, p)] -> Maybe p
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup String
    x [("stackage",0.0),("haskell-platform",0.1)]
            weightTag ("package",x :: String
    x) = 1
            weightTag ("category",x :: String
    x) = 2
            weightTag ("license",x :: String
    x) = 3
            weightTag _ = 4

    ---------------------------------------------------------------------
    -- SIMPLE SELECTORS

    completionTags :: StoreRead -> [String]
    completionTags :: StoreRead -> [String]
    completionTags store :: StoreRead
    store = (BStr0 -> String) -> [BStr0] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map BStr0 -> String
    BS.unpack ([BStr0] -> [String]) -> [BStr0] -> [String]
    forall a b. (a -> b) -> a -> b
    $ BStr0 -> [BStr0]
    bstr0Split (BStr0 -> [BStr0]) -> BStr0 -> [BStr0]
    forall a b. (a -> b) -> a -> b
    $ StoreRead -> Completions BStr0 -> BStr0
    forall (t :: * -> *) a.
    (Typeable (t a), Typeable a, Stored a) =>
    StoreRead -> t a -> a
    storeRead StoreRead
    store Completions BStr0
    Completions

    ---------------------------------------------------------------------
    -- DATA TYPE, PARSE, PRINT

    data Tag = IsExact | IsPackage | IsModule | EqPackage String | EqModule String | EqCategory String String deriving Tag -> Tag -> Bool
    (Tag -> Tag -> Bool) -> (Tag -> Tag -> Bool) -> Eq Tag
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: Tag -> Tag -> Bool
    $c/= :: Tag -> Tag -> Bool
    == :: Tag -> Tag -> Bool
    $c== :: Tag -> Tag -> Bool
    Eq

    parseTag :: String -> String -> Maybe Tag
    parseTag :: String -> String -> Maybe Tag
    parseTag k :: String
    k v :: String
    v
        | String
    k String -> String -> Bool
    ~~ "is" = case () of
            _ | String
    v String -> String -> Bool
    ~~ "exact" -> Tag -> Maybe Tag
    forall a. a -> Maybe a
    Just Tag
    IsExact
              | String
    v String -> String -> Bool
    ~~ "package" -> Tag -> Maybe Tag
    forall a. a -> Maybe a
    Just Tag
    IsPackage
              | String
    v String -> String -> Bool
    ~~ "module" -> Tag -> Maybe Tag
    forall a. a -> Maybe a
    Just Tag
    IsModule
              | Bool
    otherwise -> Maybe Tag
    forall a. Maybe a
    Nothing
        | String
    k String -> String -> Bool
    ~~ "package" = if String
    v String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "" then Maybe Tag
    forall a. Maybe a
    Nothing else Tag -> Maybe Tag
    forall a. a -> Maybe a
    Just (Tag -> Maybe Tag) -> Tag -> Maybe Tag
    forall a b. (a -> b) -> a -> b
    $ String -> Tag
    EqPackage String
    v
        | String
    k String -> String -> Bool
    ~~ "module" = if String
    v String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == "" then Maybe Tag
    forall a. Maybe a
    Nothing else Tag -> Maybe Tag
    forall a. a -> Maybe a
    Just (Tag -> Maybe Tag) -> Tag -> Maybe Tag
    forall a b. (a -> b) -> a -> b
    $ String -> Tag
    EqModule String
    v
        | String
    v String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "" = Tag -> Maybe Tag
    forall a. a -> Maybe a
    Just (Tag -> Maybe Tag) -> Tag -> Maybe Tag
    forall a b. (a -> b) -> a -> b
    $ String -> String -> Tag
    EqCategory String
    k String
    v
        | Bool
    otherwise = Maybe Tag
    forall a. Maybe a
    Nothing
        where
            -- make the assumption the first letter always disambiguates
            x :: String
    x ~~ :: String -> String -> Bool
    ~~ lit :: String
    lit = String
    x String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    /= "" Bool -> Bool -> Bool
    && String -> String
    lower String
    x String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isPrefixOf` String
    lit

    showTag :: Tag -> (String, String)
    showTag :: Tag -> (String, String)
    showTag IsExact = ("is","exact")
    showTag IsPackage = ("is","package")
    showTag IsModule = ("is","module")
    showTag (EqPackage x :: String
    x) = ("package",String
    x)
    showTag (EqModule x :: String
    x) = ("module",String
    x)
    showTag (EqCategory k :: String
    k v :: String
    v) = (String
    k,String
    v)

    ---------------------------------------------------------------------
    -- TAG SEMANTICS

    -- | Given a tag, find the ranges of identifiers it covers (if it restricts the range)
    -- An empty range means an empty result, while a Nothing means a search on the entire range
    resolveTag :: StoreRead -> Tag -> (Tag, Maybe [(TargetId,TargetId)])
    resolveTag :: StoreRead -> Tag -> (Tag, Maybe [(TargetId, TargetId)])
    resolveTag store :: StoreRead
    store x :: Tag
    x = case Tag
    x of
        IsExact -> (Tag
    IsExact, Maybe [(TargetId, TargetId)]
    forall a. Maybe a
    Nothing)
        IsPackage -> (Tag
    IsPackage, [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
    forall a. a -> Maybe a
    Just ([(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)])
    -> [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
    forall a b. (a -> b) -> a -> b
    $ ((TargetId, TargetId) -> (TargetId, TargetId))
    -> [(TargetId, TargetId)] -> [(TargetId, TargetId)]
    forall a b. (a -> b) -> [a] -> [b]
    map (TargetId -> (TargetId, TargetId)
    forall a. a -> (a, a)
    dupe (TargetId -> (TargetId, TargetId))
    -> ((TargetId, TargetId) -> TargetId)
    -> (TargetId, TargetId)
    -> (TargetId, TargetId)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (TargetId, TargetId) -> TargetId
    forall a b. (a, b) -> a
    fst) ([(TargetId, TargetId)] -> [(TargetId, TargetId)])
    -> [(TargetId, TargetId)] -> [(TargetId, TargetId)]
    forall a b. (a -> b) -> a -> b
    $ Vector (TargetId, TargetId) -> [(TargetId, TargetId)]
    forall a. Storable a => Vector a -> [a]
    V.toList Vector (TargetId, TargetId)
    packageIds)
        IsModule -> (Tag
    IsModule, [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
    forall a. a -> Maybe a
    Just ([(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)])
    -> [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
    forall a b. (a -> b) -> a -> b
    $ ((TargetId, TargetId) -> (TargetId, TargetId))
    -> [(TargetId, TargetId)] -> [(TargetId, TargetId)]
    forall a b. (a -> b) -> [a] -> [b]
    map (TargetId -> (TargetId, TargetId)
    forall a. a -> (a, a)
    dupe (TargetId -> (TargetId, TargetId))
    -> ((TargetId, TargetId) -> TargetId)
    -> (TargetId, TargetId)
    -> (TargetId, TargetId)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (TargetId, TargetId) -> TargetId
    forall a b. (a, b) -> a
    fst) ([(TargetId, TargetId)] -> [(TargetId, TargetId)])
    -> [(TargetId, TargetId)] -> [(TargetId, TargetId)]
    forall a b. (a -> b) -> a -> b
    $ Vector (TargetId, TargetId) -> [(TargetId, TargetId)]
    forall a. Storable a => Vector a -> [a]
    V.toList Vector (TargetId, TargetId)
    moduleIds)
        EqPackage orig :: String
    orig@(String -> BStr0
    BS.pack -> BStr0
    val)
            -- look for people who are an exact prefix, sort by remaining length, if there are ties, pick the first one
            | res :: [(Int, (Int, BStr0))]
    res@(_:_) <- [(BStr0 -> Int
    BS.length BStr0
    x, (Int
    i,BStr0
    x)) | (i :: Int
    i,x :: BStr0
    x) <- Int -> [BStr0] -> [(Int, BStr0)]
    forall a b. Enum a => a -> [b] -> [(a, b)]
    zipFrom 0 ([BStr0] -> [(Int, BStr0)]) -> [BStr0] -> [(Int, BStr0)]
    forall a b. (a -> b) -> a -> b
    $ BStr0 -> [BStr0]
    bstr0Split BStr0
    packageNames, BStr0
    val BStr0 -> BStr0 -> Bool
    `BS.isPrefixOf` BStr0
    x]
                -> let (i :: Int
    i,x :: BStr0
    x) = (Int, (Int, BStr0)) -> (Int, BStr0)
    forall a b. (a, b) -> b
    snd ((Int, (Int, BStr0)) -> (Int, BStr0))
    -> (Int, (Int, BStr0)) -> (Int, BStr0)
    forall a b. (a -> b) -> a -> b
    $ ((Int, (Int, BStr0)) -> (Int, (Int, BStr0)) -> Ordering)
    -> [(Int, (Int, BStr0))] -> (Int, (Int, BStr0))
    forall (t :: * -> *) a.
    Foldable t =>
    (a -> a -> Ordering) -> t a -> a
    minimumBy (Int -> Int -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare (Int -> Int -> Ordering)
    -> ((Int, (Int, BStr0)) -> Int)
    -> (Int, (Int, BStr0))
    -> (Int, (Int, BStr0))
    -> Ordering
    forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
    `on` (Int, (Int, BStr0)) -> Int
    forall a b. (a, b) -> a
    fst) [(Int, (Int, BStr0))]
    res in (String -> Tag
    EqPackage (String -> Tag) -> String -> Tag
    forall a b. (a -> b) -> a -> b
    $ BStr0 -> String
    BS.unpack BStr0
    x, [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
    forall a. a -> Maybe a
    Just [Vector (TargetId, TargetId)
    packageIds Vector (TargetId, TargetId) -> Int -> (TargetId, TargetId)
    forall a. Storable a => Vector a -> Int -> a
    V.! Int
    i])
            | Bool
    otherwise -> (String -> Tag
    EqPackage String
    orig , [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
    forall a. a -> Maybe a
    Just [])
        EqModule x :: String
    x -> (String -> Tag
    EqModule String
    x, [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
    forall a. a -> Maybe a
    Just ([(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)])
    -> [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
    forall a b. (a -> b) -> a -> b
    $ (Int -> (TargetId, TargetId)) -> [Int] -> [(TargetId, TargetId)]
    forall a b. (a -> b) -> [a] -> [b]
    map (Vector (TargetId, TargetId)
    moduleIds Vector (TargetId, TargetId) -> Int -> (TargetId, TargetId)
    forall a. Storable a => Vector a -> Int -> a
    V.!) ([Int] -> [(TargetId, TargetId)])
    -> [Int] -> [(TargetId, TargetId)]
    forall a b. (a -> b) -> a -> b
    $ (BStr0 -> Bool) -> [BStr0] -> [Int]
    forall a. (a -> Bool) -> [a] -> [Int]
    findIndices (String -> BStr0 -> Bool
    eqModule (String -> BStr0 -> Bool) -> String -> BStr0 -> Bool
    forall a b. (a -> b) -> a -> b
    $ String -> String
    lower String
    x) ([BStr0] -> [Int]) -> [BStr0] -> [Int]
    forall a b. (a -> b) -> a -> b
    $ BStr0 -> [BStr0]
    bstr0Split BStr0
    moduleNames)
        EqCategory cat :: String
    cat val :: String
    val -> (String -> String -> Tag
    EqCategory String
    cat String
    val, [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
    forall a. a -> Maybe a
    Just ([(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)])
    -> [(TargetId, TargetId)] -> Maybe [(TargetId, TargetId)]
    forall a b. (a -> b) -> a -> b
    $ [[(TargetId, TargetId)]] -> [(TargetId, TargetId)]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat
            [ Vector (TargetId, TargetId) -> [(TargetId, TargetId)]
    forall a. Storable a => Vector a -> [a]
    V.toList (Vector (TargetId, TargetId) -> [(TargetId, TargetId)])
    -> Vector (TargetId, TargetId) -> [(TargetId, TargetId)]
    forall a b. (a -> b) -> a -> b
    $ Jagged (TargetId, TargetId) -> Int -> Vector (TargetId, TargetId)
    forall a. Storable a => Jagged a -> Int -> Vector a
    jaggedAsk Jagged (TargetId, TargetId)
    categoryIds Int
    i
            | Int
    i <- BStr0 -> [BStr0] -> [Int]
    forall a. Eq a => a -> [a] -> [Int]
    elemIndices (String -> BStr0
    BS.pack (String
    cat String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ ":" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    val)) ([BStr0] -> [Int]) -> [BStr0] -> [Int]
    forall a b. (a -> b) -> a -> b
    $ BStr0 -> [BStr0]
    bstr0Split BStr0
    categoryNames])
        where
            eqModule :: String -> BStr0 -> Bool
    eqModule x :: String
    x | Just x :: String
    x <- String -> String -> Maybe String
    forall a. Eq a => [a] -> [a] -> Maybe [a]
    stripPrefix "." String
    x, Just x :: String
    x <- String -> String -> Maybe String
    forall a. Eq a => [a] -> [a] -> Maybe [a]
    stripSuffix "." String
    x = BStr0 -> BStr0 -> Bool
    forall a. Eq a => a -> a -> Bool
    (==) (String -> BStr0
    BS.pack String
    x)
                       | Just x :: String
    x <- String -> String -> Maybe String
    forall a. Eq a => [a] -> [a] -> Maybe [a]
    stripPrefix "." String
    x = BStr0 -> BStr0 -> Bool
    BS.isPrefixOf (BStr0 -> BStr0 -> Bool) -> BStr0 -> BStr0 -> Bool
    forall a b. (a -> b) -> a -> b
    $ String -> BStr0
    BS.pack String
    x
                       | Bool
    otherwise = let y :: BStr0
    y = String -> BStr0
    BS.pack String
    x; y2 :: BStr0
    y2 = String -> BStr0
    BS.pack ('.'Char -> String -> String
    forall a. a -> [a] -> [a]
    :String
    x)
                                     in \v :: BStr0
    v -> BStr0
    y BStr0 -> BStr0 -> Bool
    `BS.isPrefixOf` BStr0
    v Bool -> Bool -> Bool
    || BStr0
    y2 BStr0 -> BStr0 -> Bool
    `BS.isInfixOf` BStr0
    v

            (packageNames :: BStr0
    packageNames, packageIds :: Vector (TargetId, TargetId)
    packageIds) = StoreRead
    -> Packages (BStr0, Vector (TargetId, TargetId))
    -> (BStr0, Vector (TargetId, TargetId))
    forall (t :: * -> *) a.
    (Typeable (t a), Typeable a, Stored a) =>
    StoreRead -> t a -> a
    storeRead StoreRead
    store Packages (BStr0, Vector (TargetId, TargetId))
    Packages
            (categoryNames :: BStr0
    categoryNames, categoryIds :: Jagged (TargetId, TargetId)
    categoryIds) = StoreRead
    -> Categories (BStr0, Jagged (TargetId, TargetId))
    -> (BStr0, Jagged (TargetId, TargetId))
    forall (t :: * -> *) a.
    (Typeable (t a), Typeable a, Stored a) =>
    StoreRead -> t a -> a
    storeRead StoreRead
    store Categories (BStr0, Jagged (TargetId, TargetId))
    Categories
            (moduleNames :: BStr0
    moduleNames, moduleIds :: Vector (TargetId, TargetId)
    moduleIds) = StoreRead
    -> Modules (BStr0, Vector (TargetId, TargetId))
    -> (BStr0, Vector (TargetId, TargetId))
    forall (t :: * -> *) a.
    (Typeable (t a), Typeable a, Stored a) =>
    StoreRead -> t a -> a
    storeRead StoreRead
    store Modules (BStr0, Vector (TargetId, TargetId))
    Modules

    ---------------------------------------------------------------------
    -- TAG QUERIES

    -- | Given a query produce: (refined query, is:exact, filter, enumeration)
    --   You should apply the filter to other peoples results, or if you have nothing else, use the enumeration.
    applyTags :: StoreRead -> [Query] -> ([Query], Bool, TargetId -> Bool, [TargetId])
    applyTags :: StoreRead
    -> [Query] -> ([Query], Bool, TargetId -> Bool, [TargetId])
    applyTags store :: StoreRead
    store qs :: [Query]
    qs = ([Query]
    qs2, Bool
    exact, TargetId -> Bool
    filt, StoreRead -> [Query] -> [TargetId]
    searchTags StoreRead
    store [Query]
    qs)
        where (qs2 :: [Query]
    qs2, exact :: Bool
    exact, filt :: TargetId -> Bool
    filt) = StoreRead -> [Query] -> ([Query], Bool, TargetId -> Bool)
    filterTags StoreRead
    store [Query]
    qs

    filterTags :: StoreRead -> [Query] -> ([Query], Bool, TargetId -> Bool)
    filterTags :: StoreRead -> [Query] -> ([Query], Bool, TargetId -> Bool)
    filterTags ts :: StoreRead
    ts qs :: [Query]
    qs = ((Query -> Query) -> [Query] -> [Query]
    forall a b. (a -> b) -> [a] -> [b]
    map Query -> Query
    redo [Query]
    qs, Bool
    exact, \i :: TargetId
    i -> ((TargetId -> Bool) -> Bool) -> [TargetId -> Bool] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all ((TargetId -> Bool) -> TargetId -> Bool
    forall a b. (a -> b) -> a -> b
    $ TargetId
    i) [TargetId -> Bool]
    fs)
        where fs :: [TargetId -> Bool]
    fs = ((String, [Query]) -> TargetId -> Bool)
    -> [(String, [Query])] -> [TargetId -> Bool]
    forall a b. (a -> b) -> [a] -> [b]
    map (StoreRead -> [Query] -> TargetId -> Bool
    filterTags2 StoreRead
    ts ([Query] -> TargetId -> Bool)
    -> ((String, [Query]) -> [Query])
    -> (String, [Query])
    -> TargetId
    -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (String, [Query]) -> [Query]
    forall a b. (a, b) -> b
    snd) ([(String, [Query])] -> [TargetId -> Bool])
    -> [(String, [Query])] -> [TargetId -> Bool]
    forall a b. (a -> b) -> a -> b
    $ [(String, Query)] -> [(String, [Query])]
    forall k v. Ord k => [(k, v)] -> [(k, [v])]
    groupSort ([(String, Query)] -> [(String, [Query])])
    -> [(String, Query)] -> [(String, [Query])]
    forall a b. (a -> b) -> a -> b
    $ (Query -> (String, Query)) -> [Query] -> [(String, Query)]
    forall a b. (a -> b) -> [a] -> [b]
    map (Query -> String
    scopeCategory (Query -> String) -> (Query -> Query) -> Query -> (String, Query)
    forall a b c. (a -> b) -> (a -> c) -> a -> (b, c)
    &&& Query -> Query
    forall a. a -> a
    id) ([Query] -> [(String, Query)]) -> [Query] -> [(String, Query)]
    forall a b. (a -> b) -> a -> b
    $ (Query -> Bool) -> [Query] -> [Query]
    forall a. (a -> Bool) -> [a] -> [a]
    filter Query -> Bool
    isQueryScope [Query]
    qs
              exact :: Bool
    exact = Tag -> Maybe Tag
    forall a. a -> Maybe a
    Just Tag
    IsExact Maybe Tag -> [Maybe Tag] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [String -> String -> Maybe Tag
    parseTag String
    a String
    b | QueryScope True a :: String
    a b :: String
    b <- [Query]
    qs]
              redo :: Query -> Query
    redo (QueryScope sense :: Bool
    sense cat :: String
    cat val :: String
    val)
                  | Just (k :: String
    k,v :: String
    v) <- (Tag -> (String, String)) -> Maybe Tag -> Maybe (String, String)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Tag -> (String, String)
    showTag (Tag -> (String, String))
    -> (Tag -> Tag) -> Tag -> (String, String)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Tag, Maybe [(TargetId, TargetId)]) -> Tag
    forall a b. (a, b) -> a
    fst ((Tag, Maybe [(TargetId, TargetId)]) -> Tag)
    -> (Tag -> (Tag, Maybe [(TargetId, TargetId)])) -> Tag -> Tag
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . StoreRead -> Tag -> (Tag, Maybe [(TargetId, TargetId)])
    resolveTag StoreRead
    ts) (Maybe Tag -> Maybe (String, String))
    -> Maybe Tag -> Maybe (String, String)
    forall a b. (a -> b) -> a -> b
    $ String -> String -> Maybe Tag
    parseTag String
    cat String
    val = Bool -> String -> String -> Query
    QueryScope Bool
    sense String
    k String
    v
                  | Bool
    otherwise = String -> Query
    QueryNone (String -> Query) -> String -> Query
    forall a b. (a -> b) -> a -> b
    $ ['-' | Bool -> Bool
    not Bool
    sense] String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    cat String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ ":" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    val
              redo q :: Query
    q = Query
    q

    filterTags2 :: StoreRead -> [Query] -> TargetId -> Bool
    filterTags2 ts :: StoreRead
    ts qs :: [Query]
    qs = \i :: TargetId
    i -> Bool -> Bool
    not (TargetId -> Bool
    negq TargetId
    i) Bool -> Bool -> Bool
    && (Bool
    noPosRestrict Bool -> Bool -> Bool
    || TargetId -> Bool
    posq TargetId
    i)
        where (posq :: TargetId -> Bool
    posq,negq :: TargetId -> Bool
    negq) = ([(TargetId, TargetId)] -> TargetId -> Bool)
    -> ([(TargetId, TargetId)], [(TargetId, TargetId)])
    -> (TargetId -> Bool, TargetId -> Bool)
    forall a b. (a -> b) -> (a, a) -> (b, b)
    both [(TargetId, TargetId)] -> TargetId -> Bool
    forall a. Ix a => [(a, a)] -> a -> Bool
    inRanges ([(TargetId, TargetId)]
    pos,[(TargetId, TargetId)]
    neg)
              (pos :: [(TargetId, TargetId)]
    pos, neg :: [(TargetId, TargetId)]
    neg) = ([(Bool, [(TargetId, TargetId)])] -> [(TargetId, TargetId)])
    -> ([(Bool, [(TargetId, TargetId)])],
        [(Bool, [(TargetId, TargetId)])])
    -> ([(TargetId, TargetId)], [(TargetId, TargetId)])
    forall a b. (a -> b) -> (a, a) -> (b, b)
    both (((Bool, [(TargetId, TargetId)]) -> [(TargetId, TargetId)])
    -> [(Bool, [(TargetId, TargetId)])] -> [(TargetId, TargetId)]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap (Bool, [(TargetId, TargetId)]) -> [(TargetId, TargetId)]
    forall a b. (a, b) -> b
    snd) (([(Bool, [(TargetId, TargetId)])],
      [(Bool, [(TargetId, TargetId)])])
     -> ([(TargetId, TargetId)], [(TargetId, TargetId)]))
    -> ([(Bool, [(TargetId, TargetId)])],
        [(Bool, [(TargetId, TargetId)])])
    -> ([(TargetId, TargetId)], [(TargetId, TargetId)])
    forall a b. (a -> b) -> a -> b
    $ ((Bool, [(TargetId, TargetId)]) -> Bool)
    -> [(Bool, [(TargetId, TargetId)])]
    -> ([(Bool, [(TargetId, TargetId)])],
        [(Bool, [(TargetId, TargetId)])])
    forall a. (a -> Bool) -> [a] -> ([a], [a])
    partition (Bool, [(TargetId, TargetId)]) -> Bool
    forall a b. (a, b) -> a
    fst [(Bool, [(TargetId, TargetId)])]
    xs
              xs :: [(Bool, [(TargetId, TargetId)])]
    xs = [Maybe (Bool, [(TargetId, TargetId)])]
    -> [(Bool, [(TargetId, TargetId)])]
    forall a. [Maybe a] -> [a]
    catMaybes [Maybe (Bool, [(TargetId, TargetId)])]
    restrictions
              noPosRestrict :: Bool
    noPosRestrict = (Maybe (Bool, [(TargetId, TargetId)]) -> Bool)
    -> [Maybe (Bool, [(TargetId, TargetId)])] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all Maybe (Bool, [(TargetId, TargetId)]) -> Bool
    forall b. Maybe (Bool, b) -> Bool
    pred [Maybe (Bool, [(TargetId, TargetId)])]
    restrictions
              restrictions :: [Maybe (Bool, [(TargetId, TargetId)])]
    restrictions = (Query -> Maybe (Bool, [(TargetId, TargetId)]))
    -> [Query] -> [Maybe (Bool, [(TargetId, TargetId)])]
    forall a b. (a -> b) -> [a] -> [b]
    map Query -> Maybe (Bool, [(TargetId, TargetId)])
    getRestriction [Query]
    qs
              pred :: Maybe (Bool, b) -> Bool
    pred Nothing = Bool
    True
              pred (Just (sense :: Bool
    sense, _)) = Bool -> Bool
    not Bool
    sense
              getRestriction :: Query -> Maybe (Bool,[(TargetId, TargetId)])
              getRestriction :: Query -> Maybe (Bool, [(TargetId, TargetId)])
    getRestriction (QueryScope sense :: Bool
    sense cat :: String
    cat val :: String
    val) = do
                Tag
    tag <- String -> String -> Maybe Tag
    parseTag String
    cat String
    val
                [(TargetId, TargetId)]
    ranges <- (Tag, Maybe [(TargetId, TargetId)]) -> Maybe [(TargetId, TargetId)]
    forall a b. (a, b) -> b
    snd ((Tag, Maybe [(TargetId, TargetId)])
     -> Maybe [(TargetId, TargetId)])
    -> (Tag, Maybe [(TargetId, TargetId)])
    -> Maybe [(TargetId, TargetId)]
    forall a b. (a -> b) -> a -> b
    $ StoreRead -> Tag -> (Tag, Maybe [(TargetId, TargetId)])
    resolveTag StoreRead
    ts Tag
    tag
                (Bool, [(TargetId, TargetId)])
    -> Maybe (Bool, [(TargetId, TargetId)])
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Bool
    sense, [(TargetId, TargetId)]
    ranges)

    -- | Given a search which has no type or string in it, run the query on the tag bits.
    --   Using for things like IsModule, EqCategory etc.
    searchTags :: StoreRead -> [Query] -> [TargetId]
    searchTags :: StoreRead -> [Query] -> [TargetId]
    searchTags ts :: StoreRead
    ts qs :: [Query]
    qs
        | x :: [TargetId]
    x:xs :: [[TargetId]]
    xs <- [((TargetId, TargetId) -> TargetId)
    -> [(TargetId, TargetId)] -> [TargetId]
    forall a b. (a -> b) -> [a] -> [b]
    map (TargetId, TargetId) -> TargetId
    forall a b. (a, b) -> a
    fst ([(TargetId, TargetId)] -> [TargetId])
    -> [(TargetId, TargetId)] -> [TargetId]
    forall a b. (a -> b) -> a -> b
    $ [(TargetId, TargetId)]
    -> (Tag -> [(TargetId, TargetId)])
    -> Maybe Tag
    -> [(TargetId, TargetId)]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] ([(TargetId, TargetId)]
    -> Maybe [(TargetId, TargetId)] -> [(TargetId, TargetId)]
    forall a. a -> Maybe a -> a
    fromMaybe [] (Maybe [(TargetId, TargetId)] -> [(TargetId, TargetId)])
    -> (Tag -> Maybe [(TargetId, TargetId)])
    -> Tag
    -> [(TargetId, TargetId)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Tag, Maybe [(TargetId, TargetId)]) -> Maybe [(TargetId, TargetId)]
    forall a b. (a, b) -> b
    snd ((Tag, Maybe [(TargetId, TargetId)])
     -> Maybe [(TargetId, TargetId)])
    -> (Tag -> (Tag, Maybe [(TargetId, TargetId)]))
    -> Tag
    -> Maybe [(TargetId, TargetId)]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . StoreRead -> Tag -> (Tag, Maybe [(TargetId, TargetId)])
    resolveTag StoreRead
    ts) (Maybe Tag -> [(TargetId, TargetId)])
    -> Maybe Tag -> [(TargetId, TargetId)]
    forall a b. (a -> b) -> a -> b
    $ String -> String -> Maybe Tag
    parseTag String
    cat String
    val | QueryScope True cat :: String
    cat val :: String
    val <- [Query]
    qs]
        = if [[TargetId]] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [[TargetId]]
    xs then [TargetId]
    x else (TargetId -> Bool) -> [TargetId] -> [TargetId]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (TargetId -> Set TargetId -> Bool
    forall a. Ord a => a -> Set a -> Bool
    `Set.member` (Set TargetId -> Set TargetId -> Set TargetId)
    -> [Set TargetId] -> Set TargetId
    forall a. (a -> a -> a) -> [a] -> a
    foldl1' Set TargetId -> Set TargetId -> Set TargetId
    forall a. Ord a => Set a -> Set a -> Set a
    Set.intersection (([TargetId] -> Set TargetId) -> [[TargetId]] -> [Set TargetId]
    forall a b. (a -> b) -> [a] -> [b]
    map [TargetId] -> Set TargetId
    forall a. Ord a => [a] -> Set a
    Set.fromList [[TargetId]]
    xs)) [TargetId]
    x
    searchTags ts :: StoreRead
    ts _ = [TargetId]
    -> ([(TargetId, TargetId)] -> [TargetId])
    -> Maybe [(TargetId, TargetId)]
    -> [TargetId]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [] (((TargetId, TargetId) -> TargetId)
    -> [(TargetId, TargetId)] -> [TargetId]
    forall a b. (a -> b) -> [a] -> [b]
    map (TargetId, TargetId) -> TargetId
    forall a b. (a, b) -> a
    fst) (Maybe [(TargetId, TargetId)] -> [TargetId])
    -> Maybe [(TargetId, TargetId)] -> [TargetId]
    forall a b. (a -> b) -> a -> b
    $ (Tag, Maybe [(TargetId, TargetId)]) -> Maybe [(TargetId, TargetId)]
    forall a b. (a, b) -> b
    snd ((Tag, Maybe [(TargetId, TargetId)])
     -> Maybe [(TargetId, TargetId)])
    -> (Tag, Maybe [(TargetId, TargetId)])
    -> Maybe [(TargetId, TargetId)]
    forall a b. (a -> b) -> a -> b
    $ StoreRead -> Tag -> (Tag, Maybe [(TargetId, TargetId)])
    resolveTag StoreRead
    ts Tag
    IsPackage