text:
from changes.config import db
from changes.testutils.cases import TestCase
from changes.models import CachedSnapshotImage
import changes.lib.snapshot_garbage_collection as gc

import datetime
import mock
import sqlalchemy

class TestSnapshotGCTestCase(TestCase):
    def setUp(self):
        """
        Used to fix the current time from datetime for the entirety of a
        single test.
        """
        self.mock_datetime = datetime.datetime.utcnow()
        super(TestSnapshotGCTestCase, self).setUp()

    def test_get_plans_for_cluster(self):
        project1 = self.create_project()
        project2 = self.create_project()
        plan1_1 = self.create_plan(project1)
        plan1_2 = self.create_plan(project1)
        plan2_1 = self.create_plan(project2)
        plan2_2 = self.create_plan(project2)

        self.create_step(plan1_1, data={'cluster': 'cluster1'})
        self.create_step(plan1_2, data={'cluster': 'cluster2'})
        self.create_step(plan2_1, data={'cluster': 'cluster1'})

        plans = gc.get_plans_for_cluster('cluster1')
        assert len(plans) == 2
        assert plan1_1 in plans
        assert plan2_1 in plans

    @mock.patch('changes.lib.snapshot_garbage_collection.get_plans_for_cluster')
    def test_cached_snapshot_images_gets_plans(self, get_plans):
        """More or less a metatest that verifies that the mocking
        is actually working.
        """
        project = self.create_project()
        plan = self.create_plan(project)
        snapshot = self.create_snapshot(project)

        snapshot_image = self.create_snapshot_image(snapshot, plan)
        cached_snapshot_image = self.create_cached_snapshot_image(snapshot_image)

        get_plans.return_value = set()
        gc.get_cached_snapshot_images('cluster')
        get_plans.assert_called_with('cluster')

    @mock.patch('changes.lib.snapshot_garbage_collection.get_plans_for_cluster')
    def test_cached_snapshot_images_no_plans(self, get_plans):
        project = self.create_project()
        plan = self.create_plan(project)
        snapshot = self.create_snapshot(project)

        snapshot_image = self.create_snapshot_image(snapshot, plan)
        cached_snapshot_image = self.create_cached_snapshot_image(snapshot_image)

        get_plans.return_value = set()

        assert gc.get_cached_snapshot_images('cluster') == []

    @mock.patch('changes.lib.snapshot_garbage_collection.get_current_datetime')
    @mock.patch('changes.lib.snapshot_garbage_collection.get_plans_for_cluster')
    def test_cached_snapshot_images_get_current_datetime(self, get_plans, get_current_datetime):
        """More or less a metatest that verifies that the mocking
        is actually working.
        """
        project = self.create_project()
        plan = self.create_plan(project)
        snapshot = self.create_snapshot(project)

        snapshot_image = self.create_snapshot_image(snapshot, plan)
        cached_snapshot_image = self.create_cached_snapshot_image(snapshot_image)

        get_plans.return_value = set()
        get_current_datetime.return_value = self.mock_datetime
        gc.get_cached_snapshot_images('cluster')
        get_current_datetime.assert_any_call()

    @mock.patch('changes.lib.snapshot_garbage_collection.get_current_datetime')
    @mock.patch('changes.lib.snapshot_garbage_collection.get_plans_for_cluster')
    def test_cached_snapshot_images_all(self, get_plans, get_current_datetime):
        """
        Tests the four fundamental cases for an image:
         - No expiration date
         - Not yet expired
         - Expired
         - Not part of the plans associated with the cluster
        """
        project = self.create_project()
        plan1 = self.create_plan(project)
        plan2 = self.create_plan(project)
        plan3 = self.create_plan(project)
        plan4 = self.create_plan(project)

        get_current_datetime.return_value = self.mock_datetime
        get_plans.return_value = {plan1, plan2, plan3}

        snapshot = self.create_snapshot(project)
        snapshot_image1 = self.create_snapshot_image(snapshot, plan1)
        snapshot_image2 = self.create_snapshot_image(snapshot, plan2)
        snapshot_image3 = self.create_snapshot_image(snapshot, plan3)
        snapshot_image4 = self.create_snapshot_image(snapshot, plan4)

        self.create_cached_snapshot_image(snapshot_image1, expiration_date=None)
        self.create_cached_snapshot_image(snapshot_image2,
                expiration_date=self.mock_datetime + datetime.timedelta(0, 1))
        self.create_cached_snapshot_image(snapshot_image3,
                expiration_date=self.mock_datetime - datetime.timedelta(0, 1))
        self.create_cached_snapshot_image(snapshot_image4, expiration_date=None)

        cached_snapshot_ids = [s.id for s in gc.get_cached_snapshot_images('cluster')]

        assert len(cached_snapshot_ids) == 2
        assert snapshot_image1.id in cached_snapshot_ids
        assert snapshot_image2.id in cached_snapshot_ids

    @mock.patch('changes.lib.snapshot_garbage_collection.get_current_datetime')
    def test_cache_snapshot_images_have_no_expiration(self, get_current_datetime):
        project = self.create_project()
        snapshot = self.create_snapshot(project)
        plans = [self.create_plan(project) for _ in range(3)]
        snapshot_images = [self.create_snapshot_image(snapshot, plan) for plan in plans]
        snapshot_image_ids = [image.id for image in snapshot_images]

        get_current_datetime.return_value = self.mock_datetime

        gc.cache_snapshot(snapshot)
        assert not db.session.query(CachedSnapshotImage.query.filter(
            CachedSnapshotImage.id.in_(snapshot_image_ids),
            CachedSnapshotImage.expiration_date != None,  # NOQA
        ).exists()).scalar()

    @mock.patch('changes.lib.snapshot_garbage_collection.get_current_datetime')
    def test_cache_snapshot_images_have_no_expiration_with_old(self, get_current_datetime):
        project = self.create_project()
        old_snapshot = self.create_snapshot(project)
        snapshot = self.create_snapshot(project)
        plans = [self.create_plan(project) for _ in range(3)]

        for plan in plans:
            old_snapshot_image = self.create_snapshot_image(old_snapshot, plan)
            self.create_cached_snapshot_image(old_snapshot_image)

        snapshot_images = [self.create_snapshot_image(snapshot, plan) for plan in plans]
        snapshot_image_ids = [image.id for image in snapshot_images]

        get_current_datetime.return_value = self.mock_datetime

        gc.cache_snapshot(snapshot)
        assert not db.session.query(CachedSnapshotImage.query.filter(
            CachedSnapshotImage.id.in_(snapshot_image_ids),
            CachedSnapshotImage.expiration_date != None,  # NOQA
        ).exists()).scalar()

    @mock.patch('changes.lib.snapshot_garbage_collection.get_current_datetime')
    def test_cache_snapshot_expires_old_snapshot(self, get_current_datetime):
        project = self.create_project()
        plans = [self.create_plan(project) for _ in range(3)]

        old_snapshot = self.create_snapshot(project)
        old_snapshot_images = [self.create_snapshot_image(old_snapshot, plan) for plan in plans]
        old_snapshot_image_ids = [image.id for image in old_snapshot_images]

        snapshot = self.create_snapshot(project)
        snapshot_images = [self.create_snapshot_image(snapshot, plan) for plan in plans]

        for old_snapshot_image in old_snapshot_images:
            self.create_cached_snapshot_image(old_snapshot_image)

        get_current_datetime.return_value = self.mock_datetime

        gc.cache_snapshot(snapshot)
        # Ensure that the old snapshots now expire sometime in the future
        assert not db.session.query(CachedSnapshotImage.query.filter(
            CachedSnapshotImage.id.in_(old_snapshot_image_ids),
            sqlalchemy.or_(
                CachedSnapshotImage.expiration_date == None,  # NOQA
                CachedSnapshotImage.expiration_date <= self.mock_datetime
            )
        ).exists()).scalar()

    @mock.patch('changes.lib.snapshot_garbage_collection.get_current_datetime')
    def test_recache_existing_cached_snapshot(self, get_current_datetime):
        """
        In some cases we may want to re-cache an existing snapshot that
        already has an entry in the cache. This should be transparent.
        """
        project = self.create_project()
        plan = self.create_plan(project)
        snapshot = self.create_snapshot(project)
        snapshot_image = self.create_snapshot_image(snapshot, plan)

        get_current_datetime.return_value = self.mock_datetime

        self.create_cached_snapshot_image(snapshot_image,
            expiration_date=self.mock_datetime - datetime.timedelta(0, 1))
        gc.cache_snapshot(snapshot)

        # The old snapshot now has no expiration
        cached_snapshot_image = CachedSnapshotImage.query.get(snapshot_image.id)
        assert cached_snapshot_image is not None
        assert cached_snapshot_image.expiration_date is None

        # and is the only snapshot in existence
        assert CachedSnapshotImage.query.count() == 1

    @mock.patch('changes.lib.snapshot_garbage_collection.get_current_datetime')
    def test_get_relevant_snapshot_images_simple(self, get_current_datetime):
        project = self.create_project()
        plan1 = self.create_plan(project)
        plan2 = self.create_plan(project)
        plan3 = self.create_plan(project)
        plan4 = self.create_plan(project)
        plan5 = self.create_plan(project)

        self.create_step(plan1, data={'cluster': 'cluster1'})
        self.create_step(plan2, data={'cluster': 'cluster1'})
        self.create_step(plan3, data={'cluster': 'cluster2'})
        self.create_step(plan4, data={})
        self.create_step(plan5)

        snapshot = self.create_snapshot(project)
        snapshot_image1 = self.create_snapshot_image(snapshot, plan1)
        snapshot_image2 = self.create_snapshot_image(snapshot, plan2)
        snapshot_image3 = self.create_snapshot_image(snapshot, plan3)
        snapshot_image4 = self.create_snapshot_image(snapshot, plan4)
        snapshot_image5 = self.create_snapshot_image(snapshot, plan5)

        get_current_datetime.return_value = self.mock_datetime
        gc.cache_snapshot(snapshot)

        images = gc.get_relevant_snapshot_images(snapshot.id)
        assert len(images) == 2
        assert 'cluster1' in images
        assert 'cluster2' in images
        assert len(images['cluster1']) == 2
        assert snapshot_image1 in images['cluster1']
        assert snapshot_image2 in images['cluster1']
        assert len(images['cluster2']) == 1
        assert snapshot_image3 in images['cluster2']

    @mock.patch('changes.lib.snapshot_garbage_collection.get_current_datetime')
    def test_get_relevant_snapshot_images_across_projects(self, get_current_datetime):
        project1 = self.create_project()
        project2 = self.create_project()
        plan1_1 = self.create_plan(project1)
        plan1_2 = self.create_plan(project1)
        plan2_1 = self.create_plan(project2)
        plan2_2 = self.create_plan(project2)

        self.create_step(plan1_1, data={'cluster': 'cluster1'})
        self.create_step(plan1_2, data={'cluster': 'cluster2'})
        self.create_step(plan2_1, data={'cluster': 'cluster2'})
        self.create_step(plan2_2, data={'cluster': 'cluster3'})

        snapshot1 = self.create_snapshot(project1)
        snapshot2 = self.create_snapshot(project2)

        snapshot_image1_1 = self.create_snapshot_image(snapshot1, plan1_1)
        snapshot_image1_2 = self.create_snapshot_image(snapshot1, plan1_2)
        snapshot_image2_1 = self.create_snapshot_image(snapshot2, plan2_1)
        snapshot_image2_2 = self.create_snapshot_image(snapshot2, plan2_2)

        get_current_datetime.return_value = self.mock_datetime
        gc.cache_snapshot(snapshot2)
        gc.cache_snapshot(snapshot1)

        images = gc.get_relevant_snapshot_images(snapshot1.id)
        assert len(images) == 2
        assert 'cluster1' in images
        assert 'cluster2' in images
        assert len(images['cluster1']) == 1
        assert snapshot_image1_1 in images['cluster1']
        assert len(images['cluster2']) == 2
        assert snapshot_image1_2 in images['cluster2']
        assert snapshot_image2_1 in images['cluster2']

    @mock.patch('changes.lib.snapshot_garbage_collection.get_current_datetime')
    def test_clear_expired(self, get_current_datetime):
        project = self.create_project()
        plan1 = self.create_plan(project)
        plan2 = self.create_plan(project)
        plan3 = self.create_plan(project)

        snapshot = self.create_snapshot(project)
        snapshot_image1 = self.create_snapshot_image(snapshot, plan1)
        snapshot_image2 = self.create_snapshot_image(snapshot, plan2)
        snapshot_image3 = self.create_snapshot_image(snapshot, plan3)

        # only the third image has expired. (This is a bit awkward as in a normal
        # situation all images for a snapshot would actually expire simultaneously)
        # since they would have been superceded at the same time, but its easier
        # to only use a single snapshot for testing and the behavior is independent
        # of what snapshot owns them.
        cached_snapshot_image1 = self.create_cached_snapshot_image(snapshot_image1)
        cached_snapshot_image2 = self.create_cached_snapshot_image(snapshot_image2,
            expiration_date=self.mock_datetime + datetime.timedelta(0, 1))
        cached_snapshot_image3 = self.create_cached_snapshot_image(snapshot_image3,
            expiration_date=self.mock_datetime - datetime.timedelta(0, 1))

        get_current_datetime.return_value = self.mock_datetime
        gc.clear_expired()

        assert len(CachedSnapshotImage.query.all()) == 2
        assert CachedSnapshotImage.query.get(cached_snapshot_image1.id) is not None
        assert CachedSnapshotImage.query.get(cached_snapshot_image2.id) is not None
        assert CachedSnapshotImage.query.get(cached_snapshot_image3.id) is None


text:
alter table `test_audit`.`TABLE1`
  change column `col1` `col1` timestamp null default now()
;

redpajama_set_name: RedPajamaGithub


text:
<?php

namespace App\Http\Controllers\Auth;

use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class RegisterValidationController extends Controller
{
    /**
     * responds to an ajax request to check if a email is taken
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function email(Request $request)
    {
        $this->validate($request, [
            'email' => 'email'
        ]);
        $count = (User::where('email', $request->input('email'))->count() === 0) ? true : false;

        return response()->json([
            'email' => $count
        ], 200);
    }

    /**
     * responds to an ajax request to check if a user name is taken
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function username(Request $request)
    {
        $count = (User::where('username', $request->input('username'))->count() === 0) ? true : false;

        return response()->json([
            'username' => $count
        ], 200);
    }
}


text:
import Graphics.UI.Gtk -- hiding (fill)
import qualified Graphics.Rendering.Cairo as C

import Data.Complex
import Control.Monad (when, forM_)
import Data.IORef

import qualified Copernicus as Cop
import qualified Palette

---------------------------------------------------------------------------------------------------
-- Types
---------------------------------------------------------------------------------------------------
-- TODO: One trail per body ([[Complex Double]]) (?)
data World = World { frame :: Int, size :: (Int, Int), bodies :: [Cop.Body Double], trails :: [[Complex Double]] } deriving Show

---------------------------------------------------------------------------------------------------
-- Data
---------------------------------------------------------------------------------------------------
animate = True --
π       = pi   -- :: Double -- TODO: Polymorphic (?)
τ       = 2*π  -- :: Double -- TODO: Polymorphic (?)
fps     = 30   :: Int

v = 2.0:+0.5 --40.0 :+ 20.0
g = 0.0:+(-9.82) --0.0 :+ (-9.82)

bodies' = map (\ (p', v', g') -> Cop.Body p' v' g') [(0.0:+1.0, v, g), (1.0:+0.0, (2.0):+1.50, g), (3.0:+(2.80), v, g), (2.5:+1.92, v, g)]

---------------------------------------------------------------------------------------------------
-- Functions
---------------------------------------------------------------------------------------------------
-- |
mainGTK :: IO ()
mainGTK = do
    initGUI
    window <- windowNew

    frame  <- frameNew
    canvas <- drawingAreaNew
    containerAdd frame canvas

    set window [ containerChild := frame]
    windowSetDefaultSize window 650 650

    widgetAddEvents canvas [PointerMotionMask]

    widgetShowAll window

    -- Assets
    -- planets <- C.withImageSurfaceFromPNG "assets/planets.png" $ \surface -> surface
    planets <- C.liftIO $ C.imageSurfaceCreateFromPNG "assets/planets.png"

    -- Animation
    (w,h)    <- widgetSize window
    worldVar <- newIORef $ World { frame=0, size=(w,h), bodies=bodies', trails=map (const []) bodies' } --
    when animate $ timeoutAdd (onanimate worldVar canvas) (1000 `div` fps) >> return ()

    -- Events
    canvas `on` draw $ (C.liftIO $ readIORef worldVar) >>= flip render planets -- readIORef worldVar >>= \ w -> render (fromIntegral w) (fromIntegral h) w
    canvas `on` motionNotifyEvent $ onmousemove

    window `on` configureEvent $ onresize window worldVar
    window `on` deleteEvent $ C.liftIO mainQuit >> return False -- TODO: Uhmmm... what?
    window `on` keyPressEvent $ onkeypress

    mainGUI

-- |
-- TODO: Make polymorphic
widgetSize :: WidgetClass self => self -> IO (Int, Int)
widgetSize widget = do
    w <- widgetGetAllocatedWidth widget
    h <- widgetGetAllocatedHeight widget
    return (w, h)

-- |
-- onresize :: WidgetClass self => self -> IORef World -> IO Bool
onresize window worldVar = do
    sz <- eventSize
    C.liftIO $ modifyIORef worldVar $ \ wd -> wd { size=sz }
    return True

-- |
-- onkeypress ::
onkeypress = do
    key <- eventKeyName
    C.liftIO $ print key
    return True

-- |
-- onmousemove ::
onmousemove = do
    when False $ do
        (mx,my) <- eventCoordinates
        C.liftIO $ print (mx,my)
    return False

-- Animation --------------------------------------------------------------------------------------
-- |
onanimate :: IORef World -> DrawingArea -> IO Bool
onanimate world canvas = do
    -- withMVar var print
    modifyIORef world update
    widgetQueueDraw canvas
    return True

-- |
-- TODO: Refactor, make readable (State monad, lenses)
update :: World -> World
update w@(World { frame=f, bodies=bodies'' } ) = w { frame=f+1,
                                                                       bodies=map (Cop.animate (1.0/fromIntegral fps)) bodies'',
                                                                       trails=map (\ (trail, (Cop.Body p _ _)) -> take 50 $ p:trail) $ zip (trails w) bodies'' }

-- | The time elapsed (in seconds)
-- TODO: Polymorphic (?)
elapsed :: World -> Double
elapsed world = (fromIntegral $ frame world) * 1.0/fromIntegral fps

-- Rendering --------------------------------------------------------------------------------------
-- |
-- TODO: Make polymorphic
-- TODO: Apply coordinate transformations (to World perhaps; make world a monad?)
renderBody :: Cop.Body Double -> C.Render ()
renderBody (Cop.Body (x:+y) (vx:+vy) (ax:+ay)) = do
    -- C.arc (x/3 + 200) (y/3 + 200) 12 0 τ
    -- Body
    C.arc x y 12 0 τ
    C.setSourceRGBA 0.5 0.2 0.3 1.0
    C.fill

    -- Vector arrows
    C.setSourceRGBA 0.12 0.05 1 0.8
    renderArrow (x:+y) (x:+(y+vy*10)) (abs vy*10*0.8) 5 12

    C.setSourceRGBA 1 0.05 0.12 0.8
    renderArrow (x:+y) ((x+vx*10):+y) (abs vx*10*0.8) 5 12

-- |
renderWorld :: World -> C.Render ()
renderWorld world = do

    -- X-axis
    vectorise C.moveTo $ toScreenCoords world ((-5):+0)
    vectorise C.lineTo $ toScreenCoords world (  5:+0)
    C.setSourceRGBA 1 0 0 0.8
    C.stroke

    -- Y-axis
    vectorise C.moveTo $ toScreenCoords world (0:+(-5))
    vectorise C.lineTo $ toScreenCoords world (0:+  5)
    C.setSourceRGBA 0 1 0 0.8
    C.stroke

    -- Trail(s)
    -- TODO: Better way of doing 2D 'loops'
    forM_ (zip [Palette.green, Palette.red, Palette.blue] $ trails world) $ \(fill, trail) -> do
        forM_ trail $ \ dot -> do
            -- C.setSourceRGBA (cos $ 1.3*c) (sin $ 5*c) 0.2 1.0
            Palette.choose fill
            renderCircle (toScreenCoords world dot) 3

    -- Render bodies
    forM_ (bodies world) $ renderBody . bodyToScreenCoords world

-- |
render :: World -> C.Surface -> C.Render ()
render world planets = do

    --
    when False $ do
        C.moveTo 16 44
        C.liftIO $ C.fontOptionsCreate >>= flip C.fontOptionsSetAntialias C.AntialiasSubpixel
        C.selectFontFace "Helvetica" C.FontSlantNormal C.FontWeightNormal
        C.setFontSize 30
        C.setSourceRGBA 0.62 0.62 0.62 0.7
        C.showText "Copernicus"

        extents <- C.textExtents "Copernicus"

        C.setFontSize 14
        C.setSourceRGBA 0.3 0.3 0.3 1.0
        C.moveTo 16 $ 44 + C.textExtentsHeight extents + 5
        C.showText "Jonatan H Sundqvist 2015"

    --
    renderGrid 10 10 $ fromIntegral (fst $ size world) / 10

    -- Image
    when False $ do
        {-action <- C.liftIO . C.withImageSurfaceFromPNG "assets/planets.png" $ (\surface -> return $
            do C.setSourceSurface surface 20 20 >> C.paint)-}
        -- planets <- C.liftIO $ C.imageSurfaceCreateFromPNG "assets/planets.png"
        C.setSourceSurface planets 50 50
        C.rectangle 320 310 250 250
        C.clip
        C.paint
        C.resetClip

    -- Arrow
    -- renderArrow (40:+40) (200:+120) 80 20 40
    -- TODO: Don't hard-code arrow values
    when False $ do
        forM_ (bodies world) $ \ body -> do
            let (from, to, len, width, headWidth) = (40:+50, let (Cop.Body p _ _) = body in toScreenCoords world p, 0.78 * magnitude (to-from), 40, 88)
            let thearrow = arrow from to len width headWidth
            renderArrow from to len width headWidth

            -- Arrow vertices
            C.setSourceRGBA 0 0 0 1.0
            forM_ thearrow (flip renderCircle 5)

            C.setSourceRGBA 0 0 0 1.0
            forM_ (zip [1..] thearrow) $ \(n, p) -> vectorise C.moveTo (p+(6:+6)) >> C.showText (show n)

            -- Arrow symmetry line
            vectorise C.moveTo from
            vectorise C.lineTo to
            C.setSourceRGBA 0 0 0 1.0
            C.stroke

    -- Shifting polygons
    when False $ do
        let sides       = 3 + (flip mod 10 . flip div fps $ frame world)
            radius mini = (+mini) . (*35.0) . (+1.0) . sin  $ elapsed world
            origin      = (w/2):+(h/2)
            fill        = False in forM_ [(10, (0.0, 0.5, 0, 1.0)),
                                          (30, (0.3, 0.0, 0.8, 1.0)),
                                          (50, (0.0, 0.7, 0.2, 1.0)),
                                          (70, (0.8, 0.8, 0.1, 1.0))] $ \(mini, colour) -> renderPolygon sides (radius mini) origin colour fill

    --  Bouncing balls
    renderWorld world

    -- Circle carousel
    when False $ do
        renderCircleArc 10 origin spread radius begin τ
    where count  = 10
          origin = (w/2):+(h/2)
          spread = 50 + 50 * (1 + sin (τ * rpm * elapsed world)) -- 134      -- Radius of the big circle (pixels?)
          radius = 20       -- Radius of a small circle (pixels?)
          (w,h)  = let (w', h') = size world in (fromIntegral w', fromIntegral h')
          rpm    = 0.3      --
          begin  = τ * rpm * elapsed world

-- |
renderGrid :: Int -> Int -> Double -> C.Render ()
renderGrid cols rows size = do
    sequence_ [ tilePath cl rw >> C.fill   | cl <- [0..(cols-1)], rw <- [0..(rows-1)] ] -- Tiles
    sequence_ [ tilePath cl rw >> C.stroke | cl <- [0..(cols-1)], rw <- [0..(rows-1)] ] -- Borders
    -- TODO: Figure out how to use fill AND stroke
    where chooseColour cl rw = if (cl `mod` 2) == (rw `mod` 2) then 0.3 else 0.75 -- TODO: This should be a utility function
          tilePath cl rw     = C.rectangle (fromIntegral cl*size) (fromIntegral rw*size) size size >> C.setSourceRGBA 0.22 0.81 (chooseColour cl rw) 0.32

-- |
renderArrow :: Complex Double -> Complex Double -> Double -> Double -> Double -> C.Render ()
renderArrow from to sl sw hw = do
    let (first:rest) = closePath $ arrow from to sl sw hw
    vectorise C.moveTo first
    forM_ rest $ vectorise C.lineTo

    -- C.setSourceRGBA 1 0.8 0.15 1.0
    C.setLineWidth 3
    C.stroke

-- |
-- TODO: Add arguments for colour, stroke, etc.
-- TODO: Make polymorphic
renderPolygon :: Int -> Double -> Complex Double -> (Double, Double, Double, Double) -> Bool -> C.Render ()
renderPolygon sides radius origin (r,g,b,a) filled = do
    -- TODO: Refine 'wrap-around logic'
    C.moveTo fx fy
    forM_ rest $ \(x:+y) -> C.lineTo x y

    C.setSourceRGBA r g b a
    C.setLineWidth 12
    if filled
        then C.fill
        else C.stroke
    where ((fx:+fy):rest) = polygon sides radius origin ++ [fx:+fy]

-- |
-- TODO: Options for fill/stroke, colour, width, etc.
renderCircle :: Complex Double -> Double -> C.Render ()
renderCircle (cx:+cy) radius = do
    C.arc cx cy radius 0 τ
    C.fill

-- |
-- TODO: Options for colour, width, closed/open, etc.
renderPath :: [Complex Double] -> C.Render ()
renderPath (p:ath) = do
    vectorise C.moveTo p
    forM_ ath $ vectorise C.lineTo
    C.stroke

-- |
-- Ugh, I hate underscores so much
-- TODO: Make polymorphic
renderCircleArc :: Int -> Complex Double -> Double -> Double -> Double -> Double -> C.Render ()
renderCircleArc
    count    -- Number of small circles
    (ox:+oy) -- Centre of the 'arc' (pixels?)
    spread   -- Radius of the 'arc'
    radius   -- Radius of the small circles
    begin    -- Start angle of the arc
    extent = forM_ [1..count] $ \ n -> do
        let n' = fromIntegral n
        let θ  = begin + n'*extent/fromIntegral count
        C.arc (ox - spread*cos θ) (oy - spread*sin θ) radius 0 τ
        C.setSourceRGBA (0.5 * (1 + sin θ)) (0.1*n') (1/n') 0.95
        C.fill

-- Geometry ---------------------------------------------------------------------------------------
-- |
-- TODO: Start angle
-- TODO: Invalid arguments (eg. sides < 3) (use Maybe?)
-- TODO: Make polymorphic
-- TODO: Move to geometry section
-- polygon :: (Floating f, RealFloat f) => Int -> f -> Complex f -> [Complex f]
polygon :: Int -> Double -> Complex Double -> [Complex Double]
polygon sides radius origin = [ let θ = arg n in origin + ((radius * cos θ):+(radius * sin θ)) | n <- [1..sides]]
    where arg n = fromIntegral n * (2*π)/fromIntegral sides

-- |
-- TODO: Simplify and expound comments
arrow :: Complex Double -> Complex Double -> Double -> Double -> Double -> [Complex Double]
arrow from to sl sw hw = [from     + straight (sw/2), --
                          shaftEnd + straight (sw/2), --
                          shaftEnd + straight (hw/2), --
                          to,                         --
                          shaftEnd - straight (hw/2), --
                          shaftEnd - straight (sw/2), --
                          from     - straight (sw/2)]  --
    where along a b distance = a + (mkPolar distance . snd . polar $ b-a) -- Walk distance along the from a to b
          normal a b = let (mag, arg) = polar (b-a) in mkPolar mag (arg+π/2)
          shaftEnd = along from to sl --
          straight = along (0:+0) (normal from to) -- Vector perpendicular to the centre line
          -- shaftWidth = along (0:+0) (normal a b) (sw/2) -- Half of shaft width (vector relative to symmetry line)
          -- headWidth  = along (0:+0) (normal a b) (hw/2)

-- Utilities --------------------------------------------------------------------------------------
-- |
vectorise :: (Double -> Double -> a) -> Complex Double -> a
vectorise f (re:+im) = f re im

-- |
-- TODO: Unsafe, use Maybe (?)
closePath :: [Complex Double] -> [Complex Double]
closePath path = path ++ [head path]

-- Transforms a vector from one coordinate space to another
-- by applying the given scaling and translation
-- Useful for converting between simulation and screen coordinates
-- TODO: Types for representing coordinate systems
-- TODO: Use matrix instead (scale and translate should be applied in reverse order when undoing the transformation)
-- TODO: Add undo parameter (?)
-- TODO: Pure function, move to Copernicus.hs or use Cairo matrix functions
transform :: Complex Double -> Complex Double -> Complex Double -> Complex Double
transform scaling translation = scale scaling . translate translation

-- |
scale :: Complex Double -> Complex Double -> Complex Double
scale (sx:+sy) (x:+y) = (sx*x):+(sy*y)

-- |
translate :: Complex Double -> Complex Double -> Complex Double
translate = (+)

-- |
toScreenCoords :: World -> Complex Double -> Complex Double
toScreenCoords world = transform (sx:+sy) translation
    where (w, h)   = let (w', h') = size world in (fromIntegral w', fromIntegral h')
          (sx:+sy)    = (w/10):+(-h/10)
          translation = w/(2*sx):+h/(2*sy)

-- | TODO: Implement :/
-- TODO: Dotwise application for Complex numbers
-- TODO: Don't hard-code the world-size of the canvas (currently 10-by-10)
toWorldCoords :: World -> Complex Double -> Complex Double
toWorldCoords world = translate (-translation) . scale (sx**(-1):+sy**(-1))
    where (w, h) = let (w', h') = size world in (fromIntegral w', fromIntegral h')
          (sx:+sy)    = (w/10):+(-h/10)
          translation = (w/(2*sx)):+(h/(2*sy))

-- |
bodyToScreenCoords :: World -> Cop.Body Double -> Cop.Body Double
bodyToScreenCoords world (Cop.Body p v' a') = Cop.Body (toScreenCoords world p) v' a' -- TODO: Make transformation less ad-hoc

---------------------------------------------------------------------------------------------------
-- Entry point
---------------------------------------------------------------------------------------------------
main :: IO ()
main = mainGTK


text:
import { Injectable } from '@angular/core';
import { ConfigurationData } from './data';

@Injectable()
export class ConfigurationService {

    public getData(): ConfigurationData {
        return {
            api: sessionStorage.getItem('api'),
            token: localStorage.getItem('token')
        };
    }
}


text:
var Rx = require('rx');

var source1 = Rx.Observable
  .interval(500)
;
var source2 = Rx.Observable
  .interval(100)
  .pausable()
;

source1.subscribe(
  function(callCount) {
    source2.resume();
    console.log('source1:', callCount);
  },
  function (err) {
    console.log('Error(source1): ' + err);
  }
);
source2.subscribe(
  function(callCount) {
    source2.pause();
    console.log('source2:', callCount);
  },
  function (err) {
    console.log('Error(source2): ' + err);
  }
);

source2.resume();


text:
package com.planet_ink.coffee_mud.Abilities.Misc;
import com.planet_ink.coffee_mud.Abilities.StdAbility;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.core.*;
import com.planet_ink.coffee_mud.core.collections.*;
import com.planet_ink.coffee_mud.Abilities.interfaces.*;
import com.planet_ink.coffee_mud.Areas.interfaces.*;
import com.planet_ink.coffee_mud.Behaviors.interfaces.*;
import com.planet_ink.coffee_mud.CharClasses.interfaces.*;
import com.planet_ink.coffee_mud.Commands.interfaces.*;
import com.planet_ink.coffee_mud.Common.interfaces.*;
import com.planet_ink.coffee_mud.Exits.interfaces.*;
import com.planet_ink.coffee_mud.Items.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.*;
import com.planet_ink.coffee_mud.Locales.interfaces.*;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;

import java.util.*;

public class BrokenLimbs extends StdAbility implements LimbDamage, HealthCondition
{
	@Override
	public String ID()
	{
		return "BrokenLimbs";
	}

	private final static String	localizedName	= CMLib.lang().L("Broken Limbs");

	@Override
	public String name()
	{
		return localizedName;
	}

	protected int						HEALING_TICKS	= (int) ((TimeManager.MILI_MINUTE * 10) / CMProps.getTickMillis());
	protected List<String>				brokenLimbsList	= null;
	private int[]						brokenParts		= new int[Race.BODY_PARTS];
	private final Map<String, int[]>	setBones		= new STreeMap<String, int[]>();

	@Override
	public String displayText()
	{
		final List<String> affectedLimbs = affectedLimbNameSet();
		if(affectedLimbs.size()==0)
			return "";
		final List<String> limbConditionStrs = new XVector<String>(affectedLimbs);
		for(int i=0;i<limbConditionStrs.size();i++)
		{
			final String limb=limbConditionStrs.get(i);
			final int[] condition = setBones.get(limb);
			if(condition != null)
			{
				final double pct = CMath.div(condition[0], HEALING_TICKS) * 100.0;
				limbConditionStrs.set(i, limb + " (healing "+(100-Math.round(pct))+"%)");
			}
		}
		return "(Broken "+CMLib.english().toEnglishStringList(limbConditionStrs)+")";
	}

	@Override
	public String getHealthConditionDesc()
	{
		return "Broken "+CMLib.english().toEnglishStringList(affectedLimbNameSet());
	}

	@Override
	protected int canAffectCode()
	{
		return CAN_MOBS;
	}

	@Override
	protected int canTargetCode()
	{
		return CAN_MOBS;
	}

	@Override
	public int abstractQuality()
	{
		return Ability.QUALITY_INDIFFERENT;
	}

	@Override
	public boolean putInCommandlist()
	{
		return false;
	}

	private static final String[]	triggerStrings	= I(new String[] { "BREAKLIMB" });

	@Override
	public String[] triggerStrings()
	{
		return triggerStrings;
	}

	@Override
	public int classificationCode()
	{
		return Ability.ACODE_SKILL | Ability.DOMAIN_ANATOMY;
	}

	@Override
	public int usageType()
	{
		return USAGE_MOVEMENT | USAGE_MANA;
	}

	public final static boolean[] validBrokens ={true,//antenea
												 false,//eye
												 false,//ear
												 false,//head
												 false,//neck
												 true,//arm
												 true,//hand
												 false,//torso
												 true,//leg
												 true,//foot
												 true,//nose
												 false,//gills
												 false,//mouth
												 false,//waist
												 true,//tail
												 true//wing
												 };

	@Override
	public void executeMsg(Environmental host, CMMsg msg)
	{
		if(affected instanceof MOB)
		{
			final MOB M = (MOB)affected;
			if((msg.target()==M)
			&&((msg.targetMinor()==CMMsg.TYP_LOOK)||(msg.targetMinor()==CMMsg.TYP_EXAMINE))
			&&(CMLib.flags().canBeSeenBy(M,msg.source())))
			{
				final String s=CMLib.utensils().niceCommaList(affectedLimbNameSet(),true);
				if(s.length()>0)
					msg.addTrailerMsg(CMClass.getMsg(msg.source(),null,null,
									  CMMsg.MSG_OK_VISUAL,L("\n\r@x1 has broken @x2 @x3.\n\r",M.name(msg.source()),M.charStats().hisher(),s),
									  CMMsg.NO_EFFECT,null,
									  CMMsg.NO_EFFECT,null));
			}
			if((msg.sourceMinor()==CMMsg.TYP_DEATH)&&(msg.amISource(M)))
			{
				M.delEffect(this);
				M.recoverCharStats();
				M.recoverPhyStats();
				M.recoverMaxState();
			}
			if(msg.amITarget(M)&&(msg.targetMinor()==CMMsg.TYP_HEALING))
			{
				final int amount=msg.value();
				if((amount>0)
				&&(msg.tool() instanceof Ability)
				&&(CMath.bset(((Ability)msg.tool()).flags(),Ability.FLAG_HEALINGMAGIC))
				&&(!CMath.bset(((Ability)msg.tool()).flags(),Ability.FLAG_UNHOLY)))
				{
					startAllLimbsHealing();
					double healAmount = CMath.div(amount,M.maxState().getHitPoints());
					if(healAmount < 0.05)
						healAmount = 0.05;
					progressLimbHealing(M, (int)Math.round(CMath.mul(HEALING_TICKS, healAmount)));
				}
			}
		}
		super.executeMsg(host,msg);
	}

	@Override
	public void affectPhyStats(Physical affected, PhyStats affectableStats)
	{
		super.affectPhyStats(affected,affectableStats);
		affectedLimbNameSet();
		if(affected instanceof MOB)
		{
			final MOB mob=(MOB)affected;
			if((brokenParts[Race.BODY_LEG]<0)&&(mob.getWearPositions(Wearable.WORN_LEGS)==0))
			{
				if((brokenParts[Race.BODY_ARM]<0)&&(mob.getWearPositions(Wearable.WORN_ARMS)==0))
					affectableStats.setSensesMask(affectableStats.sensesMask()|PhyStats.CAN_NOT_MOVE);
				affectableStats.setDisposition(affectableStats.disposition()|PhyStats.IS_SITTING);
			}
		}
	}

	@Override
	public void affectCharStats(MOB affected, CharStats affectableStats)
	{
		super.affectCharStats(affected,affectableStats);
		affectedLimbNameSet();
		for(int i=0;i<brokenParts.length;i++)
			if((brokenParts[i]!=0)
			&&((i==Race.BODY_ARM)||(i==Race.BODY_LEG)||(i==Race.BODY_FOOT)||(i==Race.BODY_HAND)))
				affectableStats.alterBodypart(i,brokenParts[i]);
	}

	@Override
	public void affectCharState(MOB affected, CharState affectableState)
	{
		super.affectCharState(affected,affectableState);
		affectedLimbNameSet();
		if(brokenParts[Race.BODY_LEG]<0)
		{
			if(affected.getWearPositions(Wearable.WORN_LEGS)==0)
				affectableState.setMovement(affectableState.getMovement()/8);
			else
				affectableState.setMovement(affectableState.getMovement()/4);
		}
		else
		if(brokenParts[Race.BODY_FOOT]<0)
		{
			if(affected.getWearPositions(Wearable.WORN_FEET)==0)
				affectableState.setMovement(affectableState.getMovement()/4);
			else
				affectableState.setMovement(affectableState.getMovement()/2);
		}
	}

	@Override
	public boolean okMessage(Environmental host, CMMsg msg)
	{
		if(!super.okMessage(host, msg))
			return false;
		if(msg.source() == affected)
			switch(msg.sourceMinor())
			{
			case CMMsg.TYP_STAND:
				{
					final MOB mob=msg.source();
					if((brokenParts[Race.BODY_LEG]<0)&&(mob.getWearPositions(Wearable.WORN_LEGS)==0)&&(!CMLib.flags().isSleeping(mob)))
					{
						mob.tell(L("Your legs are broken!"));
						return false;
					}
					break;
				}
			case CMMsg.TYP_ADVANCE: case CMMsg.TYP_RETREAT:
			{
				final MOB mob=msg.source();
				if((brokenParts[Race.BODY_LEG]<0)&&(!CMLib.flags().isSleeping(mob)))
				{
					mob.tell(L("Your broken leg made movement too painful this time.  Try again."));
					return false;
				}
				break;
			}
			case CMMsg.TYP_WIELD:
			{
				final MOB mob=msg.source();
				if((brokenParts[Race.BODY_HAND]<0)&&(mob.getWearPositions(Wearable.WORN_WIELD)==0))
				{
					mob.tell(L("Your weapon hand is broken!"));
					return false;
				}
				break;
			}
			case CMMsg.TYP_WEAPONATTACK:
			{
				final MOB mob=msg.source();
				if(((brokenParts[Race.BODY_HAND]<0)||(brokenParts[Race.BODY_ARM]<0))&&(msg.tool() == mob.fetchWieldedItem()))
				{
					mob.tell(L("Your broken limbs make the attack impossible!"));
					return false;
				}
				break;
			}
			}
		return true;
	}

	@Override
	public void unInvoke()
	{
		// undo the affects of this spell
		if(!(affected instanceof MOB))
			return;
		final MOB mob=(MOB)affected;

		if((mob.isMonster())&&(mob.amDead())&&(!canBeUninvoked()))
			super.canBeUninvoked=true;

		super.unInvoke();

		if(canBeUninvoked())
			if((mob.location()!=null)&&(!mob.amDead()))
				mob.location().show(mob,null,CMMsg.MSG_OK_VISUAL,L("<S-YOUPOSS> broken limbs have been healed."));
	}

	public MOB getTarget(MOB mob, List<String> commands, Environmental givenTarget, boolean quiet)
	{
		String targetName=CMParms.combine(commands,0);
		MOB target=null;
		if((givenTarget!=null)&&(givenTarget instanceof MOB))
			target=(MOB)givenTarget;
		else
		if((targetName.length()==0)&&(mob.isInCombat())&&(abstractQuality()==Ability.QUALITY_MALICIOUS)&&(mob.getVictim()!=null))
		   target=mob.getVictim();
		else
		if((targetName.length()==0)&&(abstractQuality()!=Ability.QUALITY_MALICIOUS))
			target=mob;
		else
		if(targetName.length()>0)
		{
			target=mob.location().fetchInhabitant(targetName);
			if(target==null)
			{
				final Environmental t=mob.location().fetchFromRoomFavorItems(null,targetName);
				if((t!=null)&&(!(t instanceof MOB)))
				{
					if(!quiet)
						mob.tell(mob,target,null,L("You can't do that to <T-NAMESELF>."));
					return null;
				}
			}
		}

		if(target!=null)
			targetName=target.name();

		if((target==null)||((!CMLib.flags().canBeSeenBy(target,mob))&&((!CMLib.flags().canBeHeardMovingBy(target,mob))||(!target.isInCombat()))))
		{
			if(!quiet)
			{
				if(targetName.trim().length()==0)
					mob.tell(L("You don't see them here."));
				else
					mob.tell(L("You don't see '@x1' here.",targetName));
			}
			return null;
		}
		return target;
	}

	protected void startAllLimbsHealing()
	{
		for(String limb : affectedLimbNameSet())
			if(!setBones.containsKey(limb))
				setBones.put(limb, new int[]{HEALING_TICKS});
	}

	@Override
	public void setMiscText(String text)
	{
		if(text.toUpperCase().startsWith("+"))
		{
			if(text.toUpperCase().startsWith("+SETBONES"))
			{
				startAllLimbsHealing();
			}
		}
		else
		{
			super.setMiscText(text);
			brokenLimbsList=null;
		}
	}

	@Override
	public List<String> affectedLimbNameSet()
	{
		if(brokenLimbsList!=null)
			return brokenLimbsList;
		brokenLimbsList=new Vector<String>();
		if(affected==null)
			return brokenLimbsList;
		if((!(affected instanceof MOB))&&(!(affected instanceof DeadBody)))
		   return brokenLimbsList;
		brokenLimbsList=CMParms.parseSemicolons(text(),true);
		brokenParts=new int[Race.BODY_PARTS];
		boolean right=false;
		boolean left=false;
		Integer code=null;
		for(int v=0;v<brokenLimbsList.size();v++)
		{
			final String s=brokenLimbsList.get(v).toUpperCase();
			left=s.startsWith("LEFT ");
			right=s.startsWith("RIGHT ");
			code=Race.BODYPARTHASH.get(s.substring(right?6:left?5:0).trim());
			if(code!=null)
				brokenParts[code.intValue()]--;
		}
		return brokenLimbsList;
	}

	public List<String> completeBrokenLimbNameSet(Environmental E)
	{
		final Vector<String> V=new Vector<String>();
		if(!(E instanceof MOB))
			return V;
		final MOB M=(MOB)E;
		final int[] limbs=M.charStats().getMyRace().bodyMask();
		for(int i=0;i<limbs.length;i++)
		{
			if((limbs[i]>0)&&(validBrokens[i]))
			{
				if(limbs[i]==1)
					V.addElement(Race.BODYPARTSTR[i].toLowerCase());
				else
				if(limbs[i]==2)
				{
					V.addElement("left "+Race.BODYPARTSTR[i].toLowerCase());
					V.addElement("right "+Race.BODYPARTSTR[i].toLowerCase());
				}
				else
				for(int ii=0;ii<limbs[i];ii++)
					V.addElement(Race.BODYPARTSTR[i].toLowerCase());
			}
		}
		return V;
	}

	protected void progressLimbHealing(final CMObject obj, final int thisMuch)
	{
		for(final String limb : setBones.keySet())
		{
			final int[] ticksRemaining = setBones.get(limb);
			ticksRemaining[0] -= thisMuch;
			if(ticksRemaining[0] <= 0)
			{
				setBones.remove(limb);
				if(obj instanceof MOB)
					restoreLimb(limb);
			}
		}
	}

	@Override
	public boolean tick(Tickable ticking, int tickID)
	{
		if(tickID == Tickable.TICKID_MOB)
		{
			progressLimbHealing(ticking, 1);
		}
		return super.tick(ticking, tickID);
	}

	@Override
	public List<String> unaffectedLimbSet()
	{
		affectedLimbNameSet();
		final List<String> remains=new Vector<String>();
		if(!(affected instanceof MOB))
			return remains;
		final MOB M=(MOB)affected;
		final int[] limbs=new int[Race.BODY_PARTS];
		final List<String> affected=affectedLimbNameSet();
		for(int i=0;i<limbs.length;i++)
		{
			limbs[i]=M.charStats().getBodyPart(i);
			if((limbs[i]>0)
			&&(validBrokens[i]))
			{
				if(limbs[i]-brokenParts[i]==1)
				{
					if(!affected.contains(Race.BODYPARTSTR[i].toLowerCase()))
						remains.add(Race.BODYPARTSTR[i].toLowerCase());
				}
				else
				if(limbs[i]-brokenParts[i]==2)
				{
					if(!affected.contains("left "+Race.BODYPARTSTR[i].toLowerCase()))
						remains.add("left "+Race.BODYPARTSTR[i].toLowerCase());
					if(!affected.contains("right "+Race.BODYPARTSTR[i].toLowerCase()))
						remains.add("right "+Race.BODYPARTSTR[i].toLowerCase());
				}
				else
				for(int ii=0;ii<limbs[i];ii++)
					remains.add(Race.BODYPARTSTR[i].toLowerCase());
			}
		}
		final Amputation A=(Amputation)M.fetchEffect("Amputation");
		if(A!=null)
		{
			final List<String> missing=A.affectedLimbNameSet();
			for(String limb : missing)
				remains.remove(limb);
		}
		return remains;
	}

	@Override
	public void restoreLimb(String gone)
	{
		if (affected != null)
		{
			if (affected instanceof MOB)
			{
				((MOB)affected).location().show(((MOB)affected), null, CMMsg.MSG_OK_VISUAL, L("^G<S-YOUPOSS> @x1 is now mended.^?",gone));
			}
			else
			if ((affected instanceof DeadBody)
			&& (((Item)affected).owner() instanceof Room))
			{
				((Room)((Item)affected).owner()).showHappens(CMMsg.MSG_OK_VISUAL, L("^G@x1's @x2 is now mended.^?",affected.name(),gone));
			}
		}

		final List<String> theRest = affectedLimbNameSet();
		if (theRest.contains(gone))
			theRest.remove(gone);
		if((theRest.size()==0)&&(affected!=null))
			affected.delEffect(this);
		else
		{
			setMiscText(CMParms.combineWith(theRest, ';'));
		}
	}

	@Override
	public Item damageLimb(String brokenLimbName)
	{
		if(affected!=null)
		{
			if(affected instanceof MOB)
			{
				boolean success=((MOB)affected).location().show(((MOB)affected),this,CMMsg.MSG_OK_VISUAL,L("^G<S-YOUPOSS> @x1 breaks!^?",brokenLimbName));
				if(!success)
					return null;
			}
			else
			if((affected instanceof DeadBody)
			&&(((Item)affected).owner()!=null)
			&&(((Item)affected).owner() instanceof Room))
			{
				((Room)((Item)affected).owner()).showHappens(CMMsg.MSG_OK_VISUAL,L("^G@x1's @x2 breaks!^?",affected.name(),brokenLimbName));
			}
		}
		setMiscText(text()+brokenLimbName+";");
		return null;
	}

	@Override
	public boolean invoke(MOB mob, List<String> commands, Physical givenTarget, boolean auto, int asLevel)
	{
		String choice="";
		if(givenTarget!=null)
		{
			if((commands.size()>0)&&((commands.get(0)).equals(givenTarget.name())))
				commands.remove(0);
			choice=CMParms.combine(commands,0);
			commands.clear();
		}
		else
		if(commands.size()>1)
		{
			choice=CMParms.combine(commands,1);
			while(commands.size()>1)
				commands.remove(1);
		}
		if(choice.toUpperCase().startsWith("RIGHT "))
			choice=choice.substring(6).trim();
		else
		if(choice.toUpperCase().startsWith("LEFT "))
			choice=choice.substring(5).trim();
		final MOB target=super.getTarget(mob,commands,givenTarget,false,true);
		if(target==null)
			return false;
		if(!auto)
		{
			LegalBehavior B=null;
			if(mob.location()!=null)
				B=CMLib.law().getLegalBehavior(mob.location());
			List<LegalWarrant> warrants=new Vector<LegalWarrant>();
			if(B!=null)
				warrants=B.getWarrantsOf(CMLib.law().getLegalObject(mob.location()),target);
			if((warrants.size()==0)&&(!CMSecurity.isAllowed(mob,mob.location(),CMSecurity.SecFlag.ABOVELAW)))
			{
				mob.tell(L("You are not authorized by law to break anything on @x1 at this time.",target.Name()));
				return false;
			}
			final Item w=mob.fetchWieldedItem();
			if(!CMSecurity.isASysOp(mob))
			{
				Weapon ww=null;
				if((w==null)||(!(w instanceof Weapon)))
				{
					mob.tell(L("You cannot break anything without a weapon!"));
					return false;
				}
				ww=(Weapon)w;
				if((ww.weaponDamageType()==Weapon.TYPE_PIERCING)
				&&(ww.weaponDamageType()!=Weapon.TYPE_SLASHING)
				&&(ww.weaponDamageType()!=Weapon.TYPE_BASHING))
				{
					mob.tell(L("You cannot break a limb with a @x1!",ww.name()));
					return false;
				}
				if(mob.isInCombat()&&(mob.rangeToTarget()>0))
				{
					mob.tell(L("You are too far away to try that!"));
					return false;
				}
				if(!CMLib.flags().isBoundOrHeld(target))
				{
					mob.tell(L("@x1 must be bound before you can break @x2 limbs.",target.charStats().HeShe(),target.charStats().hisher()));
					return false;
				}
			}
		}
		if(!super.invoke(mob,commands,givenTarget,auto,asLevel))
			return false;
		boolean success=proficiencyCheck(mob,0,auto);
		if(success)
		{
			LimbDamage ampuA=(LimbDamage)target.fetchEffect("Amputation");
			final List<String> missingLimbs;
			if(ampuA != null)
				missingLimbs=ampuA.affectedLimbNameSet();
			else
				missingLimbs=new ArrayList<String>(1);

			BrokenLimbs brokenA=(BrokenLimbs)target.fetchEffect(ID());
			boolean newOne=false;
			if(brokenA==null)
			{
				brokenA=new BrokenLimbs();
				brokenA.setAffectedOne(target);
				newOne=true;
			}

			String brokeStr=null;
			final List<String> healthyLimbSet=brokenA.unaffectedLimbSet();
			for(String missingLimb : missingLimbs)
				healthyLimbSet.remove(missingLimb);
			if(healthyLimbSet.size()==0)
			{
				if(!auto)
					mob.tell(L("There is nothing left on @x1 that is unbroken!",target.name(mob)));
				return false;
			}

			if(choice.length()>0)
			{
				for(int i=0;i<healthyLimbSet.size();i++)
				{
					if(CMLib.english().containsString(healthyLimbSet.get(i),choice))
					{
						brokeStr=healthyLimbSet.get(i);
						break;
					}
				}
				if(brokeStr==null)
				{
					if(!auto)
						mob.tell(L("There is nothing unbroken on @x1 called '@x2'!",target.name(mob),choice));
					return false;
				}
			}

			if(brokeStr==null)
				brokeStr=healthyLimbSet.get(CMLib.dice().roll(1,healthyLimbSet.size(),-1));

			final String brokeName = brokeStr;

			final String str=auto?"":L("^F^<FIGHT^><S-NAME> break(s) <T-YOUPOSS> @x1!^</FIGHT^>^?",brokeName);
			final CMMsg msg=CMClass.getMsg(mob,target,this,CMMsg.MSK_MALICIOUS_MOVE|CMMsg.TYP_DELICATE_HANDS_ACT|(auto?CMMsg.MASK_ALWAYS:0),str);
			CMLib.color().fixSourceFightColor(msg);
			if(target.location().okMessage(target,msg))
			{
				final MOB vic=target.getVictim();
				final MOB vic2=mob.getVictim();
				target.location().send(target,msg);
				if(msg.value()<=0)
				{
					if(newOne)
					{
						brokenA.makeLongLasting();
						target.addEffect(brokenA);
					}
					brokenA.damageLimb(brokeStr);
					target.recoverCharStats();
					target.recoverPhyStats();
					target.recoverMaxState();
					target.location().recoverRoomStats();
					target.setVictim(vic);
					mob.setVictim(vic2);
					success=true;
				}
			}
			else
				success=false;
		}
		else
			return maliciousFizzle(mob,target,L("<S-NAME> attempt(s) to break one of <T-YOUPOSS> limbs, but fail(s)."));
		return success;
	}
}


text:
<?php

 namespace Antares\Support\Traits;

trait MacroableTrait
{
    /**
     * The registered html macros.
     *
     * @var array
     */
    protected $macros;

    /**
     * Register a custom HTML macro.
     *
     * @param  string  $name
     * @param  callable  $macro
     *
     * @return void
     */
    public function macro($name, $macro)
    {
        $this->macros[$name] = $macro;
    }

    /**
     * Dynamically handle calls to the html class.
     *
     * @param  string  $method
     * @param  array   $parameters
     *
     * @return mixed
     *
     * @throws \BadMethodCallException
     */
    public function __call($method, $parameters)
    {
        if (isset($this->macros[$method])) {
            return call_user_func_array($this->macros[$method], $parameters);
        }

        throw new \BadMethodCallException("Method {$method} does not exist.");
    }
}


text:
WordWiki
========

Learning Python/Djano Wiki project, and friends


text: A beautiful weather app.


text:
import java.util.HashMap;
import java.util.Scanner;

public class PhoneBook {

    private static final String STR_TO_SEARCH_FOR_NAMES = "search";
    private static final String STR_TO_STOP = "stop";

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        HashMap<String, String> namesPhoneNums = new HashMap<>();

        String input;
        while (!STR_TO_SEARCH_FOR_NAMES.equals((input = scanner.nextLine()))) {
            String[] namesPhoneNumsTokens = input.split("-");
            namesPhoneNums.put(namesPhoneNumsTokens[0], namesPhoneNumsTokens[1]);
        }

        while (!STR_TO_STOP.equals((input = scanner.nextLine()))) {
            if (namesPhoneNums.containsKey(input)) {
                System.out.printf("%s -> %s%s", input, namesPhoneNums.get(input), System.lineSeparator());
            } else {
                System.out.printf("Contact %s does not exist.%s", input, System.lineSeparator());
            }
        }
    }
}


text:
import {
    FETCH_ROOM_SUCCESS,
    FETCH_ROOM_ERROR,
    REGISTER_ROOM,
    FECTH_MESSSAGE_SUCCESS,
    FECTH_MESSSAGE_ERROR
} from '../actions/types';

const INITIAL = {
    loading: true,
    messages: [],
    roomKey: null
};

export default (state = INITIAL, action) => {
    switch (action.type) {
        case FETCH_ROOM_SUCCESS:
            return { ...INITIAL, loading: false, roomKey: action.roomKey };
        case FETCH_ROOM_ERROR:
            return { ...INITIAL, loading: false };
        case REGISTER_ROOM:
            return { ...state, roomKey: action.roomKey };
        case FECTH_MESSSAGE_SUCCESS:
            return { ...state, loading: false, messages: action.messages };
        case FECTH_MESSSAGE_ERROR:
            return { ...INITIAL, loading: false };
        default:
            return state;
    }
}


text:
<!doctype html>

<meta charset="utf-8">
<title>Sample Link Post – Shad Ahmad</title>
<meta name="description" content="Example and code for using link posts.">
<meta name="keywords" content="sample post, link post">

<meta property="og:locale" content="en_US">
<meta property="og:type" content="article">
<meta property="og:title" content="Sample Link Post">
<meta property="og:description" content="Example and code for using link posts.">
<meta property="og:url" content="http://shadahmad.com/sample-link-post/">
<meta property="og:site_name" content="Shad Ahmad">

<link rel="canonical" href="http://shadahmad.com/sample-link-post/">
<link href="http://shadahmad.com/feed.xml" type="application/atom+xml" rel="alternate" title="Shad Ahmad Feed">

<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<link rel="stylesheet" href="http://shadahmad.com/assets/css/main.css">

<link href="//fonts.googleapis.com/css?family=Lato:300,400,700,300italic,400italic" rel="stylesheet" type="text/css">

<meta http-equiv="cleartype" content="on">

<link rel="shortcut icon" href="http://shadahmad.com/favicon.ico">

<link rel="shortcut icon" href="http://shadahmad.com/favicon.png">

<link rel="apple-touch-icon-precomposed" href="http://shadahmad.com/images/apple-touch-icon-precomposed.png">

<link rel="apple-touch-icon-precomposed" sizes="72x72" href="http://shadahmad.com/images/apple-touch-icon-72x72-precomposed.png">

<link rel="apple-touch-icon-precomposed" sizes="114x114" href="http://shadahmad.com/images/apple-touch-icon-114x114-precomposed.png">

<link rel="apple-touch-icon-precomposed" sizes="144x144" href="http://shadahmad.com/images/apple-touch-icon-144x144-precomposed.png">

	<button class="dl-trigger">Open Menu</button>

Home

			About

Shad Ahmad

Co-founder @ Greymeter, foodie, gamer, wanderlust.

Learn More

					 Email

					 Facebook

					 LinkedIn

			Posts

All Posts

All Tags

 Sample Link Post

<time datetime="2013-08-12T00:00:00+05:30">August 12, 2013</time>

Reading time ~1 minute

This theme supports link posts, made famous by John Gruber. To use, just add link: http://url-you-want-linked to the post's YAML front matter and you're done.

        sample postlink post

 Like

 Tweet

 +1

    © 2016 Shad Ahmad. Powered by Jekyll using the HPSTR Theme.

Please enable JavaScript to view the comments powered by Disqus.
    comments powered by Disqus


text:
package monix.reactive.internal.builders

import cats.laws._
import cats.laws.discipline._
import monix.execution.Ack.Continue
import monix.execution.internal.Platform.recommendedBatchSize
import monix.reactive.observers.Subscriber
import monix.reactive.{ BaseTestSuite, Observable }

import scala.concurrent.duration.MILLISECONDS

object UnfoldObservableSuite extends BaseTestSuite {

  test("should be exception-proof") { implicit s =>
    val dummy = new RuntimeException("dummy")
    var received = 0

    Observable.unfold(0)(i => if (i < 20) Some((i, i + 1)) else throw dummy).subscribe { (_: Int) =>
      received += 1
      Continue
    }

    assertEquals((0 until received).toList, (0 to 19).toList)
    assertEquals(s.state.lastReportedError, dummy)
  }

  test("should execute 10 times then return None") { implicit s =>
    var received = 0

    Observable.unfold(0)(i => if (i < 10) Some((i, i + 1)) else None).subscribe { (_: Int) =>
      received += 1
      Continue
    }

    assertEquals((0 until received).toList, (0 to 9).toList)
  }

  test("should be cancelable") { implicit s =>
    var wasCompleted = false
    var sum = 0

    val cancelable = Observable
      .unfold(s.clockMonotonic(MILLISECONDS))(intOption)
      .unsafeSubscribeFn(new Subscriber[Int] {
        implicit val scheduler = s

        def onNext(elem: Int) = {
          sum += 1
          Continue
        }

        def onComplete() = wasCompleted = true

        def onError(ex: Throwable) = wasCompleted = true
      })

    cancelable.cancel()

    s.tick()

    assertEquals(sum, s.executionModel.recommendedBatchSize * 2)
    assert(!wasCompleted)
  }

  test("unfold and fromStateAction results should be equal given generated inputs") { implicit s =>
    check2 { (s: Int, i: Int) =>
      val seed = s % (recommendedBatchSize * 2)
      val n = i % (recommendedBatchSize * 2)

      val f: Int => Option[(Int, Int)] = i => if (i < n) Some((i, i + 1)) else None
      val f2: Int => (Int, Int) = i => (i, i + 1)

      Observable.unfold(seed)(f).toListL <-> Observable.fromStateAction(f2)(seed).takeWhile(_ < n).toListL
    }
  }

  def intOption(seed: Long): Option[(Int, Long)] = Option(int(seed))

  def int(seed: Long): (Int, Long) = {
    // `&` is bitwise AND. We use the current seed to generate a new seed.
    val newSeed = (seed * 0x5deece66dL + 0xbL) & 0xffffffffffffL
    // The next state, which is an `RNG` instance created from the new seed.
    val nextRNG = newSeed
    // `>>>` is right binary shift with zero fill. The value `n` is our new pseudo-random integer.
    val n = (newSeed >>> 16).toInt
    // The return value is a tuple containing both a pseudo-random integer and the next `RNG` state.
    (n, nextRNG)
  }
}


text:
package io.github.winsontse.hearteyes.page.image.presenter;

import javax.inject.Inject;

import io.github.winsontse.hearteyes.page.image.contract.GalleryContract;
import io.github.winsontse.hearteyes.page.base.BasePresenterImpl;
import rx.functions.Action1;

public class GalleryPresenter extends BasePresenterImpl implements GalleryContract.Presenter {
    private GalleryContract.View view;

    @Inject
    public GalleryPresenter(final GalleryContract.View view) {
        this.view = view;
    }
}


text:
class CreatePorts < ActiveRecord::Migration
  def change
    create_table :ports do |t|
      t.integer :death_star_id
      t.integer :metal_id
      t.string :name
      t.integer :landing_pads
      t.decimal :size
      t.decimal :x
      t.decimal :y
      t.decimal :z
      # t.integer :material_id
      # t.string :material_type

      t.timestamps
    end
  end
end


text:
package org.jboss.resteasy.category;

/**
 * Marker interface for tests which are expected to fail on WildFly 9.x series
 */
public interface NotForWildFly9 {
}


text:
package com.alibaba.jstorm.daemon.worker;

import java.util.List;

import backtype.storm.messaging.IConnection;
import backtype.storm.messaging.TaskMessage;

import com.alibaba.jstorm.metric.JStormTimer;
import com.alibaba.jstorm.metric.MetricDef;
import com.alibaba.jstorm.metric.Metrics;
import com.alibaba.jstorm.utils.DisruptorRunable;
import com.alibaba.jstorm.utils.Pair;

//import com.alibaba.jstorm.message.zeroMq.ISendConnection;

/**
 *
 * Tuple sender
 *
 * @author yannian
 *
 */
public class DrainerRunable extends DisruptorRunable{

	private static JStormTimer timer = Metrics.registerTimer(null,
			MetricDef.DRAINER_TIME, null, Metrics.MetricType.WORKER);

	public DrainerRunable(WorkerData workerData) {
		super(workerData.getSendingQueue(), timer,
				DrainerRunable.class.getSimpleName(), workerData.getActive());

		Metrics.registerQueue(null, MetricDef.DRAINER_QUEUE, queue, null, Metrics.MetricType.WORKER);
	}

	@SuppressWarnings("unchecked")
	@Override
	public void handleEvent(Object event, boolean endOfBatch)
			throws Exception {

		Pair<IConnection, List<TaskMessage>> pair = (Pair<IConnection, List<TaskMessage>>)event;

		pair.getFirst().send(pair.getSecond());

	}

}


text:
require 'spec_helper'

describe ClassSource do
  after { test_unload_all }

  describe "for a simple class with only an initializer" do
    before do
      test_load 'SimpleClass'
    end
    it "knows the unique methods of the class" do
      SimpleClass.__source__.methods.unique.should == [:initialize]
    end

    it "knows the method location for each of the unique methods of the class" do
      SimpleClass.__source__.methods.locations.should == [[fixtures_path(:simple_class), 4]]
    end

    it "can pinpoint the opening of a simple class" do
      SimpleClass.__source__.locations.should == [[fixtures_path(:simple_class), 3]]
    end

    it "can return the full source of a simple class" do
      SimpleClass.__source__.should == File.read(fixtures_path(:simple_class)).lines.to_a[2..-1].join("")
    end
  end

  describe "for a class with public, private and protected methods" do
    before { test_load 'ProtectedMethodClass' }

    it "knows the unique methods of the class" do
      ProtectedMethodClass.__source__.methods.unique.should =~ [:initialize, :talk, :think, :whisper]
    end

    it "knows the method location for each of the unique methods of the class" do
      ProtectedMethodClass.__source__.methods.locations.should =~ [
        [fixtures_path(:protected_method_class), 2],
        [fixtures_path(:protected_method_class), 6],
        [fixtures_path(:protected_method_class), 11],
        [fixtures_path(:protected_method_class), 16]
      ]
    end

    it "can pinpoint the opening" do
      ProtectedMethodClass.__source__.locations.should == [[fixtures_path(:protected_method_class), 1]]
    end

    it "can return the full source" do
      ProtectedMethodClass.__source__.should == File.read(fixtures_path(:protected_method_class)).lines.to_a[0..-1].join("")
    end
  end

  describe "for a subclass of a user class" do
    before { test_load 'ProtectedMethodClass', 'SubClass' }

    it "knows the unique methods of the class" do
      SubClass.__source__.methods.unique.should =~ [:talk, :think]
    end

    it "knows the method location for each of the unique methods of the class" do
      SubClass.__source__.methods.locations.should =~ [
        [fixtures_path(:sub_class), 2],
        [fixtures_path(:sub_class), 6]
      ]
    end

    it "can pinpoint the opening" do
      SubClass.__source__.locations.should == [[fixtures_path(:sub_class), 1]]
    end

    it "can return the full source" do
      SubClass.__source__.should == File.read(fixtures_path(:sub_class)).lines.to_a[0..-1].join("")
    end
  end

  describe "for a nested class" do
    before { test_load 'OuterClass' }
    it "can return the full source" do
      OuterClass::NestedClass.__source__.should == File.read(fixtures_path(:outer_class)).lines.to_a[12..16].join("")
    end
  end

  describe "for a class with no unique methods" do
    before { test_load 'NoMethodsClass' }
    it "can return the full source if you pass a source file" do
      NoMethodsClass.__source__(:file => fixtures_path(:no_methods_class)).should == File.read(fixtures_path(:no_methods_class)).lines.to_a[0..4].join("")
    end
    describe "for a nested class with no unique methods" do
      it "can return the full source" do
        NoMethodsClass::NestedClass.__source__(:file => fixtures_path(:no_methods_class)).should == File.read(fixtures_path(:no_methods_class)).lines.to_a[1..3].join("")
      end
    end
  end

  describe "for an outer class" do
    before { test_load 'OuterClass' }
    it "can return the full source" do
      OuterClass.__source__.should == File.read(fixtures_path(:outer_class)).lines.to_a[0..-1].join("")
    end

    it "can also return the source minus any nested classes" do
      source_lines = File.read(fixtures_path(:outer_class)).lines.to_a
      non_nested_lines = (source_lines[0..3] + source_lines[8..11] + source_lines[17..-1]).join("")
      OuterClass.__source__.to_s(:include_nested => false).should == non_nested_lines
    end
  end

  describe "for dynamically defined classes" do
    before do
      test_load 'DynamicClass'
    end

    it "should have a single source location" do
      DynamicClass.__source__.should have(1).locations
    end

    it "can return the full source" do
      DynamicClass.__source__.should == File.read(fixtures_path(:dynamic_class)).lines.to_a[0..4].join("")
    end

    it "can return the source for a class named later in the file" do
      LateNamedDynamicClass.send :extend, ClassSource
      LateNamedDynamicClass.__source__.should == File.read(fixtures_path(:dynamic_class)).lines.to_a[11]
    end

    describe "with no methods" do
      it "knows the source" do
        MethodlessDynamicClass.send :extend, ClassSource
        MethodlessDynamicClass.__source__.should == "MethodlessDynamicClass = Class.new\n"
      end
    end
  end

  describe "for duplicated classes" do
    before { test_load 'DuplicatedClass' }
    it "should point to the duplication point" do
      DuplicateClass.__source__.locations.should == [
        [fixtures_path(:duplicated_class), 5]
      ]
    end
  end

  describe "for cloned classes" do
    before { test_load 'ClonedClass' }
    it "should point to the cloning point" do
      CloneClass.__source__.locations.should == [
        [fixtures_path(:cloned_class), 5]
      ]
    end
  end

  describe "for classes defined within eval" do
    before { test_load 'EvalClass' }
    it "should point to the evaluation point" do
      EvalClass.__source__.locations.should == [
        [fixtures_path(:eval_class), 11]
      ]
    end
  end

  describe "for classes that are reopened in separate files" do
    before { test_load 'ReOpenedClass' }
    it "should have more than one source file" do
      ReOpenedClass.__source__.files.length.should == 2
    end

    it "should have more than one source location" do
      ReOpenedClass.__source__.locations.length.should == 2
    end

    it "should have the full source in its source" do
      ReOpenedClass.__source__.all.should == {
        [fixtures_path(:re_opened_class), 3] => File.read(fixtures_path(:re_opened_class)).lines.to_a[2..-1].join(""),
        [fixtures_path(:re_opened_class_2), 1] => File.read(fixtures_path(:re_opened_class_2))
      }
    end

    it "should be able to display without nested classes if needed" do
      reopened_source = File.read(fixtures_path(:re_opened_class)).lines.to_a
      reopened_source_2 = File.read(fixtures_path(:re_opened_class_2)).lines.to_a
      ReOpenedClass.__source__.all(:include_nested => false).should == {
        [fixtures_path(:re_opened_class), 3] => (reopened_source[2..6] + reopened_source[15..-1]).join(""),
        [fixtures_path(:re_opened_class_2), 1] => (reopened_source_2[0..4] + reopened_source_2[10..-1]).join("")
      }
    end
  end

  describe "for a nested class that is reopened within the parent" do
    before { test_load 'ReOpenedClass' }
    it "should have more than one source location" do
      ReOpenedClass::NestedClass.__source__.all.should == {
        [fixtures_path(:re_opened_class), 8] => File.read(fixtures_path(:re_opened_class)).lines.to_a[7..10].join(""),
        [fixtures_path(:re_opened_class), 12] => File.read(fixtures_path(:re_opened_class)).lines.to_a[11..14].join("")
      }
    end
  end

  describe "for class with only class methods" do
    before do
      test_load 'ClassMethodsClass'
    end
    it "knows the unique class methods of the class" do
      ClassMethodsClass.__source__.class_methods.unique.should == [:simple_method]
    end
    it "can find the source" do
      ClassMethodsClass.__source__.should == File.read(fixtures_path(:class_methods_class)).lines.to_a[0..-1].join("")
    end
  end

  describe "it doesn't cause side effects for class-scoped code" do
    before do
      test_load 'SideEffectClass'
    end

    it "should retain the same values as set" do
      SideEffectClass.should be_active
      SideEffectClass.deactivate!
      SideEffectClass.should_not be_active
      SideEffectClass.__source__.should == File.read(fixtures_path(:side_effect_class)).lines.to_a[0..-1].join("")
      SideEffectClass.should_not be_active
    end
  end

end


text:
'use strict';

describe('Sequoia Tree Factory', function() {

  var node, template, wrongTemplate, nodes;

  node = { _id: '1234', title: 'My title', nodes: [] };
  template = { id: '_id', title: 'title', nodes: 'nodes' };
  wrongTemplate = { id: 'not_id', title: 'title', nodes: 'nodes' };
  nodes = [
    { _id: '1234', title: 'Title one', nodes: [] },
    { _id: '5678', title: 'Title two', nodes: [] },
    { _id: '9012', title: 'Title three', nodes: [{ _id: '3456', title: 'Subtitle one', nodes: [] }, { _id: '7890', title: 'Subtitle two', nodes: [{ _id: '12345', title: 'Subsubtitle one', nodes: [] }] }] },
    { _id: '345678', title: 'Title four', nodes: [{ _id: '901234', title: 'Subtitle one', nodes: [] }] }
  ];

  beforeEach(module('ngSequoia'));

  var SequoiaTree,
      Utils,
      log,
      NODE_TEMPLATE,
      BUTTONS;

  beforeEach(inject(function(_SequoiaTree_, _SequoiaTreeUtils_, _$log_, _NODE_TEMPLATE_, _BUTTONS_){
    SequoiaTree = _SequoiaTree_;
    Utils = _SequoiaTreeUtils_;
    log = _$log_;
    NODE_TEMPLATE = _NODE_TEMPLATE_;
    BUTTONS = _BUTTONS_;
  }));

  it('should create a new tree', function() {
    var tree1 = new SequoiaTree(nodes,template),
        tree2 = new SequoiaTree(nodes);

    expect(tree1).toBeDefined(); //passing a template
    expect(tree2).toBeDefined(); //create a tree with the default template
  });

  it('should validate the node template', function() {
    var tree = new SequoiaTree(nodes,template);

    expect(tree.tree.length).toBeTruthy();
  });

  it('should not validate the node template', function() {
    var tree = new SequoiaTree(nodes,wrongTemplate);

    expect(tree.tree.length).toBeFalsy();
  });

  it('should validate a node', function() {
    var tree = new SequoiaTree([],template);

    expect(tree.isValidNode(node)).toBeTruthy();
  });

  it('should set reset the startkey for pagination and empty the current nodes', function() {
    var tree = new SequoiaTree(nodes,template);

    tree.setCurrentNodes();
    expect(tree.nodes).toEqual([]);
    expect(tree.pagination.startkey).toEqual(0);
  });

  it('should set the current nodes to the tree nodes', function() {
    var tree = new SequoiaTree(nodes,template);

    tree.setCurrentNodes();
    tree.paginate();
    expect(tree.nodes).toEqual(nodes);
  });

  it('should paginate', function() {
    var tree, i, _nodes = [];

    _nodes = nodes.concat([0]);

    for(i=0;i<25;i++) {
      _nodes.push({_id: 'generated_' + i, title: 'Generated title ' + i, nodes: []});
    }

    tree = new SequoiaTree(_nodes,template);

    tree.setCurrentNodes();
    tree.paginate();
    expect(tree.currentNodes.length).toEqual(_nodes.length);
    expect(tree.nodes.length).toEqual(tree.pagination.limit);
  });

  it('should not finish pagination', function() {
    var tree, i, _nodes = [];

    for(i=0;i<25;i++) {
      _nodes.push({_id: 'generated_' + i, title: 'Generated title ' + i, nodes: []});
    }

    tree = new SequoiaTree(_nodes,template);

    tree.setCurrentNodes();
    tree.paginate();
    expect(tree.pagination.finished).toBe(false);
  });

  it('should finish pagination', function() {
    var tree;

    tree = new SequoiaTree(nodes,template);

    tree.setCurrentNodes();
    tree.paginate();
    expect(tree.pagination.finished).toBe(true);
  });

  it('should set the current nodes to passed nodes', function() {
    var someNodes = [{_id: '1234', title: 'Title', nodes: []}],
        tree = new SequoiaTree(nodes,template);

    tree.setCurrentNodes(someNodes);
    tree.paginate();
    expect(tree.nodes).toEqual(someNodes);
  });

  it('should find elements containing a string in the title', function() {
    var tree = new SequoiaTree(nodes,template),
        found = tree.find('title', 'sub');

    expect(found.length).toBe(4);
  });

  it('should find selected items', function() {
    var tree = new SequoiaTree(nodes,template),
        ids = ['1234', '5678', '12345', 'wrong_id'],
        found = tree.findSelected(ids);

    expect(found.length).toBe(3);
  });

  it('create breadcrumbs', function() {
    var tree = new SequoiaTree(nodes,template),
        breadcrumbs = {
          path: '[3]["nodes"][0]["nodes"]',
          nodes: [
            { title: BUTTONS.root },
            { _id: '345678', title: 'Title four', nodes: [{ _id: '901234', title: 'Subtitle one', nodes: [] }] },
            { _id: '901234', title: 'Subtitle one', nodes: [] }
          ]
        };

    expect(tree.breadcrumbs('901234')).toEqual(breadcrumbs);
  });

  it('should get the parent node', function() {
    var tree = new SequoiaTree(nodes,template),
        path = [{ _id: '9012', title: 'Title', nodes: [] }, { _id: '90122', title: 'Title two', nodes: [] }, { _id: '90123', title: 'Title three', nodes: [] }],
        node = { _id: '90122', title: 'Title two', nodes: [] };

    expect(tree.findParentNode(path)).toEqual(node);
  });

  it('should build the correct path to a node', function() {
    var tree = new SequoiaTree(nodes,template),
        testPath = 'Full path: ' + BUTTONS.root + ' » Title three » Subtitle two » Subsubtitle one',
        path = tree.buildPathToNode({ _id: '12345', title: 'Subsubtitle one', nodes: [] });

    expect(testPath).toEqual(path);
  });

  it('should retrieve the path to a single node passed as a string', function() {
    var tree = new SequoiaTree(nodes,template),
        found = tree.findSelected('1234');

    expect(found.length).toBe(1);
  });

  it('should retrieve the path to two nodes passed as an array', function() {
    var tree = new SequoiaTree(nodes,template),
        found = tree.findSelected(['1234', '5678']);

    expect(found.length).toBe(2);
  });

  it('should fail to retrieve the path to a node passed as an object', function() {
    var tree = new SequoiaTree(nodes,template),
        found = tree.findSelected({id: '1234'});

    expect(found.length).toBe(0);
    expect(log.warn.logs).toContain(['You must pass an array of IDs or a single ID in order to find the selected nodes!']);
  });

  it('should create a new empty node', function() {
    var tree = new SequoiaTree(nodes,template);

    tree.setCurrentNodes(nodes);

    var node = tree.addNode();

    expect(nodes.length).toEqual(tree.currentNodes.length);
  });

  it('should remove an existing node', function() {
    var tree = new SequoiaTree(nodes,template),
        remove = nodes[0],
        initialLength = tree.tree.length;

    tree.removeNode(remove);

    expect(initialLength).toEqual(tree.tree.length + 1);
  });

});


text:
<?php
/**
 * Created by PhpStorm.
 * User: Angel
 * Date: 6/30/14
 * Time: 11:16 PM
 */

namespace Ociosos\ComunBundle\Controller;

use Ociosos\ComunBundle\Captcha;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;

class EmailController extends Controller
{

    /*public function generateCaptchaText()
    {
        // Create a random string, leaving out 'o' to avoid confusion with '0'
        $char = strtoupper(substr(str_shuffle('abcdefghjkmnpqrstuvwxyz'), 0, 4));

        // Concatenate the random string onto the random numbers
        // The font 'Anorexia' doesn't have a character for '8', so the numbers will only go up to 7
        // '0' is left out to avoid confusion with 'O'
        return rand(1, 7) . rand(1, 7) . $char;
    }*/

    /*public function startCaptchaSession()
    {
        $this->getRequest()->getSession()->set('captcha_id', $this->generateCaptchaText());
    }*/

//    TODO: regenerar la captcha.
    public function refreshCaptcha()
    {

    }

    public function createImageCaptchaAction()
    {
        $captcha =  new Captcha($this->getRequest()->getSession());

        $captcha->outputImage();

        /*return new Response(
            $captchaText,
            200,
            array(
                'Content-Type' => 'image/png',
                'Cache-Control' => 'no-cache'
            )
        );*/
    }

    public function verifyCaptchaAction()
    {
        /*var_dump($this->getRequest()->get('captcha'));
        die;*/

        return new Response('false');

        if (!$this->getRequest()->getSession()->isStarted()) {
            return new Response('false');
        }

        $captchaId = strtoupper($this->getRequest()->getSession()->get('captcha_id'));

        if ($captchaId != $captcha) {
            return new Response('false');
        }

        return new Response('true');
    }

    public function SendEmailAction()
    {
        $request = $this->getRequest();
        $name = $request->request->get('txtName');
        $email = $request->request->get('txtEmail');
        $comment = $request->request->get('txtMessage');
        $em = $this->getDoctrine()->getManager();
        $adminEmail = $em->getRepository('UsuarioBundle:Usuario')->FindEmailFromAdmin();
//        $logo = realpath('bundles/comun/images/logoociosos.png');

//        var_dump($adminEmail['email']);
//        die;
        $message = \Swift_Message::newInstance()

            ->setContentType("text/html")

            ->setSubject('Ociosos: ' . $name)

            ->setFrom($email)
            ->setTo($adminEmail['email'])
                        ->setBody(

                $this->renderView(
                    'ComunBundle:Email:message.html.twig',
                    array(
                        'name' => $name,
                        'email' => $email,
                        'comment' => $comment,
                        //'logo'=>$logo
                    )
                )
            );

        $this->get('mailer')->send($message);

//        var_dump('test');
        return $this->render('ComunBundle:Default:portada.html.twig');
    }

    public function SendEmailSolicitudAction()
    {

        $request = $this->getRequest();
        $productoId = $request->request->get('id');

        $name = $request->request->get('txtName');
        $email = $request->request->get('txtEmail');
        $comment = $request->request->get('txtMessage');

        $em = $this->getDoctrine()->getManager();
//        akakjdaksdjhakjdhalkjdhakljdhakljdsh me quede aqui
        $emailTo = $em->getRepository('ComunBundle:Producto')->FindEmailById($productoId);
        $productoInfo = $em->getRepository('ComunBundle:Producto')->findOneById($productoId);

        $productoNombre = $productoInfo->getNombre();
        $productoCodigo = $productoInfo->getCodigo();

//        var_dump($emailTo['email']);
//        var_dump($email);
//        die;
        $message = \Swift_Message::newInstance()
            ->setSubject('Ociosos: ' . $name)
            ->setFrom($email)
            ->setTo($emailTo['email'])
            ->setBody(
                $this->renderView(
                    'ComunBundle:Email:messageSolicitud.html.twig',
                    array(
                        'name' => $name,
                        'email' => $email,
                        'comment' => $comment,
                        'nombre' => $productoNombre,
                        'codigo' => $productoCodigo
                    )
                )
            );
        $this->get('mailer')->send($message);

        return $this->render('ComunBundle:Default:portada.html.twig');
    }

}


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

using ASC.Common.Data;
using ASC.Common.Data.Sql;
using ASC.Common.Data.Sql.Expressions;
using ASC.Mail.Core.Dao.Interfaces;
using ASC.Mail.Core.DbSchema;
using ASC.Mail.Core.DbSchema.Interfaces;
using ASC.Mail.Core.DbSchema.Tables;
using ASC.Mail.Core.Entities;

namespace ASC.Mail.Core.Dao
{
    public class UserFolderXMailDao : BaseDao, IUserFolderXMailDao
    {
        protected static ITable table = new MailTableFactory().Create<UserFoldertXMailTable>();

        protected string CurrentUserId { get; private set; }

        public UserFolderXMailDao(IDbManager dbManager, int tenant, string user)
            : base(table, dbManager, tenant)
        {
            CurrentUserId = user;
        }

        public UserFolderXMail Get(int mailId)
        {
            var query = Query()
                .Where(UserFoldertXMailTable.Columns.Tenant, Tenant)
                .Where(UserFoldertXMailTable.Columns.User, CurrentUserId)
                .Where(UserFoldertXMailTable.Columns.MailId, mailId);

            var result = Db.ExecuteList(query)
                .ConvertAll(ToUserFolderXMail)
                .SingleOrDefault();

            return result;
        }

        public List<UserFolderXMail> GetList(uint? folderId = null, List<int> mailIds = null)
        {
            var query = Query()
                .Where(UserFoldertXMailTable.Columns.Tenant, Tenant)
                .Where(UserFoldertXMailTable.Columns.User, CurrentUserId);

            if (folderId.HasValue)
            {
                query.Where(UserFoldertXMailTable.Columns.FolderId, folderId.Value);
            }

            if (mailIds != null && mailIds.Any())
            {
                query.Where(Exp.In(UserFoldertXMailTable.Columns.MailId, mailIds));
            }

            var list = Db.ExecuteList(query)
                .ConvertAll(ToUserFolderXMail);

            return list;
        }

        public List<int> GetMailIds(uint folderId)
        {
            var query = new SqlQuery(UserFoldertXMailTable.TABLE_NAME)
                .Select(UserFoldertXMailTable.Columns.MailId)
                .Where(UserFoldertXMailTable.Columns.Tenant, Tenant)
                .Where(UserFoldertXMailTable.Columns.User, CurrentUserId)
                .Where(UserFoldertXMailTable.Columns.FolderId, folderId);

            var list = Db.ExecuteList(query)
                .ConvertAll(r => Convert.ToInt32(r[0]));

            return list;
        }

        private delegate SqlInsert CreateInsertDelegate();

        public void SetMessagesFolder(IEnumerable<int> messageIds, uint folderId)
        {
            var idMessages = messageIds as IList<int> ?? messageIds.ToList();
            if (!idMessages.Any())
                return;

            CreateInsertDelegate createInsertQuery = ()
                => new SqlInsert(UserFoldertXMailTable.TABLE_NAME)
                    .IgnoreExists(true)
                    .InColumns(UserFoldertXMailTable.Columns.Tenant,
                        UserFoldertXMailTable.Columns.User,
                        UserFoldertXMailTable.Columns.MailId,
                        UserFoldertXMailTable.Columns.FolderId);

            var insertQuery = createInsertQuery();

            int i, messagessLen;
            for (i = 0, messagessLen = idMessages.Count; i < messagessLen; i++)
            {
                var messageId = idMessages[i];

                insertQuery
                    .Values(Tenant, CurrentUserId, messageId, folderId);

                if ((i % 100 != 0 || i == 0) && i + 1 != messagessLen)
                    continue;

                Db.ExecuteNonQuery(insertQuery);

                insertQuery = createInsertQuery();
            }
        }

        public int Save(UserFolderXMail item)
        {
            var query = new SqlInsert(UserFoldertXMailTable.TABLE_NAME, true)
                .InColumnValue(UserFoldertXMailTable.Columns.Tenant, item.Tenant)
                .InColumnValue(UserFoldertXMailTable.Columns.User, item.User)
                .InColumnValue(UserFoldertXMailTable.Columns.MailId, item.MailId)
                .InColumnValue(UserFoldertXMailTable.Columns.FolderId, item.FolderId);

            var result = Db.ExecuteNonQuery(query);

            return result;
        }

        public int Remove(int? mailId = null, uint? folderId = null)
        {
            var query = new SqlDelete(UserFoldertXMailTable.TABLE_NAME)
                .Where(UserFoldertXMailTable.Columns.Tenant, Tenant)
                .Where(UserFoldertXMailTable.Columns.User, CurrentUserId);

            if (mailId.HasValue)
            {
                query.Where(UserFoldertXMailTable.Columns.MailId, mailId.Value);
            }

            if (folderId.HasValue)
            {
                query.Where(UserFoldertXMailTable.Columns.FolderId, folderId.Value);
            }

            var result = Db.ExecuteNonQuery(query);

            return result;
        }

        public int Remove(List<int> mailIds)
        {
            var query = new SqlDelete(UserFoldertXMailTable.TABLE_NAME)
                .Where(UserFoldertXMailTable.Columns.Tenant, Tenant)
                .Where(UserFoldertXMailTable.Columns.User, CurrentUserId)
                .Where(Exp.In(UserFoldertXMailTable.Columns.MailId, mailIds));

            var result = Db.ExecuteNonQuery(query);

            return result;
        }

        private static readonly string QueryDeleteFormat =
                string.Format(
                    "delete t from {0} t inner join {1} m " +
                    "on t.{2} = m.{3} and t.{4} = m.{5} and t.{6} = m.{7} " +
                    "where m.{8} = @mailbox_id and m.{5} = @tenant and m.{7} = @user",
                    UserFoldertXMailTable.TABLE_NAME, MailTable.TABLE_NAME,
                    UserFoldertXMailTable.Columns.MailId, MailTable.Columns.Id,
                    UserFoldertXMailTable.Columns.Tenant, MailTable.Columns.Tenant,
                    UserFoldertXMailTable.Columns.User, MailTable.Columns.User,
                    MailTable.Columns.MailboxId);

        public int RemoveByMailbox(int mailboxId)
        {
            return Db.ExecuteNonQuery(QueryDeleteFormat, new { mailbox_id = mailboxId, tenant = Tenant, user = CurrentUserId });
        }

        protected UserFolderXMail ToUserFolderXMail(object[] r)
        {
            var folderXMail = new UserFolderXMail
            {
                Tenant = Convert.ToInt32(r[0]),
                User = Convert.ToString(r[1]),
                MailId = Convert.ToInt32(r[2]),
                FolderId = Convert.ToUInt32(r[3]),
                TimeModified = Convert.ToDateTime(r[4])
            };

            return folderXMail;
        }
    }
}


text:
frappe.provide('frappe.dom');

frappe.dom = {
	id_count: 0,
	freeze_count: 0,
	by_id: function(id) {
		return document.getElementById(id);
	},
	set_unique_id: function(ele) {
		var id = 'unique-' + frappe.dom.id_count;
		if(ele)
			ele.setAttribute('id', id);
		frappe.dom.id_count++;
		return id;
	},
	eval: function(txt) {
		if(!txt) return;
		var el = document.createElement('script');
		el.appendChild(document.createTextNode(txt));
		// execute the script globally
		document.getElementsByTagName('head')[0].appendChild(el);
	},
	remove_script_and_style: function(txt) {
		var div = document.createElement('div');
		div.innerHTML = txt;
		["script", "style", "noscript", "title", "meta", "base", "head"].forEach(function(e, i) {
			var elements = div.getElementsByTagName(e);
			var i = elements.length;
			while (i--) {
				elements[i].parentNode.removeChild(elements[i]);
			}
		});
		return div.innerHTML;
	},
	set_style: function(txt, id) {
		if(!txt) return;

		var se = document.createElement('style');
		se.type = "text/css";

		if (id) {
			var element = document.getElementById(id);
			if (element) {
				element.parentNode.removeChild(element);
			}
			se.id = id;
		}

		if (se.styleSheet) {
			se.styleSheet.cssText = txt;
		} else {
			se.appendChild(document.createTextNode(txt));
		}
		document.getElementsByTagName('head')[0].appendChild(se);
	},
	add: function(parent, newtag, className, cs, innerHTML, onclick) {
		if(parent && parent.substr)parent = frappe.dom.by_id(parent);
		var c = document.createElement(newtag);
		if(parent)
			parent.appendChild(c);

		// if image, 3rd parameter is source
		if(className) {
			if(newtag.toLowerCase()=='img')
				c.src = className
			else
				c.className = className;
		}
		if(cs) frappe.dom.css(c,cs);
		if(innerHTML) c.innerHTML = innerHTML;
		if(onclick) c.onclick = onclick;
		return c;
	},
	css: function(ele, s) {
		if(ele && s) {
			$.extend(ele.style, s);
		};
		return ele;
	},
	freeze: function(msg, css_class) {
		// blur
		if(!$('#freeze').length) {
			var freeze = $('

')
				.on("click", function() {
					if (cur_frm && cur_frm.cur_grid) {
						cur_frm.cur_grid.toggle_view();
						return false;
					}
				})
				.appendTo("#body_div");

			freeze.html(repl('

%(msg)s

',
				{msg: msg || ""}));

			setTimeout(function() { freeze.addClass("in") }, 1);

		} else {
			$("#freeze").addClass("in");
		}

		if (css_class) {
			$("#freeze").addClass(css_class);
		}

		frappe.dom.freeze_count++;
	},
	unfreeze: function() {
		if(!frappe.dom.freeze_count) return; // anything open?
		frappe.dom.freeze_count--;
		if(!frappe.dom.freeze_count) {
			var freeze = $('#freeze').removeClass("in");
			setTimeout(function() {
				if(!frappe.dom.freeze_count) { freeze.remove(); }
			}, 150);
		}
	},
	save_selection: function() {
		// via http://stackoverflow.com/questions/5605401/insert-link-in-contenteditable-element
		if (window.getSelection) {
			sel = window.getSelection();
			if (sel.getRangeAt && sel.rangeCount) {
				var ranges = [];
				for (var i = 0, len = sel.rangeCount; i < len; ++i) {
					ranges.push(sel.getRangeAt(i));
				}
				return ranges;
			}
		} else if (document.selection && document.selection.createRange) {
			return document.selection.createRange();
		}
		return null;
	},
	restore_selection: function(savedSel) {
		if (savedSel) {
			if (window.getSelection) {
				sel = window.getSelection();
				sel.removeAllRanges();
				for (var i = 0, len = savedSel.length; i < len; ++i) {
					sel.addRange(savedSel[i]);
				}
			} else if (document.selection && savedSel.select) {
				savedSel.select();
			}
		}
	},
	is_touchscreen: function() {
		return ('ontouchstart' in window)
	}
}

frappe.get_modal = function(title, content) {
	return $(frappe.render_template("modal", {title:title, content:content})).appendTo(document.body);
};

var get_hex = function(i) {
	i = Math.round(i);
	if(i>255) return 'ff';
	if(i<0) return '00';
	i =i .toString(16);
	if(i.length==1) i = '0'+i;
	return i;
}

frappe.get_shade = function(color, factor) {
	if(color.substr(0,3)=="rgb") {
		var rgb = function(r,g,b) {
			return get_hex(r) + get_hex(g) + get_hex(b);
		}
		color = eval(color);
	}
	if(color.substr(0,1)=="#") {
		var color = color.substr(1);
	}

	var get_int = function(hex) {
		return parseInt(hex,16);
	}
	return get_hex(get_int(color.substr(0,2)) + factor)
		+ get_hex(get_int(color.substr(2,2)) + factor)
		+ get_hex(get_int(color.substr(4,2)) + factor)
}

frappe.dom.set_box_shadow = function(ele, spread) {
	$(ele).css('-moz-box-shadow', '0px 0px '+ spread +'px rgba(0,0,0,0.3);')
	$(ele).css('-webkit-box-shadow', '0px 0px '+ spread +'px rgba(0,0,0,0.3);')
	$(ele).css('-box-shadow', '0px 0px '+ spread +'px rgba(0,0,0,0.3);')

};

// add <option> list to <select>
(function($) {
	$.fn.add_options = function(options_list) {
		// create options
		for(var i=0; i<options_list.length; i++) {
			var v = options_list[i];
			if (is_null(v)) {
				var value = null;
				var label = null;
			} else {
				var is_value_null = is_null(v.value);
				var is_label_null = is_null(v.label);

				if (is_value_null && is_label_null) {
					var value = v;
					var label = __(v);
				} else {
					var value = is_value_null ? "" : v.value;
					var label = is_label_null ? __(value) : __(v.label);
				}
			}
			$('<option>').html(cstr(label)).attr('value', value).appendTo(this);
		}
		// select the first option
		this.selectedIndex = 0;
		return $(this);
	}
	$.fn.set_working = function() {
		this.prop('disabled', true);
	}
	$.fn.done_working = function() {
		this.prop('disabled', false);
	}
})(jQuery);

(function($) {
    function pasteIntoInput(el, text) {
        el.focus();
        if (typeof el.selectionStart == "number") {
            var val = el.value;
            var selStart = el.selectionStart;
            el.value = val.slice(0, selStart) + text + val.slice(el.selectionEnd);
            el.selectionEnd = el.selectionStart = selStart + text.length;
        } else if (typeof document.selection != "undefined") {
            var textRange = document.selection.createRange();
            textRange.text = text;
            textRange.collapse(false);
            textRange.select();
        }
    }

    function allowTabChar(el) {
        $(el).keydown(function(e) {
            if (e.which == 9) {
                pasteIntoInput(this, "\t");
                return false;
            }
        });

        // For Opera, which only allows suppression of keypress events, not keydown
        $(el).keypress(function(e) {
            if (e.which == 9) {
                return false;
            }
        });
    }

    $.fn.allowTabs = function() {
        if (this.jquery) {
            this.each(function() {
                if (this.nodeType == 1) {
                    var nodeName = this.nodeName.toLowerCase();
                    if (nodeName == "textarea" || (nodeName == "input" && this.type == "text")) {
                        allowTabChar(this);
                    }
                }
            })
        }
        return this;
    }
})(jQuery);


text:
|-------------------------------------------------------------------|
| **Tag Library Documentation Generator - Generated Documentation** |

|----------------------------------------------------------|
| [All Tags / Functions](alltags-frame.html.md) Tag Libraries
  [tiles](tiles/tld-frame.html.md)                            |


text:
import knockout from './knockout-3.5.1.js';
import knockout_es5 from './knockout-es5.js';
import SvgPathBindingHandler from '../Widgets/SvgPathBindingHandler.js';

// install the Knockout-ES5 plugin
knockout_es5.attachToKo(knockout);

// Register all Cesium binding handlers
SvgPathBindingHandler.register(knockout);

export default knockout;


text:
<?php

namespace Deicer\Query;

use Deicer\Model\ModelInterface;
use Deicer\Model\ModelCompositeInterface;

/**
 * Deicer Query Builder Interface
 *
 * Assembles concrete query instances.
 *
 * @category   Deicer
 * @package    Query
 * @version    $id$
 * @copyright  2013 Alex Butucea <alex826@gmail.com>
 * @author     Alex Butucea <alex826@gmail.com>
 * @license    The MIT License (MIT) {@link http://opensource.org/licenses/MIT}
 */
interface QueryBuilderInterface
{
    /**
     * Query builder constructor
     *
     * @throws InvalidArgumentException If $namespace is not a string
     * @param  string $namespace Namespace concrete queries are located under
     * @return QueryBuilderInterface
     */
    public function __construct($namespace);

    /**
     * Sets the data provider to build with
     *
     * @param  mixed $dataProvider Data provider to build with
     * @return QueryBuilderInterface Fluent interface
     */
    public function withDataProvider($dataProvider);

    /**
     * Sets the model prototype to build with
     *
     * @param  ModelInterface $modelPrototype Model prototype to build with
     * @return QueryBuilderInterface Fluent interface
     */
    public function withModelPrototype(ModelInterface $modelPrototype);

    /**
     * Sets the model composite prototype to build with
     *
     * @param  ModelCompositeInterface $modelCompositePrototype
     *         Composite prototype to build with
     * @return QueryBuilderInterface Fluent interface
     */
    public function withModelCompositePrototype(
        ModelCompositeInterface $modelCompositePrototype
    );

    /**
     * Assembles an instance of the specified query using the set parameters
     *
     * @throws LogicException If model prototype has not been set
     * @throws LogicException If model composite prototype has not been set
     * @throws LogicException If data provider is unset and query has method setDataProider
     * @throws InvalidArgumentException If $classname is empty
     * @throws InvalidArgumentException If $classname is not a string
     * @throws UnexpectedValueException If query doesnt implement QueryInterface
     * @throws NonExistentQueryException If query doesn't exist
     *
     * @param  string $classname Query name that is appended onto set namespace
     * @return QueryInterface Assembled query instance
     */
    public function build($classname);
}


text: DASHENG