+ = proc str → do case str of
+ "" → none ⤙ ()
+ _ → returnA ⤙ str
+
+chomp ∷ String → String
+{-# INLINE chomp #-}
+chomp = reverse . snd . break (≢ '\n') . reverse
+
+guessMIMEType ∷ LS.ByteString → MIMEType
+{-# INLINEABLE guessMIMEType #-}
+guessMIMEType = read
+ ∘ unsafePerformIO
+ ∘ flip BS.unsafeUseAsCStringLen (magicCString magic)
+ ∘ BS.concat
+ ∘ LS.toChunks
+ where
+ magic ∷ Magic
+ {-# NOINLINE magic #-}
+ magic = unsafePerformIO
+ $ do m ← magicOpen [MagicMime]
+ magicLoadDefault m
+ return m
+
+{-
+isSafeChar ∷ Char → Bool
+{-# INLINEABLE isSafeChar #-}
+isSafeChar c
+ | c ≡ '/' = True
+ | isReserved c = False
+ | c > ' ' ∧ c ≤ '~' = True
+ | otherwise = False
+-}
+
+mkQueryString ∷ [(T.Text, T.Text)] → Ascii
+{-# INLINEABLE mkQueryString #-}
+mkQueryString = A.unsafeFromByteString
+ ∘ BS.intercalate (C8.singleton ';')
+ ∘ map encodePair
+ where
+ encodePair ∷ (T.Text, T.Text) → BS.ByteString
+ {-# INLINE encodePair #-}
+ encodePair (k, v)
+ = BS.intercalate (C8.singleton '=') [encodeText k, encodeText v]
+
+ encodeText ∷ T.Text → BS.ByteString
+ {-# INLINE encodeText #-}
+ encodeText = toURLEncoded ∘ encodeUtf8
+
+toURLEncoded ∷ BS.ByteString → BS.ByteString
+{-# INLINEABLE toURLEncoded #-}
+toURLEncoded = C8.concatMap go
+ where
+ go ∷ Char → BS.ByteString
+ {-# INLINE go #-}
+ go c | c ≡ ' ' = C8.singleton '+'
+ | isReserved c = urlEncode c
+ | isUnreserved c = C8.singleton c
+ | otherwise = urlEncode c
+
+ urlEncode ∷ Char → BS.ByteString
+ {-# INLINE urlEncode #-}
+ urlEncode c = C8.pack ('%':toHex (ord c))