diff --git a/Sound/Tidal/Pattern.hs b/Sound/Tidal/Pattern.hs
--- a/Sound/Tidal/Pattern.hs
+++ b/Sound/Tidal/Pattern.hs
@@ -20,12 +20,10 @@
 -- values. For discrete patterns, this returns the events which are
 -- active during that time. For continuous patterns, events with
 -- values for the midpoint of the given @Arc@ is returned.
-
 data Pattern a = Pattern {arc :: Arc -> [Event a]}
 
 -- | @show (p :: Pattern)@ returns a text string representing the
 -- event values active during the first cycle of the given pattern.
-
 instance (Show a) => Show (Pattern a) where
   show p@(Pattern _) = show $ arc p (0, 1)
 
@@ -168,7 +166,6 @@
 
 -- | @run@ @n@ returns a pattern representing a cycle of numbers from @0@ to @n-1@.
 run n = listToPat [0 .. n-1]
-
 scan n = cat $ map run [1 .. n]
 
 -- | @density@ returns the given pattern with density increased by the
@@ -195,7 +192,6 @@
 slow 0 = id
 slow t = density (1/t) 
 
-
 -- | The @<~@ operator shifts (or rotates) a pattern to the left (or
 -- counter-clockwise) by the given @Time@ value. For example 
 -- @(1%16) <~ p@ will return a pattern with all the events moved 
@@ -408,6 +404,15 @@
           toMaybe True a  = Just a
           unMaybe = (fromJust <$>) . filterValues isJust
 
+unDegradeBy :: Double -> Pattern a -> Pattern a
+unDegradeBy x p = unMaybe $ (\a f -> toMaybe (f <= x) a) <$> p <*> rand
+    where toMaybe False _ = Nothing
+          toMaybe True a  = Just a
+          unMaybe = (fromJust <$>) . filterValues isJust
+
+sometimesBy :: Double -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
+sometimesBy x f p = overlay (f (degradeBy x p)) (unDegradeBy x p)
+
 degrade :: Pattern a -> Pattern a
 degrade = degradeBy 0.5
 
@@ -451,13 +456,11 @@
 -- @within@ uses @compress@ and @zoom to apply @f@ to only part of pattern @p@
 -- for example, @within (1%2) (3%4) ((1%8) <~) "bd sn bd cp"@ would shift only
 -- the second @bd@
-withArc :: Arc -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
-withArc (s,e) f p = stack [sliceArc (0,s) p, 
+within :: Arc -> (Pattern a -> Pattern a) -> Pattern a -> Pattern a
+within (s,e) f p = stack [sliceArc (0,s) p, 
                            compress (s,e) $ f $ zoom (s,e) p, 
                            sliceArc (e,1) p
                           ]
 
-within = withArc
-
-revArc a = withArc a rev
+revArc a = within a rev
 
diff --git a/Sound/Tidal/Strategies.hs b/Sound/Tidal/Strategies.hs
--- a/Sound/Tidal/Strategies.hs
+++ b/Sound/Tidal/Strategies.hs
@@ -6,6 +6,7 @@
 import Control.Applicative
 import qualified Data.Map as Map
 
+import Data.Maybe
 import Sound.Tidal.Dirt
 import Sound.Tidal.Pattern
 import Sound.Tidal.Stream
@@ -107,4 +108,22 @@
 
 chopArc :: Arc -> Int -> [Arc]
 chopArc (s, e) n = map (\i -> ((s + (e-s)*(fromIntegral i/fromIntegral n)), s + (e-s)*((fromIntegral $ i+1)/fromIntegral n))) [0 .. n-1]
+{-
+normEv :: Event a -> Event a -> Event a
+normEv ev@(_, (s,e), _) ev'@(_, (s',e'), _) 
+       | not on && not off = [] -- shouldn't happen
+       | on && off = splitEv ev'
+       | not on && s' > sam s = []
+       | not off && e' < nextSam s = [(fst' ev, mapSnd' (mapSnd (min $ nextSam s)) ev, thd' ev)]
+  where on = onsetIn (sam s, nextSam s) ev
+        off = offsetIn (sam s, nextSam s) ev
+        eplitEv
+-}
+--mapCycleEvents :: Pattern a -> ([Event a] -> [Event a]) -> Pattern a
+--mapCycleEvents p f = splitQueries $ Pattern $ \(s,e) -> filter (\ev -> isJust $ subArc (s,e) (eventArc ev)) $ f $ arc p (sam s, nextSam s)
+
+--off :: Time -> Pattern a -> Pattern a
+--off t p = mapCycleEvents p (mapArcs (mapSnd wrappedPlus . mapFst wrappedPlus))
+--               where wrapAtCycle f t' = sam t' + cyclePos (f t')
+--                     wrappedPlus = wrapAtCycle (+t)
 
diff --git a/Sound/Tidal/Time.hs b/Sound/Tidal/Time.hs
--- a/Sound/Tidal/Time.hs
+++ b/Sound/Tidal/Time.hs
@@ -47,7 +47,13 @@
                 | sam s == sam e = [(s,e)]
                 | otherwise = (s, nextSam s) : (arcCycles (nextSam s, e))
 
+-- | Splits the given @Arc@ into a list of @Arc@s, at cycle boundaries, but wrapping the arcs within the same cycle.
+arcCycles' :: Arc -> [Arc]
+arcCycles' (s,e) | s >= e = []
+                 | sam s == sam e = [(s,e)]
+                 | otherwise = (s, nextSam s) : (arcCycles' ((nextSam s) - 1, e - 1))
 
+
 -- | @subArc i j@ is the arc that is the intersection of @i@ and @j@.
 subArc :: Arc -> Arc -> Maybe Arc
 subArc (s, e) (s',e') | s'' < e'' = Just (s'', e'')
@@ -74,13 +80,30 @@
 eventStart :: Event a -> Time
 eventStart = fst . snd'
 
--- | The start time of the given @Event@
+-- | The original onset of the given @Event@
 eventOnset :: Event a -> Time
 eventOnset = fst . fst'
 
+-- | The original offset of the given @Event@
+eventOffset :: Event a -> Time
+eventOffset = snd . fst'
+
+-- | The arc of the given @Event@
+eventArc :: Event a -> Arc
+eventArc = snd'
+
 -- | The midpoint of an @Arc@
 midPoint :: Arc -> Time
 midPoint (s,e) = s + ((e - s) / 2)
 
 hasOnset :: Event a -> Bool
 hasOnset ((s,_), (s',_), _) = s == s'
+
+hasOffset :: Event a -> Bool
+hasOffset ((_,e), (_,e'), _) = e == e'
+
+onsetIn :: Arc -> Event a -> Bool
+onsetIn a e = isIn a (eventOnset e)
+
+offsetIn :: Arc -> Event a -> Bool
+offsetIn a e = isIn a (eventOffset e)
diff --git a/tidal.cabal b/tidal.cabal
--- a/tidal.cabal
+++ b/tidal.cabal
@@ -1,5 +1,5 @@
 name:                tidal
-version:             0.4.11
+version:             0.4.12
 synopsis:            Pattern language for improvised music
 -- description:         
 homepage:            http://yaxu.org/tidal/
