text:
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/** @file
 * This file declares the RasterImage class, which
 * handles static and animated rasterized images.
 *
 * @author  Stuart Parmenter <pavlov@netscape.com>
 * @author  Chris Saari <saari@netscape.com>
 * @author  Arron Mogge <paper@animecity.nu>
 * @author  Andrew Smith <asmith15@learn.senecac.on.ca>
 */

#ifndef mozilla_imagelib_RasterImage_h_
#define mozilla_imagelib_RasterImage_h_

#include "mozilla/Mutex.h"
#include "Image.h"
#include "nsCOMArray.h"
#include "nsCOMPtr.h"
#include "imgIContainer.h"
#include "nsIProperties.h"
#include "nsITimer.h"
#include "nsWeakReference.h"
#include "nsTArray.h"
#include "imgFrame.h"
#include "nsThreadUtils.h"
#include "DiscardTracker.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Telemetry.h"
#include "mozilla/LinkedList.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/WeakPtr.h"
#ifdef DEBUG
  #include "imgIContainerDebug.h"
#endif

class imgIDecoder;
class imgIContainerObserver;
class nsIInputStream;

#define NS_RASTERIMAGE_CID \
{ /* 376ff2c1-9bf6-418a-b143-3340c00112f7 */         \
     0x376ff2c1,                                     \
     0x9bf6,                                         \
     0x418a,                                         \
    {0xb1, 0x43, 0x33, 0x40, 0xc0, 0x01, 0x12, 0xf7} \
}

/**
 * Handles static and animated image containers.
 *
 *
 * @par A Quick Walk Through
 * The decoder initializes this class and calls AppendFrame() to add a frame.
 * Once RasterImage detects more than one frame, it starts the animation
 * with StartAnimation(). Note that the invalidation events for RasterImage are
 * generated automatically using nsRefreshDriver.
 *
 * @par
 * StartAnimation() initializes the animation helper object and sets the time
 * the first frame was displayed to the current clock time.
 *
 * @par
 * When the refresh driver corresponding to the imgIContainer that this image is
 * a part of notifies the RasterImage that it's time to invalidate,
 * RequestRefresh() is called with a given TimeStamp to advance to. As long as
 * the timeout of the given frame (the frame's "delay") plus the time that frame
 * was first displayed is less than or equal to the TimeStamp given,
 * RequestRefresh() calls AdvanceFrame().
 *
 * @par
 * AdvanceFrame() is responsible for advancing a single frame of the animation.
 * It can return true, meaning that the frame advanced, or false, meaning that
 * the frame failed to advance (usually because the next frame hasn't been
 * decoded yet). It is also responsible for performing the final animation stop
 * procedure if the final frame of a non-looping animation is reached.
 *
 * @par
 * Each frame can have a different method of removing itself. These are
 * listed as imgIContainer::cDispose... constants.  Notify() calls
 * DoComposite() to handle any special frame destruction.
 *
 * @par
 * The basic path through DoComposite() is:
 * 1) Calculate Area that needs updating, which is at least the area of
 *    aNextFrame.
 * 2) Dispose of previous frame.
 * 3) Draw new image onto compositingFrame.
 * See comments in DoComposite() for more information and optimizations.
 *
 * @par
 * The rest of the RasterImage specific functions are used by DoComposite to
 * destroy the old frame and build the new one.
 *
 * @note
 * <li> "Mask", "Alpha", and "Alpha Level" are interchangeable phrases in
 * respects to RasterImage.
 *
 * @par
 * <li> GIFs never have more than a 1 bit alpha.
 * <li> APNGs may have a full alpha channel.
 *
 * @par
 * <li> Background color specified in GIF is ignored by web browsers.
 *
 * @par
 * <li> If Frame 3 wants to dispose by restoring previous, what it wants is to
 * restore the composition up to and including Frame 2, as well as Frame 2s
 * disposal.  So, in the middle of DoComposite when composing Frame 3, right
 * after destroying Frame 2's area, we copy compositingFrame to
 * prevCompositingFrame.  When DoComposite gets called to do Frame 4, we
 * copy prevCompositingFrame back, and then draw Frame 4 on top.
 *
 * @par
 * The mAnim structure has members only needed for animated images, so
 * it's not allocated until the second frame is added.
 *
 * @note
 * mAnimationMode, mLoopCount and mObserver are not in the mAnim structure
 * because the first two have public setters and the observer we only get
 * in Init().
 */

namespace mozilla {
namespace layers {
class LayerManager;
class ImageContainer;
class Image;
}
namespace image {

class Decoder;

class RasterImage : public Image
                  , public nsIProperties
                  , public SupportsWeakPtr<RasterImage>
#ifdef DEBUG
                  , public imgIContainerDebug
#endif
{
public:
  NS_DECL_ISUPPORTS
  NS_DECL_NSIPROPERTIES
#ifdef DEBUG
  NS_DECL_IMGICONTAINERDEBUG
#endif

  // BEGIN NS_DECL_IMGICONTAINER (minus GetAnimationMode/SetAnimationMode)
  // ** Don't edit this chunk except to mirror changes in imgIContainer.idl **
  NS_IMETHOD GetWidth(int32_t *aWidth);
  NS_IMETHOD GetHeight(int32_t *aHeight);
  NS_IMETHOD GetType(uint16_t *aType);
  NS_IMETHOD_(uint16_t) GetType(void);
  NS_IMETHOD GetAnimated(bool *aAnimated);
  NS_IMETHOD GetCurrentFrameIsOpaque(bool *aCurrentFrameIsOpaque);
  NS_IMETHOD GetFrame(uint32_t aWhichFrame, uint32_t aFlags, gfxASurface **_retval);
  NS_IMETHOD GetImageContainer(mozilla::layers::ImageContainer **_retval);
  NS_IMETHOD CopyFrame(uint32_t aWhichFrame, uint32_t aFlags, gfxImageSurface **_retval);
  NS_IMETHOD ExtractFrame(uint32_t aWhichFrame, const nsIntRect & aRect, uint32_t aFlags, imgIContainer **_retval);
  NS_IMETHOD Draw(gfxContext *aContext, gfxPattern::GraphicsFilter aFilter, const gfxMatrix & aUserSpaceToImageSpace, const gfxRect & aFill, const nsIntRect & aSubimage, const nsIntSize & aViewportSize, uint32_t aFlags);
  NS_IMETHOD_(nsIFrame *) GetRootLayoutFrame(void);
  NS_IMETHOD RequestDecode(void);
  NS_IMETHOD LockImage(void);
  NS_IMETHOD UnlockImage(void);
  NS_IMETHOD RequestDiscard(void);
  NS_IMETHOD ResetAnimation(void);
  NS_IMETHOD_(void) RequestRefresh(const mozilla::TimeStamp& aTime);
  // END NS_DECL_IMGICONTAINER

  RasterImage(imgStatusTracker* aStatusTracker = nullptr);
  virtual ~RasterImage();

  virtual nsresult StartAnimation();
  virtual nsresult StopAnimation();

  // Methods inherited from Image
  nsresult Init(imgIDecoderObserver* aObserver,
                const char* aMimeType,
                const char* aURIString,
                uint32_t aFlags);
  void     GetCurrentFrameRect(nsIntRect& aRect);

  // Raster-specific methods
  static NS_METHOD WriteToRasterImage(nsIInputStream* aIn, void* aClosure,
                                      const char* aFromRawSegment,
                                      uint32_t aToOffset, uint32_t aCount,
                                      uint32_t* aWriteCount);

  /* The index of the current frame that would be drawn if the image was to be
   * drawn now. */
  uint32_t GetCurrentFrameIndex();

  /* The total number of frames in this image. */
  uint32_t GetNumFrames();

  virtual size_t HeapSizeOfSourceWithComputedFallback(nsMallocSizeOfFun aMallocSizeOf) const;
  virtual size_t HeapSizeOfDecodedWithComputedFallback(nsMallocSizeOfFun aMallocSizeOf) const;
  virtual size_t NonHeapSizeOfDecoded() const;
  virtual size_t OutOfProcessSizeOfDecoded() const;

  /* Triggers discarding. */
  void Discard(bool force = false);
  void ForceDiscard() { Discard(/* force = */ true); }

  /* Callbacks for decoders */
  nsresult SetFrameDisposalMethod(uint32_t aFrameNum,
                                  int32_t aDisposalMethod);
  nsresult SetFrameTimeout(uint32_t aFrameNum, int32_t aTimeout);
  nsresult SetFrameBlendMethod(uint32_t aFrameNum, int32_t aBlendMethod);
  nsresult SetFrameHasNoAlpha(uint32_t aFrameNum);
  nsresult SetFrameAsNonPremult(uint32_t aFrameNum, bool aIsNonPremult);

  /**
   * Sets the size of the container. This should only be called by the
   * decoder. This function may be called multiple times, but will throw an
   * error if subsequent calls do not match the first.
   */
  nsresult SetSize(int32_t aWidth, int32_t aHeight);

  /**
   * Ensures that a given frame number exists with the given parameters, and
   * returns pointers to the data storage for that frame.
   * It is not possible to create sparse frame arrays; you can only append
   * frames to the current frame array.
   */
  nsresult EnsureFrame(uint32_t aFramenum, int32_t aX, int32_t aY,
                       int32_t aWidth, int32_t aHeight,
                       gfxASurface::gfxImageFormat aFormat,
                       uint8_t aPaletteDepth,
                       uint8_t** imageData,
                       uint32_t* imageLength,
                       uint32_t** paletteData,
                       uint32_t* paletteLength);

  /**
   * A shorthand for EnsureFrame, above, with aPaletteDepth = 0 and paletteData
   * and paletteLength set to null.
   */
  nsresult EnsureFrame(uint32_t aFramenum, int32_t aX, int32_t aY,
                       int32_t aWidth, int32_t aHeight,
                       gfxASurface::gfxImageFormat aFormat,
                       uint8_t** imageData,
                       uint32_t* imageLength);

  void FrameUpdated(uint32_t aFrameNum, nsIntRect& aUpdatedRect);

  /* notification that the entire image has been decoded */
  nsresult DecodingComplete();

  /**
   * Number of times to loop the image.
   * @note -1 means forever.
   */
  void     SetLoopCount(int32_t aLoopCount);

  /* Add compressed source data to the imgContainer.
   *
   * The decoder will use this data, either immediately or at draw time, to
   * decode the image.
   *
   * XXX This method's only caller (WriteToContainer) ignores the return
   * value. Should this just return void?
   */
  nsresult AddSourceData(const char *aBuffer, uint32_t aCount);

  /* Called after the all the source data has been added with addSourceData. */
  nsresult SourceDataComplete();

  /* Called for multipart images when there's a new source image to add. */
  nsresult NewSourceData();

  /**
   * A hint of the number of bytes of source data that the image contains. If
   * called early on, this can help reduce copying and reallocations by
   * appropriately preallocating the source data buffer.
   *
   * We take this approach rather than having the source data management code do
   * something more complicated (like chunklisting) because HTTP is by far the
   * dominant source of images, and the Content-Length header is quite reliable.
   * Thus, pre-allocation simplifies code and reduces the total number of
   * allocations.
   */
  nsresult SetSourceSizeHint(uint32_t sizeHint);

  // "Blend" method indicates how the current image is combined with the
  // previous image.
  enum {
    // All color components of the frame, including alpha, overwrite the current
    // contents of the frame's output buffer region
    kBlendSource =  0,

    // The frame should be composited onto the output buffer based on its alpha,
    // using a simple OVER operation
    kBlendOver
  };

  enum {
    kDisposeClearAll         = -1, // Clear the whole image, revealing
                                   // what was there before the gif displayed
    kDisposeNotSpecified,   // Leave frame, let new frame draw on top
    kDisposeKeep,           // Leave frame, let new frame draw on top
    kDisposeClear,          // Clear the frame's area, revealing bg
    kDisposeRestorePrevious // Restore the previous (composited) frame
  };

  const char* GetURIString() { return mURIString.get();}

  // Called from module startup. Sets up RasterImage to be used.
  static void Initialize();

private:
  struct Anim
  {
    //! Area of the first frame that needs to be redrawn on subsequent loops.
    nsIntRect                  firstFrameRefreshArea;
    uint32_t                   currentAnimationFrameIndex; // 0 to numFrames-1

    // the time that the animation advanced to the current frame
    TimeStamp                  currentAnimationFrameTime;

    //! Track the last composited frame for Optimizations (See DoComposite code)
    int32_t                    lastCompositedFrameIndex;
    /** For managing blending of frames
     *
     * Some animations will use the compositingFrame to composite images
     * and just hand this back to the caller when it is time to draw the frame.
     * NOTE: When clearing compositingFrame, remember to set
     *       lastCompositedFrameIndex to -1.  Code assume that if
     *       lastCompositedFrameIndex >= 0 then compositingFrame exists.
     */
    nsAutoPtr<imgFrame>        compositingFrame;
    /** the previous composited frame, for DISPOSE_RESTORE_PREVIOUS
     *
     * The Previous Frame (all frames composited up to the current) needs to be
     * stored in cases where the image specifies it wants the last frame back
     * when it's done with the current frame.
     */
    nsAutoPtr<imgFrame>        compositingPrevFrame;

    Anim() :
      firstFrameRefreshArea(),
      currentAnimationFrameIndex(0),
      lastCompositedFrameIndex(-1) {}
    ~Anim() {}
  };

  /**
   * DecodeWorker keeps a linked list of DecodeRequests to keep track of the
   * images it needs to decode.
   *
   * Each RasterImage has a single DecodeRequest member.
   */
  struct DecodeRequest : public LinkedListElement<DecodeRequest>
  {
    DecodeRequest(RasterImage* aImage)
      : mImage(aImage)
      , mIsASAP(false)
    {
    }

    RasterImage* const mImage;

    /* Keeps track of how much time we've burned decoding this particular decode
     * request. */
    TimeDuration mDecodeTime;

    /* True if we need to handle this decode as soon as possible. */
    bool mIsASAP;
  };

  /*
   * DecodeWorker is a singleton class we use when decoding large images.
   *
   * When we wish to decode an image larger than
   * image.mem.max_bytes_for_sync_decode, we call DecodeWorker::RequestDecode()
   * for the image.  This adds the image to a queue of pending requests and posts
   * the DecodeWorker singleton to the event queue, if it's not already pending
   * there.
   *
   * When the DecodeWorker is run from the event queue, it decodes the image (and
   * all others it's managing) in chunks, periodically yielding control back to
   * the event loop.
   *
   * An image being decoded may have one of two priorities: normal or ASAP.  ASAP
   * images are always decoded before normal images.  (We currently give ASAP
   * priority to images which appear onscreen but are not yet decoded.)
   */
  class DecodeWorker : public nsRunnable
  {
  public:
    static DecodeWorker* Singleton();

    /**
     * Ask the DecodeWorker to asynchronously decode this image.
     */
    void RequestDecode(RasterImage* aImg);

    /**
     * Decode aImg for a short amount of time, and post the remainder to the
     * queue.
     */
    void DecodeABitOf(RasterImage* aImg);

    /**
     * Give this image ASAP priority; it will be decoded before all non-ASAP
     * images.  You can call MarkAsASAP before or after you call RequestDecode
     * for the image, but if you MarkAsASAP before you call RequestDecode, you
     * still need to call RequestDecode.
     *
     * StopDecoding() resets the image's ASAP flag.
     */
    void MarkAsASAP(RasterImage* aImg);

    /**
     * Ask the DecodeWorker to stop decoding this image.  Internally, we also
     * call this function when we finish decoding an image.
     *
     * Since the DecodeWorker keeps raw pointers to RasterImages, make sure you
     * call this before a RasterImage is destroyed!
     */
    void StopDecoding(RasterImage* aImg);

    /**
     * Synchronously decode the beginning of the image until we run out of
     * bytes or we get the image's size.  Note that this done on a best-effort
     * basis; if the size is burried too deep in the image, we'll give up.
     *
     * @return NS_ERROR if an error is encountered, and NS_OK otherwise.  (Note
     *         that we return NS_OK even when the size was not found.)
     */
    nsresult DecodeUntilSizeAvailable(RasterImage* aImg);

    NS_IMETHOD Run();

  private: /* statics */
    static StaticRefPtr<DecodeWorker> sSingleton;

  private: /* methods */
    DecodeWorker()
      : mPendingInEventLoop(false)
    {}

    /* Post ourselves to the event loop if we're not currently pending. */
    void EnsurePendingInEventLoop();

    /* Add the given request to the appropriate list of decode requests, but
     * don't ensure that we're pending in the event loop. */
    void AddDecodeRequest(DecodeRequest* aRequest);

    enum DecodeType {
      DECODE_TYPE_NORMAL,
      DECODE_TYPE_UNTIL_SIZE
    };

    /* Decode some chunks of the given image.  If aDecodeType is UNTIL_SIZE,
     * decode until we have the image's size, then stop. */
    nsresult DecodeSomeOfImage(RasterImage* aImg,
                               DecodeType aDecodeType = DECODE_TYPE_NORMAL);

  private: /* members */

    LinkedList<DecodeRequest> mASAPDecodeRequests;
    LinkedList<DecodeRequest> mNormalDecodeRequests;

    /* True if we've posted ourselves to the event loop and expect Run() to
     * be called sometime in the future. */
    bool mPendingInEventLoop;
  };

  struct ScaleRequest : public LinkedListElement<ScaleRequest>
  {
    ScaleRequest(RasterImage* aImage)
      : image(aImage)
      , srcFrame(nullptr)
      , dstFrame(nullptr)
      , scale(0, 0)
      , done(false)
      , stopped(false)
      , srcDataLocked(false)
    {};

    bool LockSourceData()
    {
      if (!srcDataLocked) {
        bool success = true;
        success = success && NS_SUCCEEDED(image->LockImage());
        success = success && NS_SUCCEEDED(srcFrame->LockImageData());
        srcDataLocked = success;
      }
      return srcDataLocked;
    }

    bool UnlockSourceData()
    {
      bool success = true;
      if (srcDataLocked) {
        success = success && NS_SUCCEEDED(image->UnlockImage());
        success = success && NS_SUCCEEDED(srcFrame->UnlockImageData());

        // If unlocking fails, there's nothing we can do to make it work, so we
        // claim that we're not locked regardless.
        srcDataLocked = false;
      }
      return success;
    }

    static void Stop(RasterImage* aImg);

    RasterImage* const image;
    imgFrame *srcFrame;
    nsAutoPtr<imgFrame> dstFrame;
    gfxSize scale;
    bool done;
    bool stopped;
    bool srcDataLocked;
  };

  class ScaleWorker : public nsRunnable
  {
  public:
    static ScaleWorker* Singleton();

    NS_IMETHOD Run();

  /* statics */
    static nsRefPtr<ScaleWorker> sSingleton;

  private: /* methods */
    ScaleWorker()
      : mRequestsMutex("RasterImage.ScaleWorker.mRequestsMutex")
      , mInitialized(false)
    {};

    // Note: you MUST call RequestScale with the ScaleWorker mutex held.
    void RequestScale(RasterImage* aImg);

  private: /* members */

    friend class RasterImage;
    LinkedList<ScaleRequest> mScaleRequests;
    Mutex mRequestsMutex;
    bool mInitialized;
  };

  class DrawWorker : public nsRunnable
  {
  public:
    static DrawWorker* Singleton();

    NS_IMETHOD Run();

  /* statics */
    static nsRefPtr<DrawWorker> sSingleton;

  private: /* methods */
    DrawWorker() {};

    void RequestDraw(RasterImage* aImg);

  private: /* members */

    friend class RasterImage;
    LinkedList<ScaleRequest> mDrawRequests;
  };

  void DrawWithPreDownscaleIfNeeded(imgFrame *aFrame,
                                    gfxContext *aContext,
                                    gfxPattern::GraphicsFilter aFilter,
                                    const gfxMatrix &aUserSpaceToImageSpace,
                                    const gfxRect &aFill,
                                    const nsIntRect &aSubimage);

  /**
   * Advances the animation. Typically, this will advance a single frame, but it
   * may advance multiple frames. This may happen if we have infrequently
   * "ticking" refresh drivers (e.g. in background tabs), or extremely short-
   * lived animation frames.
   *
   * @param aTime the time that the animation should advance to. This will
   *              typically be <= TimeStamp::Now().
   *
   * @param [out] aDirtyRect a pointer to an nsIntRect which encapsulates the
   *        area to be repainted after the frame is advanced.
   *
   * @returns true, if the frame was successfully advanced, false if it was not
   *          able to be advanced (e.g. the frame to which we want to advance is
   *          still decoding). Note: If false is returned, then aDirtyRect will
   *          remain unmodified.
   */
  bool AdvanceFrame(mozilla::TimeStamp aTime, nsIntRect* aDirtyRect);

  /**
   * Deletes and nulls out the frame in mFrames[framenum].
   *
   * Does not change the size of mFrames.
   *
   * @param framenum The index of the frame to be deleted.
   *                 Must lie in [0, mFrames.Length() )
   */
  void DeleteImgFrame(uint32_t framenum);

  imgFrame* GetImgFrameNoDecode(uint32_t framenum);
  imgFrame* GetImgFrame(uint32_t framenum);
  imgFrame* GetDrawableImgFrame(uint32_t framenum);
  imgFrame* GetCurrentImgFrame();
  imgFrame* GetCurrentDrawableImgFrame();
  uint32_t GetCurrentImgFrameIndex() const;
  mozilla::TimeStamp GetCurrentImgFrameEndTime() const;

  inline void EnsureAnimExists()
  {
    if (!mAnim) {

      // Create the animation context
      mAnim = new Anim();

      // We don't support discarding animated images (See bug 414259).
      // Lock the image and throw away the key.
      //
      // Note that this is inefficient, since we could get rid of the source
      // data too. However, doing this is actually hard, because we're probably
      // calling ensureAnimExists mid-decode, and thus we're decoding out of
      // the source buffer. Since we're going to fix this anyway later, and
      // since we didn't kill the source data in the old world either, locking
      // is acceptable for the moment.
      LockImage();

      // Notify our observers that we are starting animation.
      mStatusTracker->RecordImageIsAnimated();
    }
  }

  /** Function for doing the frame compositing of animations
   *
   * @param aDirtyRect  Area that the display will need to update
   * @param aPrevFrame  Last Frame seen/processed
   * @param aNextFrame  Frame we need to incorperate/display
   * @param aNextFrameIndex Position of aNextFrame in mFrames list
   */
  nsresult DoComposite(nsIntRect* aDirtyRect,
                       imgFrame* aPrevFrame,
                       imgFrame* aNextFrame,
                       int32_t aNextFrameIndex);

  /** Clears an area of <aFrame> with transparent black.
   *
   * @param aFrame Target Frame
   *
   * @note Does also clears the transparancy mask
   */
  static void ClearFrame(imgFrame* aFrame);

  //! @overload
  static void ClearFrame(imgFrame* aFrame, nsIntRect &aRect);

  //! Copy one frames's image and mask into another
  static bool CopyFrameImage(imgFrame *aSrcFrame,
                               imgFrame *aDstFrame);

  /** Draws one frames's image to into another,
   * at the position specified by aRect
   *
   * @param aSrcFrame  Frame providing the source image
   * @param aDstFrame  Frame where the image is drawn into
   * @param aRect      The position and size to draw the image
   */
  static nsresult DrawFrameTo(imgFrame *aSrcFrame,
                              imgFrame *aDstFrame,
                              nsIntRect& aRect);

  nsresult InternalAddFrameHelper(uint32_t framenum, imgFrame *frame,
                                  uint8_t **imageData, uint32_t *imageLength,
                                  uint32_t **paletteData, uint32_t *paletteLength);
  nsresult InternalAddFrame(uint32_t framenum, int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight,
                            gfxASurface::gfxImageFormat aFormat, uint8_t aPaletteDepth,
                            uint8_t **imageData, uint32_t *imageLength,
                            uint32_t **paletteData, uint32_t *paletteLength);

  bool ApplyDecodeFlags(uint32_t aNewFlags);

  already_AddRefed<layers::Image> GetCurrentImage();
  void UpdateImageContainer();

  void SetInUpdateImageContainer(bool aInUpdate) { mInUpdateImageContainer = aInUpdate; }
  bool IsInUpdateImageContainer() { return mInUpdateImageContainer; }

private: // data

  nsIntSize                  mSize;

  // Whether mFrames below were decoded using any special flags.
  // Some flags (e.g. unpremultiplied data) may not be compatible
  // with the browser's needs for displaying the image to the user.
  // As such, we may need to redecode if we're being asked for
  // a frame with different flags.  0 indicates default flags.
  //
  // Valid flag bits are imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA
  // and imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION.
  uint32_t                   mFrameDecodeFlags;

  //! All the frames of the image
  // IMPORTANT: if you use mFrames in a method, call EnsureImageIsDecoded() first
  // to ensure that the frames actually exist (they may have been discarded to save
  // memory, or we may be decoding on draw).
  nsTArray<imgFrame *>       mFrames;

  nsCOMPtr<nsIProperties>    mProperties;

  // IMPORTANT: if you use mAnim in a method, call EnsureImageIsDecoded() first to ensure
  // that the frames actually exist (they may have been discarded to save memory, or
  // we maybe decoding on draw).
  RasterImage::Anim*        mAnim;

  //! # loops remaining before animation stops (-1 no stop)
  int32_t                    mLoopCount;

  //! imgIDecoderObserver
  nsWeakPtr                  mObserver;

  // Discard members
  uint32_t                   mLockCount;
  DiscardTracker::Node       mDiscardTrackerNode;

  // Source data members
  FallibleTArray<char>       mSourceData;
  nsCString                  mSourceDataMimeType;
  nsCString                  mURIString;

  friend class DiscardTracker;

  // Decoder and friends
  nsRefPtr<Decoder>              mDecoder;
  DecodeRequest                  mDecodeRequest;
  uint32_t                       mBytesDecoded;

  // How many times we've decoded this image.
  // This is currently only used for statistics
  int32_t                        mDecodeCount;

  // Cached value for GetImageContainer.
  nsRefPtr<mozilla::layers::ImageContainer> mImageContainer;

#ifdef DEBUG
  uint32_t                       mFramesNotified;
#endif

  // Boolean flags (clustered together to conserve space):
  bool                       mHasSize:1;       // Has SetSize() been called?
  bool                       mDecodeOnDraw:1;  // Decoding on draw?
  bool                       mMultipart:1;     // Multipart?
  bool                       mDiscardable:1;   // Is container discardable?
  bool                       mHasSourceData:1; // Do we have source data?

  // Do we have the frames in decoded form?
  bool                       mDecoded:1;
  bool                       mHasBeenDecoded:1;

  bool                       mInDecoder:1;

  // Whether the animation can stop, due to running out
  // of frames, or no more owning request
  bool                       mAnimationFinished:1;

  // Whether we're calling Decoder::Finish() from ShutdownDecoder.
  bool                       mFinishing:1;

  bool                       mInUpdateImageContainer:1;

  // Decoding
  nsresult WantDecodedFrames();
  nsresult SyncDecode();
  nsresult InitDecoder(bool aDoSizeDecode);
  nsresult WriteToDecoder(const char *aBuffer, uint32_t aCount);
  nsresult DecodeSomeData(uint32_t aMaxBytes);
  bool     IsDecodeFinished();
  TimeStamp mDrawStartTime;

  inline bool CanScale(gfxPattern::GraphicsFilter aFilter, gfxSize aScale);
  ScaleRequest mScaleRequest;

  // Decoder shutdown
  enum eShutdownIntent {
    eShutdownIntent_Done        = 0,
    eShutdownIntent_Interrupted = 1,
    eShutdownIntent_Error       = 2,
    eShutdownIntent_AllCount    = 3
  };
  nsresult ShutdownDecoder(eShutdownIntent aIntent);

  // Helpers
  void DoError();
  bool CanDiscard();
  bool CanForciblyDiscard();
  bool DiscardingActive();
  bool StoringSourceData() const;

protected:
  bool ShouldAnimate();
};

// Asynchronous Decode Requestor
//
// We use this class when someone calls requestDecode() from within a decode
// notification. Since requestDecode() involves modifying the decoder's state
// (for example, possibly shutting down a header-only decode and starting a
// full decode), we don't want to do this from inside a decoder.
class imgDecodeRequestor : public nsRunnable
{
  public:
    imgDecodeRequestor(RasterImage &aContainer) {
      mContainer = aContainer.asWeakPtr();
    }
    NS_IMETHOD Run() {
      if (mContainer)
        mContainer->RequestDecode();
      return NS_OK;
    }

  private:
    WeakPtr<RasterImage> mContainer;
};

} // namespace image
} // namespace mozilla

#endif /* mozilla_imagelib_RasterImage_h_ */

redpajama_set_name: RedPajamaGithub


text:
Share this Story: Jagmeet Singh accused of inflating party membership signups
Jagmeet Singh accused of inflating party membership signups
As the NDP leadership race tightens, Charlie Angus's campaign is crying foul on the figures released by the Singh team
Ontario deputy NDP leader Jagmeet Singh is being accused by a rival campaign that his membership signups were inflated. Photo by Nathan Denette/The Canadian Press
OTTAWA — A rival campaign in the federal NDP leadership race is accusing candidate Jagmeet Singh of inflating the number of new party members he signed up.
Singh announced Tuesday he had signed up 47,000-plus new people, more than a third of the 124,000 the party says are eligible to vote this fall.
Jagmeet Singh accused of inflating party membership signups Back to video
But Charlie Angus's campaign says this number doesn't make sense, based on how many people were members of the party at the beginning of May before Singh entered the race.
" Looking back through the records of the updating of the party database, of the membership, we found that we are approximately around 41,000 around the end of March, as the party reported. However, by the beginning of May, the party had updated the database systems and the party list and we were at about 70,000 members at that point," said Jesse Brady, a co-campaign manager for Angus.
The difference would be roughly 54,000 new members between early May and the party's announcement this week. Singh's number would leave only 7,000 new members signed up through other channels.
"It's hard to see how any one campaign can claim that they then signed up all of the rest of the membership from that point on. That would exclude the efforts that our campaign and the other campaigns had also done."
Several attempts to reach Singh's campaign team Wednesday were unsuccessful. One of the two other campaigns confirmed the 70,000 number looks accurate, but they did not want to say so on the record unless the third campaign would corroborate it. The third campaign was unable to reach its data team to confirm the number.
Jagmeet Singh fundraises nearly three times his nearest rival despite later entry in NDP leadership race
Angus heads to Singh's backyard in attempt to win support from Muslim community
NDP leadership candidate Niki Ashton expecting twins shortly after race ends in November
A party official said the number of active, in-good-standing members was roughly the same in May as in March: just over 41,000. Additional names in the database were likely people whose memberships had lapsed, they said, though admitting that because of how the database system works, it would be difficult to go back and get a precise number from May.
That the party didn't bring in new members for over a month doesn't ring true to Brady, since it was a busy time during which leadership candidates were getting their campaigns underway.
And since provincial and federal branches of the NDP are connected, new members were coming not just from nascent leadership campaigns, but also from sign-ups generated by the B.C. provincial election, a leadership race in Manitoba, the nomination of candidates in Ontario and an upcoming leadership race in Saskatchewan — though provincial sign-ups weren't automatically entered into the federal database.
Not to mention there has been an ongoing drive by the federal party to increase memberships and renewals during its leadership race, which officially started in summer 2016.
Brady added many of the "new" names could have been renewals from lapsed members, but said the Angus database was checked for duplicates and they are confident in their number.
A spokesperson for candidate Niki Ashton's campaign said they had always expected "amazing numbers" from the Singh campaign. "Of course he brings good energy to the race, and it's a new kind of energy, if I could say, because he comes from the Ontario legislature," they said.
They wouldn't comment on whether Singh's numbers made sense to them, but said they were "extremely proud" of their own numbers. "We over-achieved our goal," the spokesperson said.
"Just like in any election, we won't be releasing our numbers. We're not going to give our marks to our colleagues, a.k.a. opponents."
Neither would Angus nor leadership hopeful Guy Caron show their cards, though Brady said "we hit all of our membership targets across the country and it reassures us that Charlie will win this thing."
A spokesperson for Caron's campaign said the numbers released this week, including those put out by Singh's campaign, suggest Singh won't win on the first ballot.
"That is great news for us," they said, citing Caron's potential for second-ballot support. Of Singh's numbers, they said, "it's kind of odd that you're putting it out there. Even with their number, with that number, it's hard to see a first-ballot win … We have a race."
Strategists are divided on whether Singh can pull off a first-ballot victory.
" The Singh camp strategy has always been to try and sign up as many members as possible," said Karl Bélanger, a longtime NDP strategist.
He noted about half of the membership ends up casting ballots in most leadership contests, including the 2012 NDP race. "If Singh's new members do show up en masse, then he has a good chance of winning. But if they show up at a lower rate, then he has to convince a good chunk of the long-standing members," he said. "At the end of the day, the name of the game is voter turnout."
Bélanger said it would surprise him if someone was able to snag a win on the first ballot. Although many are predicting the race will come down to Angus and Singh, he said Caron's second-ballot support seems to be the highest, and with an endorsement from former leader Alexa McDonough Wednesday, "he has a bit of momentum."
Party veteran Robin Sears cautioned it's irresponsible for campaigns to accuse others of blowing smoke. "My gut would tell me that (inflating numbers) wouldn't be a very smart thing for Jagmeet's campaign to do, so why would they do it?"
Sears said he thinks the race will come down to Singh or Angus. He was readier to opine that a first-ballot victory is possible. "In fact, I would say it's more likely than not," Sears said. "If Charlie's people's allegations are accurate, then Jagmeet would have less of an advantage."
• Email: mdsmith@postmedia.com | Twitter: mariedanielles

redpajama_set_name: RedPajamaCommonCrawl


text:
emanuel dimas de melo pimenta
virtual music scores
In the end of the 1970s, Emanuel Pimenta elaborated a new method for music composition and notation inside virtual environments. Starting from the two-dimensional graphical scores, also known as planimetrics, Pimenta expanded to four-dimensional systems. He studied with the German composer Hans Joachim Koellreutter - pupil of Paul Hindemith, Marcel Moyse, Kurt Thomas and Hermann Scherchen - among others. Pimenta recorded about four hundred compositions in electronic, digital, acoustic and electroacoustic music. Beyond the concerts his music has been regularly used in movies, television, contemporary art installations, video art and dance in various countries. Several of his compositions can be listen in his online radio. Since 1986, after a personal invitation by John Cage, he has been commissioned composer for Merce Cunningham in New York City. Many people ask about listening to his music in this site - the problem is that Emanuel Pimenta works with a wide range of frequencies, and that compression systems like MP3 eliminate a good part of them. But you can listen to some of his pieces in some films in the link bellow. His concerts have been performed in some of the most important theatres and contemporary art museums all over the world with great recognition. His musical works, from large ensembles to electronics, from solo acoustic instruments to digital music, have been mainly performed in art museums, galleries and cultural centres as artworks. In general, each concert by Emanuel Pimenta is a complete work, from conceptual art to pure music, lectures and theoretical papers. In this site, you can see some of his virtual music scores, music scores as artworks, sites about some of his concerts, papers and books that are part of the concerts and on the subject. Emanuel Pimenta's first instrument is the transversal flute. Both on architecture and on music, Emanuel Pimenta works on the establishment of sensorial design - a term coined by him in the 1980s - and its implications in the plastic formation of synaptic patterns; it is what he calls logical traps.
click here for films on emanuel pimenta's concerts
radio - listen to the music
music scores as artworks
visual art and concerts
ebooks and papers
listen his music... in films


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

using MatterHackers.Agg.Image;
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using MatterHackers.VectorMath;
using MatterHackers.MatterControl;
using MatterHackers.MatterControl.DataStorage;
using MatterHackers.MatterControl.PrintQueue;
using MatterHackers.MatterControl.SettingsManagement;

namespace MatterHackers.MatterControl.PrintLibrary
{
    public class LibraryData
    {
        private List<PrintItemWrapper> printItems = new List<PrintItemWrapper>();
        private List<PrintItemWrapper> PrintItems
        {
            get { return printItems; }
        }

        public RootedObjectEventHandler DataReloaded = new RootedObjectEventHandler();
        public RootedObjectEventHandler ItemAdded = new RootedObjectEventHandler();
        public RootedObjectEventHandler ItemRemoved = new RootedObjectEventHandler();
        public RootedObjectEventHandler OrderChanged = new RootedObjectEventHandler();

        private DataStorage.PrintItemCollection libraryCollection;

        static LibraryData instance;
        public static LibraryData Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new LibraryData();
                    instance.LoadLibraryItems();
                }
                return instance;
            }
        }

        string keywordFilter = "";
        public string KeywordFilter
        {
            get { return keywordFilter; }
            set
            {
                if (this.keywordFilter != value)
                {
                    this.keywordFilter = value;
                    LoadLibraryItems();
                }
            }
        }

        public void AddItem(PrintItemWrapper item, int indexToInsert = -1)
        {
            if (indexToInsert == -1)
            {
                indexToInsert = PrintItems.Count;
            }
            PrintItems.Insert(indexToInsert, item);
            OnItemAdded(new IndexArgs(indexToInsert));
        }

        public void RemoveItem(PrintItemWrapper printItemWrapper)
        {
            int index = PrintItems.IndexOf(printItemWrapper);
            if (index < 0)
            {
                // It may be possible to have the same item in the remove list twice.
                // so if it is not in the PrintItems then ignore it.
                return;
            }
            PrintItems.RemoveAt(index);

            // and remove it from the data base
            printItemWrapper.Delete();

            OnItemRemoved(new IndexArgs(index));
        }

        public PrintItemWrapper GetPrintItemWrapper(int index)
        {
            if(index >= 0 && index < Count)
            {
                return PrintItems[index];
            }

            return null;
        }

        public List<PrintItem> CreateReadOnlyPartList()
        {
            List<PrintItem> listToReturn = new List<PrintItem>();
            for (int i = 0; i < Count; i++)
            {
                listToReturn.Add(GetPrintItemWrapper(i).PrintItem);
            }
            return listToReturn;
        }

        public DataStorage.PrintItemCollection LibraryCollection
        {
            get
            {
                //Retrieve a list of saved printers from the Datastore
                if (libraryCollection == null)
                {
                    libraryCollection = DataStorage.Datastore.Instance.dbSQLite.Table<DataStorage.PrintItemCollection>().Where(v => v.Name == "_library").Take(1).FirstOrDefault();
                }

                if (libraryCollection == null)
                {
                    libraryCollection = new PrintItemCollection();
                    libraryCollection.Name = "_library";
                    libraryCollection.Commit();
                    PreloadLibrary();
                }
                return libraryCollection;
            }
        }

        void PreloadLibrary()
        {
            foreach (string partFile in OemSettings.Instance.PreloadedLibraryFiles)
            {
                string partFullPath = Path.Combine(ApplicationDataStorage.Instance.ApplicationStaticDataPath, "OEMSettings", "SampleParts", partFile);
                if (System.IO.File.Exists(partFullPath))
                {
                    PrintItem printItem = new PrintItem();
                    printItem.Name = Path.GetFileNameWithoutExtension(partFullPath);
                    printItem.FileLocation = Path.GetFullPath(partFullPath);
                    printItem.PrintItemCollectionID = LibraryCollection.Id;
                    printItem.Commit();
                }
            }
        }

        IEnumerable<DataStorage.PrintItem> GetLibraryItems(string keyphrase = null)
        {
            if (LibraryCollection == null)
            {
                return null;
            }
            else
            {
                string query;
                if (keyphrase == null)
                {
                    query = string.Format("SELECT * FROM PrintItem WHERE PrintItemCollectionID = {0} ORDER BY Name ASC;", libraryCollection.Id);
                }
                else
                {
                    query = string.Format("SELECT * FROM PrintItem WHERE PrintItemCollectionID = {0} AND Name LIKE '%{1}%' ORDER BY Name ASC;", libraryCollection.Id, keyphrase);
                }
                IEnumerable<DataStorage.PrintItem> result = (IEnumerable<DataStorage.PrintItem>)DataStorage.Datastore.Instance.dbSQLite.Query<DataStorage.PrintItem>(query);
                return result;
            }
        }

        public void LoadLibraryItems()
        {
            PrintItems.Clear();
            IEnumerable<DataStorage.PrintItem> partFiles = GetLibraryItems(keywordFilter);
            if (partFiles != null)
            {
                foreach (PrintItem part in partFiles)
                {
                    PrintItems.Add(new PrintItemWrapper(part));

                }
            }
            OnDataReloaded(null);
        }

        public void OnDataReloaded(EventArgs e)
        {
            DataReloaded.CallEvents(this, e);
        }

        public void OnItemAdded(EventArgs e)
        {
            ItemAdded.CallEvents(this, e);
        }

        public void OnItemRemoved(EventArgs e)
        {
            ItemRemoved.CallEvents(this, e);
        }

        public void SaveLibraryItems()
        {
            //
        }

        public int Count
        {
            get
            {
                return PrintItems.Count;
            }
        }
    }
}


text:
Editor's Note: Two Transitions
We live, clearly, in a time of change. For most people my age, President Bush has been the dominant figure for about as long as we've paid any attention to politics. And for many of my generation, he has been the touchstone by which to judge our own views about the world, as well as an inspiration for defiance and rebellion. Indeed, to countless Americans, President Bush has become the embodiment of all that is wrong with the world.
This view will change.
Now, I don't pretend to ignore his many mistakes in office. Only blind partisanship could provoke one to make the case that Bush has been a perfect president. But it would equally partisan—and more vitriolic—to ignore his successes.
In the wake of 9/11, virtually no one would have guessed that we could go over seven years without a terrorist attack. We have, in effect, batted a thousand on that very important front. This is no small accomplishment.
On the other hand, many pontificated that our first retaliatory measure—invading Afghanistan—was doomed to certain disaster. Despite the warnings that we were charging headfirst into the "graveyard of empires," catastrophe has not followed. The situation there certainly isn't perfect and our mission there clearly isn't complete, but Afghanistan has not become a Middle Eastern Vietnam.
Nor, for that matter, has Iraq. Admittedly, the mistakes made both during the invasion and in its aftermath were many. I do not believe that Bush was personally at fault for a great deal of them, but I do believe that he delegated to the wrong people and demanded little accountability in return—and that, certainly, is a substantial problem. The buck, after all, stops here.
But while we came close to defeat in the sands of Iraq, those days are behind us. By nearly any metric—American casualties, sectarian killings, political participation, functioning government—the situation in Iraq has improved drastically in Iraq. Victory is now well within sight. And so when the chips were on the table, when America was against the ropes, President Bush chose the right strategy and the right man to lead it.
Granted, it would have been preferable to have the right plan from the get-go, but Bush still deserves a measure of praise for his handling of the war. Yet, he has not received commensurate commendation—or anything close to it—for Iraq's miraculous turnaround. In fact, it seems that every other car here in Palo Alto is adorned with bumper stickers screaming "End this War!" or "US out of Iraq now!" If the locals had their way, one imagines, the American military would have to lay down its arms and roll out the red carpet for Al-Qaeda, just to prove that President Bush had been wrong all along.
This fanaticism will change.
In time, President Bush will be vindicated—to some extent—by history. He will not, I am sure, go down as the greatest leader of his time. But nor will he be remembered as the worst. He will be remembered as a man who presided over a turbulent time in history, and left office with a decidedly mixed record.
This nuance, however, is completely absent in the perceptions of his successor. Rather, our new president, Barack Obama, is hailed at home and abroad as a savior in the making, as the answer to very non-sectarian prayers.
In a sense, these "true-believers" are setting themselves up for disappointment. The world is at least as challenging as it was in 2001—more so, in fact—and an untested, unchallenged leader with no executive experience is set to lead us forward. He will inevitably fail to meet the impossibly high expectations.
And so many individuals' views of the world will change.
For the millions of my generation who have defined their beliefs in opposition to President Bush, the world will grow more complex. No longer will the simplistic view that 'Dubya' is the personification of idiocy or even evil hold such tremendous weight. They will find, rather, that their own hero is human after all, with human faults. No longer will they believe that all Republicans are ignorant, backwoods yokels with hate-filled hearts, or that all Democrats are saints of the utmost wisdom and justice (again, in the most non-sectarian of senses).
At least, not so many will. The more rational among my peers will instead realize that the world is a complicated place, that life is full of legitimate tradeoffs, and that there are good motives, ideas, and individuals on both sides.
And so my generation will change.
I hope that this transformation will soon take place, that naïveté will be replaced by true wisdom, and that The Stanford Review will serve as a guiding light for our own community.
Ironically, we, too, are in the midst of a transition. You see, this issue will be my last as Editor-in-Chief. The time has come for our traditional mid-year changing of the guard. The remainder of the school year will mark the forty-second volume of The Stanford Review, and I have every hope that it will be as successful as its predecessors.
Indeed, for over two decades, The Stanford Review has enriched and diversified the political discussion on this campus. We have helped make Stanford University a marketplace of ideas, rather than a cartel of liberalism. And during my volume, I believe, we have done so in a manner that has been professional, perceptive, and persuasive.
This, however, will not change, even as I pass the torch.
I am fully confident that both the leadership and the staff of The Stanford Review—now, and for years to come—will continue this rich and vital tradition. We will hold true to our motto, "Fiat Lux," and serve a beacon both to the world inside Campus Drive and to the one beyond it.
So though change may be occurring all around us, I close my final Editor's Note with naught but reassuring words for this paper and, more importantly, for our nation: we shall endure.
Devastation in Mumbai
![Demonstrators wave the Indian flag in front of the Taj Mahal Hotel. (Rajanish Kakade/The Associated Press)](/content/uploads/India.jpg)Demonstrators wave the Indian
The Dutchman vs. the Devout Muslims
![Indian Muslims burn a poster of Dutch lawmaker Geert Wilders during a protest against a recent Dutch film that portrays Islam, in Jammu, India, Friday,


Sri Muthukumaran Institute of Technology, Chennai has advertised in THE HINDU Opportunities newspaper for the recruitment of Professor / Associate Professor / Assistant Professor Plus Non-Faculty jobs vacancies. Interested and eligible job aspirants are requested to apply within 03 days from 04th July 2018. Check out further more details below.
How to Apply: Interested and eligible candidates are requested to send their CV, all copies of certificates / supporting documents and recent colour PP size photos to the following postal address or email address.


Gift Certificates are purchased just like any other item in our store. You can pay for them using the store's standard payment method(s). Once purchased the value of the Gift Certificate will be added to your own personal Gift Certificate Balance. If you have funds in your Gift Certificate Balance, you will notice that the amount now shows in the Shopping Cart box, and also provides a link to a page where you can send the Gift Certificate to someone via email.


Restoration Hardware (RH) rode into their first match of the Silver Air Pacific Coast Open with confidence having just won the USPA America Cup the previous weekend defeating Farmers & Merchants Bank 11-9. With their first two wins of the Pacific Coast Open under their belts, RH is leaving nothing to chance in hopes of claiming the title in 2018.
Farmers & Merchants Bank recorded their first victory of the tournament against Sol de Agosto after beginning with the bye. Nico Escobar kicked off the scoring for Sol de Agosto, stepping up to the penalty line and accurately sending the ball through the posts twice in the first chukker of play. Tomy Alberdi answered back in the following chukker with a forceful penalty goal. Scoring bounced back and forth between Sol de Agosto and FMB each scoring to match their opponent. The early two goal lead created by Sol de Agosto held through the end of the second chukker.
Farmers and Merchants Bank hit their stride in the third, with each member of the team scoring to bring their total to six goals and tying the match up after a goal each by Narvaez and Escobar. Alberdi dominated the fourth chukker, opening up the game and scoring three times from the field. The remainder of the game was fast, open and evenly matched, but Alberdi's three goal addition held FMB above Sol de Agosto, 11-9.
Lucchese tallied their first win of the tournament against Klentner Ranch, winning 10-8 on Friday. Lucchese took a quick lead in the first chukker out scoring Klentner Ranch 2-0. The fell behind in the second as Remy Muller, Mariano Obregon and Jesse Bray each added a point for Klentner Ranch pushing them ahead 3-2. They maintained their one goal advantage for the next chukker with both teams scoring twice before the half. Players on both sides struggled to score in the fourth chukker. A single goal from Facundo Obregon off of a penalty two tied the score at five goals each. Fouls continued to bog down play over the next two chukkers. Of the teams' combined eight goals scored in the fourth and fifth chukker, six came from the penalty two line. A final goal from the field by Facundo Obregon eased Lucchese ahead of Klentner Ranch 10-8.
The tournament continues on Wednesday with two games, RH vs. Klentner Ranch and Lucchese vs. Sol de Agosto.


We have all been sick at one time or another, and we have all felt totally washed out and badly in need of sleep. Why is this? Why do you want nothing but to go to bet when you feel ill? A study has revealed scientific reasons why you get tired and sleepy when you're sick. Why illness and rest go hand in hand, and why the need for sleep and rest is so common in people when they feel unwell.
In January 2017, eLife Sciences Publications published a study carried out on parasitic roundworms. When subject to stress, roundworms emit certain chemicals that send them to sleep. One of these chemicals is known as FLP-13, and it was shown that even when not sick, worms exposed to FLP-13 fell asleep. After some work, it was found that a receptor protein known as DMSR-1 was necessary for the FLP-13 to cause sleep. A similar result was obtained using fruit flies rather than roundworms.
Further work is required to establish whether or not a similar mechanism triggers sleep in humans who are ill. If that is the case, then it may be possible to develop a medication that treats people who suffer fatigue associated with sickness. It may also help those who feel tired and sleepy for unexplained reasons. It is not yet known whether the chemical involved turns off cells that cause people to be awake turns on cells that cause them to sleep. The type of sleep involved in sickness is believed to be different from normal sleep.
During sleep, your body repairs issues and restores cells lost during waking hours. This is also a time when the brain processes memories and other information. Research carried out during the past 15 years has indicated that feeling sleepy when you're sick may help the body to maximize immunity and enhance the body's immune system. This goes along with the popular belief that sleep assists in healing, and if you are feeling ill, your body forces you to feel tired and sleep to help you get better.
That's not all your body is doing to help it heal itself. As it slows you down, makes you feel sleepy and even makes you fall asleep, your body is carrying out some essential tasks to battle your illness.
It identifies and recognizes the invading bacteria or virus and gets ready to fight them. This is known as the 'encoding' process.
It gets all the information on these invaders together and consolidates it.
It stores this information and recalls it the next time the same bacteria or virus returns. This is how people become immune to getting the same viruses multiple times. It's why once you have chickenpox or mumps, you will never get it again. Your body has developed antibodies to fight them, and this is largely done when you are asleep.
It is possible for your body to carry out these functions while you are awake, but they are much more effective when carried out while you are asleep. That's why your body tells you to slow right down until you are asleep rather than try to stay awake and 'man it out.' Manning it out may make you feel even worse because your defenses are not being given the time to recover and build up again. Most of the recovery, healing, and restoration of damage, both mental and physical, takes place during slow-wave sleep when you are sleeping the deepest.
It's not only humans that do this though. Many other animals appear to get sleepy when they are unwell. Some stop eating, others slow down their movements and respond less to their environment than they normally do. From roundworms to humans, it appears as though the organism knows when it is not functioning properly (when it is ill) and slows everything down to a sleeping state. Then it can get to work on healing itself. That's why you get tired and sleepy when you're sick.
How Does Your Body Fight Sickness?
So how does your body fight sickness? What is the process – what are the steps it takes? Slowing you down and making you feel sleepy is the initial step. From the work on the roundworms and fruit flies, it appears to do this by emitting certain chemicals that block the cells that keep you awake (or activate the cells that make you fall asleep).
This has a number of effects on your body. First, your immune system is strengthened and begins fighting off invading bacteria (germs) or viruses. This helps you recover more quickly than you would have otherwise (if at all!). Another effect is to stop all exercise, slow down digestion, and focusing blood flow on providing energy and nutrition to the immune system to help beat off the invaders. Sleeping also generates an increased level of alpha-lipoic acid, a powerful antioxidant that destroys free radicals and other invaders, and so promotes healing.
In this way, your body and its immune system fight infection and promotes healing. This is all helped by sleep, and it is essential to get enough sleep when you are sick. This is why you feel tired and sleepy when sick. Your own body is controlling the process.
Without control, your immune system can lead to inflammation. The adrenal glands, situated at the top of each kidney, produce steroids known as endogenous steroids. These have the effect of suppressing the immune system and reducing inflammation. However, what we need here is to reduce the activity of the adrenal glands, thus allowing an inflammatory response to take place which in turn stimulates the immune system. By falling asleep, you reduce the activity of endogenous steroids and improve the effectiveness of the healing process.
Another benefit of sleep is that it has been shown to boost immunological memory after vaccination. One study showed that men who slept after being vaccinated against hepatitis A developed significantly more immunity to the disease than those who did not sleep. Another benefit is that of endorphin. This is a well know endogenous opioid (as opposed to an endogenous steroid). The level of this in your blood is increased through moderate exercise and by sleeping. This, in turn, leads to an increase in antibody generation and an improved immune response.
Many studies have been carried out on the effects of sleep on your health and immune system. There appears to be a definite relationship between sleep and a healthy immune function. It appears that sleep helps improve your immunity to certain viruses and that this is why your body literally sends you to sleep when you are sick or feel unwell. It is not only to repair damaged tissues and restore lost cells but to actively improve your ability to fight against diseases.
You get tired when you're sick because your body is best able to fight disease when you are sleeping. Sleep strengthens your immune system and makes it more able to tackle whatever organisms are causing your illness. Your sleeping position may be important here, particularly if you have a cold or sinus issues. Sleeping with your head elevated with a pillow or pillows helps, and both back and side sleeping positions are best.
The best way to overcome sickness and infections that are caused by bacteria and viruses is to rest. Go to bed on a comfortable mattress and let your immune system do its work. If your body is telling you to slow down, then take heed and get to bed. You will heal and be up and well again much sooner if you allow your immune system to be recharged and work more effectively. This applies to animals and humans: we are all just animals at the end of the day!


As that sentimental, love-filled holiday we call Valentine's Day approaches, you're probably thinking of how to best express your romantic affection for that very special someone. How about putting your feelings into words by writing a beautiful love letter? If you find your thoughts don't always flow quite as easily as you'd like, you may find it really difficult to come up with just the right words to convey exactly how you feel. No worries. Blue Mountain is here for you! You can now find beautiful (and free) Love Letter Stationery on BlueMountain.com that are perfect for crafting the ultimate Valentine's Day love letter.
You'll want to find a nice quiet space in which to write, away from all phones, computers, and other distractions. If you're comfortable and unhurried, your letter-writing process will be much more relaxing, enjoyable, and productive.
Before you put pen to paper, take your time and go over your feelings and emotions for that special person. Remember key moments and events you've shared. What makes them stand out from the others? Focus on their best qualities and some of the kind things they've done for you.
Don't try to imitate anyone or use words you wouldn't ordinarily use in real life. Be conversational and write exactly what comes to mind, just the way you would say it out loud. Your own voice is the sweetest voice of all—and they know it.
A personally handwritten letter is the best of all. No emails or texts will do this time, sorry. As luck would have it, our designers have created some FREE, printable love letter templates you can print right from home.
Your letter doesn't have to be long to be better. Short and sweet is just as good as any novella.
Conclude with a sentimental closing, such as "With all my love," "Forever yours," or "Your one and only." Tuck into an envelope. Consider adding a few heart-shaped confetti, or some dried rose petals before sealing. Add a candle wax seal using a heart-shaped stamp for a nice finishing touch. Hand-address and mail in plenty of time for them to receive—and enjoy—by Valentine's Day.
We're also offering two FREE, printable love quotes that are made for printing and framing. When you combine this framed quote and your love letter on coordinating Love Letter Stationery from BlueMountain.com, you'll have the perfect Valentine's Day present ready to go!
Click here to print and frame this quote.
With Valentine's Day peeking around the corner, love is most definitely in the air, and we at Blue Mountain are anxiously looking forward to sharing warm Valentine's Day smiles and hugs with our families, friends, and fans.
We decided it would be so much more fun to have you join in the fun with us, and so we've designed these wonderfully-sweet, Valentine's Day printable love notes that you can print and leave for anyone whose day you'd like to brighten with a smile. These love notes are perfect for popping in lunches, secretly tucking in coat pockets, leaving on desks at work, or inside books for a hidden surprise. Your kids, friends, family, and sweetheart are sure to love and appreciate your thoughtful little Valentine gems. Enjoy filling your world with happiness and love!
Click here download and print these love notes out today!


text:
Ein Weitabspannmast ist ein Abspannmast in einem Leitungsabschnitt mit großer Spannweite, z. B. Talüberspannungen. Bei Weitabspannmasten sind die Abstände der Leiterseile gegenüber den üblichen Werten vergrößert, um ein Zusammenschlagen der Leiterseile im Sturm (was einen Kurzschluss zur Folge hätte) zu verhindern.

Weitabspannmaste müssen wegen der hohen Zugkräfte des langen Seilabschnitts der Talquerung eine hohe Festigkeit besitzen und werden deshalb gelegentlich auch als Portalmast ausgeführt.

Bei großen Spannweiten und exponierter Lage der Weitabspannmaste kann – anstelle eines gemeinsamen Mastes – für jedes Leiterseil ein eigener Mast verwendet werden, um einen besonders großen Abstand der Leiterseile voneinander zu erzielen.

Lange Abspannfelder

Beispiele:
 Längste Spannweite: Querung des Ameralik-Fjords, 5376 m, Grönlands erstes Kraftwerk wurde 1993 errichtet.
 Längste Spannweite Europas: Querung des Sognefjords beim Ort Leikanger, 4597 m, Norwegen.
 2009 wurde in Südwestalaske bei der Querung des Eagle River im Tongass National Forest ein Feld mit 2100 m Länge gespannt.
 Längste Spannweite Deutschland: Eyachtalquerung Höfen, 1444 m.

Siehe auch
 Freileitungskreuzung

Bauform (Freileitungsmast)

en:Long-distance anchor pylon

redpajama_set_name: RedPajamaWikipedia


The Android 2.2 platform introduces many new and exciting features for users and developers. This document provides a glimpse at some of the new user features and technologies in Android 2.2. For more information about the new developer APIs, see the Android 2.2 version notes.
The Phone, applications Launcher, and Browser now have dedicated shortcuts on the Home screen, making it easy to access them from any of the 5 home screen panels.
Exchange Calendars are now supported in the Calendar application.
Gallery allows you to peek into picture stacks using a zoom gesture.
Camera onscreen buttons provide easy access to a new UI for controling zoom, flash, white balance, geo-tagging, focus and exposure. Camcorder also provides an easy way to set video size/quality for MMS and YouTube.
With the LED flash now enabled for the Camcorder, videos can be shot at night or in low light settings.
You can use your Android-powered phone as a 3G connection for a Windows or Linux laptop by connecting their phone to the computer with a USB cable. The connection is then shared between the two devices.
Multi-lingual users can add multiple languages to the keyboard and switch between multiple Latin-based input languages by swiping across the space bar. This changes the keys as well as the auto-suggest dictionary.
Apps can utilize Android Cloud to Device Messaging to enable mobile alert, send to phone, and two-way push sync functionality.
New bug reporting feature for Google Play apps enables developers to receive crash and freeze reports from their users. The reports will be available when they log into their publisher account.
New "car mode" and "night mode" controls and configurations allow applications to adjust their UI for these situations. A scale gesture detector API provides improved definition of multi-touch events. Applications can now customize the bottom strip of a TabWidget.
For more information about the new developer APIs, see the Android 2.2 version notes and the API Differences Report.


My Happiness Report is a weekly collection of things making me happy for week ending September 16th.
Happy Sunday! I hope you all had a great weekend. We spent the weekend in Omaha, Nebraska cheering on Nick as he ran the Omaha Marathon. It was so very hot and the race course was a tough one, but he did it and we are so proud of him! This was his 4th marathon…we'll see if it is his last. I've ran a couple of half marathons and those are hard, I can't imagine suffering through a full marathon. No thank you!
I was so excited to spend the weekend in Omaha. If you are curious as to why, check out this blog post. Unfortunately, our plans to dominate Omaha's food scene got foiled when Leah fell into a hole on the sidewalk and scraped up her leg pretty bad and sprained her ankle. We ended up spending Saturday afternoon/evening in our cozy hotel room, eating junk food and watching The Greatest Showman. It wasn't a horrible way to spend our time but it definitely wasn't what we had planned for our weekend away.
Alright, friends, are you ready to see the things making me happy this week? See my 41st Happiness Report Below!
I'm 100% thrilled about this new blog series by one of my absolute favorite blog friends!
If you know their story, you can understand why this news made me cry such happy tears. So so so happy for my friends!
What are the chances? This story is definitely serendipitous.
These things are proven to make you happier, and I'd believe it.
I recently stumbled across this blog and have pinned just about every recipe I've seen to try. So many great ideas here.
I've been on the hunt for the perfect mascara and finally found it. In fact, I found myself crying while getting my hair done the other day (thanks to the book I mentioned above) and my eye makeup still looked perfect despite the tears.
Have a great rest of your week and thanks for stopping by.
I agree! I was just saying on the way to Omaha how we haven't seen it or heard the soundtrack for a couple of months (after it was a daily occurrence for so long!). I may have jinxed us!
My love of how food connects people together runs deep. Explore a decade worth of Dine & Dish recipes, from sweets to savory as well as classic family favorites. Food lovers will want to check this out. Bon Appétit!
"I haven't been everywhere, but it's on my list." I've always had a serious case of wanderlust, and traveling and exploring new places continues to be one of my favorite things. Come explore my favorite places with me!
More than just a food blog, Dine & Dish has always been a place where I've shared what's happening in our life. These life posts tend to be my absolute favorite blog posts. Come get a taste of life as it happens in our house!
I believe that in order to live a happy life, you have to make happiness happen through implementing simple things that make you happy into every day. Here are a few of the things that bring me happiness - I hope they do you too.
For our site policies, click here.
Want more positivity in your life and exclusive content in your inbox every Friday?
Add your email below for a little extra happiness in your inbox once a week.


Has anyone else caught your attention this season, though?
Apart from Rooney and Sigurdsson goals it's been a season of awful or forgettable moments.
So yeah, a 19 year-old who keeps hold of the ball well in tight situations and likes to go towards the oppositions goal has offered a glimmer of hope to me at least.
I don't even think he keeps the ball well does he? Genuine question but all I can think of is him getting the head down and either giving it away or getting tackled rather than opening up a defence and building up an attack or setting up a chance?
I'm not meaning to be down on the lad, I just don't see why there's a clamour from some people to see him played more often than he has been. All three managers this season seem to have had reservations about playing him.
Sad as it is, I think Vlasic is one of our smarter players in possession.
As in, he looks like he actually thinks before he tries things.
I'll take that team mate.
I think McCarthy and Schneids are very ball shy for a two in cm but I HOPE with sig in the middle and pace either side he will be drawn to the ball. He's definitely got the legs to go centre circle to box for 90 minutes collecting the ball and playing it to the options ahead (before arriving late on the edge of the box and finishing - his best asset, my prediction for what will happen) just whether he has that natural attraction to the ball.
Will be great to see Theo and Tosun, really looking forward to it, hope we get the ball to them and in to good spaces for them plenty.
Not sure what to say about Vlasic cause I dunno how that'll work, but worried and would rather bolasie I think.
Don't think Schneiderlin is overly ball shy.
It's just that his style is more shifting it from side to side, with his best pass a switch of play.
For him to be effective with the ball he needs good vertical options to be close to him or lots of movement to the sides in order to unsettle the opposition positionally, or then the team to have good possession which drags players towards one side enabling the switch to the other.
None of which we've had this season.
It's without the ball that he's been particularly poor this season looking slow to the tackle etc.
Yeah, he keeps it well, and shows good strength.
The 'clamour' is probably in reaction to the utter dross served up all season by others in positions on the field that he could occupy.
No, it isn't ideal to throw in a 19 year-old EPL rookie, but hey, we are shite.
Feels like we have three new signings if Vlasic plays.
I like the lad, if we invest a bit of time and effort in him I think he's got enough in his locker to reward us with a baller.
Reckon your mate's on the wind up again, Garbutt isn't in the up to date Premier League squad which includes Walcott so it's been updated in the last 24 hours.


text:
Yachting News » Fleet » Hanse 315 voted European Yacht of the Year 2016
Hanse 315 voted European Yacht of the Year 2016
Posted: 4th Feb 2016 | Written By: Hanse Yachts
The new Hanse 315 was announced as "European Yacht of the Year" at boot Düsseldorf. The winner was chosen by a jury of experts from eleven major continental European sailing magazines.
The editors of eleven influential magazines chose the "European Yacht of the Year" in five different categories: Family-Cruiser, Performance-Cruiser, Luxury-Cruiser, Multihull and Special Yachts. The Hanse 315 was one of the 25 contestants and wins in the Family-Cruiser category.
All nominees faced the judgement of the jury in extensive sea trials and were evaluated in six different areas: sailing characteristics, comfort, quality of construction, innovation, design and price-performance ratio.
The winners were announced on the first night of the boot Düsseldorf (23.01.16-31.01.16) in the scope of the Delius Klasing flagship night, where Dr. Jens Gerhardt, CEO of HanseYachts AG, accepted the prize. The jury consisted of members from the following countries: Germany, Denmark, Italy, Austria, Sweden, Switzerland, Norway, Great Britain, France, the Netherlands and Spain.
Jochen Rieker, YACHT, Germany states: HanseYachts has always been a very innovative yard, especially among the big players. They started the trend of more customizable serial production boats a bit over ten years ago with the 531 and 461. With the new Hanse 315 they now offer just as many options and variations, even at the bottom of their range. The 315 is one of the most versatile entry-level cruisers on the market: tiller or wheels, self-tacking jib or genoa, oak or mahogany style interior, double, single, or a kids cabin in the front... the choice is unparalleled. Adding good sailing performance and modern looks. On top of it she really stands out from the crowd. For me the best boat in this size and class right now.
"The Hanse 315 shows despite her size, all the innovation that make her big sisters outstanding: most spacious head in class, ample cockpit, extraordinary standing height where needed, roomy bed and comfort, easy sailing, fast and new designed hull as well as elegant exterior design." Jens Gerhardt CEO of HanseYachts AG. This victory is yet another chapter in the Hanse success story: After the achievement in the USA as "Best Value Yacht" awarded by Cruising World magazine, this is the second major award given to the Hanse 315, after the new model was presented at the Cannes Yachting Festival in France last year.


text:
Q: why I can't export export a declared function in ES6? I have read docs from MDN, ok, mainly it's good about the new module feature, what makes me confused is the small things about export, now, let's see:
when I
export function foo(x) {
   return x * x;
}

or
export const foo = (x) => {
  return x * x
}

both works;
but if
const foo = (x) => {
  return x * x
}
export foo  // failed

I know here should be export {foo}, but, why? what's the difference, that should be work. glad to hear some genies ideas.

A: ES modules support only several syntax variations in order to be statically analyzed.
According to the reference, the variations are:
export { name1, name2, …, nameN };
export { variable1 as name1, variable2 as name2, …, nameN };
export let name1, name2, …, nameN; // also var, function
export let name1 = …, name2 = …, …, nameN; // also var, const

export default expression;
export default function (…) { … } // also class, function*
export default function name1(…) { … } // also class, function*
export { name1 as default, … };

export * from …;
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;

export foo is not among them. It is not supported and cannot be used.

A:
I know here should be export {foo}, but why?

Because that's the syntax that was decided for. Notice that it's actually possible to export multiple variables from a single export declaration:
export { foo as foo, bar as bar }

It just doesn't flow well without braces.

redpajama_set_name: RedPajamaStackExchange


text:
Giving workers the power to automate
By Matt Leonard
Just like Excel or PowerPoint, robotic process automation software will improve the way employees do their daily work, according to National Science Foundation officials who have started to implement the technology.
"It's basically just this software that you have on your desktop that can do manual work and transactional work," NSF Deputy CFO Mike Wetklow said. Employees are very excited about the technology, especially those that have a lot of manual data-entry work, he said at an Oct. 11 event hosted by Government Executive and NextGov.
NSF conducted a pilot last year and is currently working toward spreading the technology across the agency.
CIO Dorothy Aronson told GCN that NSF expects employees to be able to make their own bots within the year. "It depends a lot on their eagerness to adjust," she said.
"I believe that people throughout the agency should be able to develop their own bots," Aronson said. "People who have the business knowledge and understand what repetitive tasks they have should be able to use the software … to simplify their own daily work, to move away from those repetitive tasks and actually do more strategic thinking," she said.
NSF is also working to apply artificial intelligence to its merit review process for new project funding.
"We receive ideas from the public, and we put panels of experts together in order to review those ideas," Aronson said. The program officers are responsible for assembling these experts, some of which come from outside the agency.
As the proposed projects have become more interdisciplinary, finding reviewers with expertise in several fields has gotten harder, so AI has been enlisted to help. It was trained with data on funded proposals, so it looks for appropriate experts based on what they've reviewed in the past, who they've partnered with and other variables.
"It shrinks down the proposals to their essential elements, and then it looks out into our universe of people and says who looks like they might be an approximate match to this proposal or group of proposals," Aronson said.
Matt Leonard is a former reporter for GCN.
The case for AI in HR
DJI disputes claims of lax security, touts Government Edition drone
How to prepare for emerging technologies
Machine learning models at the touch of a finger
Rise of the citizen data scientist


text:
Home > Study in UK > University of Exeter - Penryn Campus > Bachelor of Science in Geography
Explore key global challenges of the 21st century by examining both human and physical issues and, importantly, the connections between the two
Gain an appreciation of global challenges from multiple perspectives with an understanding of the interactions between people, places and events
Highly flexible programme offers an innovative, contemporary and holistic approach to Geography
Your choice of dissertation topic and selection of modules will determine whether you graduate with a BA or a BSc
Hands-on fieldwork is an integral part of all our programmes, with options in the South West and further afield
University of Cumbria (Ambleside Campus)
University of Southampton - Southampton General Hospital Campus
University of Essex - Colchester Campus
Staffordshire University - Stoke-on-Trent Campus


" Classic " capitals—particularly the "Corinthian ;" the " egg/' and 44 egg-and-tongue " mouldings ; 44 pearl" beading; the sacrificial heads—bullocks1 rams', etc.; stiff festoons of drapery; sphinxes, lions, eagles, and other figures, mythological, animal, and human. The enrichment of Fig, 4, Plate II., is as comprehensive an object lesson in the decorative elements of this period as could well be found in a single example. In addition to the employment of brass in the form of mounts such as those illustrated and described, simple lines of the same metal were, very frequently, inlaid into the mahogany, with very chaste and pleasing results. Reverting, for a moment, to chairs and seats, I may mention that, when not made in mahogany, with brass mounts or gilded carving, they were painted in light and subtle shades of cream, green, pink, or blue, and touched up here and there with gilt, the mouldings and ornaments generally being thrown into prominence in that way. Gilt, in one guise or another, was a very prominent feature throughout the Napoleonic furnishing era in France, which, from more than one point of view, may be, perhaps, regarded as an age of brass.
A word or two, in conclusion, with regard to the character of the design of the 44 Empire " textile fabrics used for furniture coverings and draperies. Sometimes they were bold, free, and floral in treatment, as in the coverings of Fig. 4, Plate I., and Figs. 1 and 3, Plate II., but more generally they were stiff and conventional, as in Fig. 3, Plate Iv Fig. 6, Plate III., and Figs. 1, 2, and 6, Plate IV. The pattern was often composed solely of a "powdering," which consisted of a simple wreath, or even of the Imperial Bee alone, without any decorative accompaniment.


Weddings are a joyous and special occasion that you share with the people closest to you. Before that can happen we need to find the words to express how greatly their presence is appreciated. How do we do that? Inviting your guests can involve making some important decisions to ensure the proper etiquette is executed. Let's break it down.
If you are inviting a couple to your wedding, it is best to address them with the first and last name of the husband. For example, "Mr. and Mrs. John Smith." This format should also be used when addressing the hosts on the invitation itself. When inviting children, you need to include the names of each child, otherwise it implies they are not invited. Using "Miss" for girls under 18 and "Ms." for girls over 18 is most appropriate. Boys under the age of 18 do not need any title, just their names. If they are over 18 you should include "Mr." before their names.
The celebration is for the bride and groom, but there are other factors that the couple might want to include in their invitations. For instance, information on parking, appropriate attire, plus ones, nearby hotels, dietary needs/requests or meal options are great ideas for giving enough information to your guests. These and other factors can make it easier for the guests and the bride and groom in planning ahead. Although adding information can be helpful, it is typically considered rude to mention your registry on the wedding invitations.
Make sure the address, time & date are clear for your guests and they are able to read it with ease. Providing enough detail so your guests can plan accordingly is great, however, make sure you aren't writing a short novel on your invitations. To the point and with clarity are essential in writing invitations. Many brides are choosing to even include maps to make things as simple as possible for their guests.
Why do we worry about the details? The details are what make a difference in making your guests feel welcome and it also sets the tone for your wedding. After all, we all know the importance of first impressions. This is the first taste of what your guests will be expecting from your wedding day so it is important to make sure they like what they see.
The RSVP date is important and how your guests are to respond is just as crucial. Providing a website or app is the modern option, however e-mail, mail as well as other means of communication are acceptable as well. Making sure you cater to your guests and knowing what may be easiest for them is imperative because it will ensure they RSVP by the given date and you won't have guests showing up that you hadn't accounted for.
These are just a few tips to keep in mind.
From the fabulous ladies at Fab Fête Event Planning Boutique, we wish our beautiful brides all the best with their invitations.


text:
namespace MediaMonitoringSystem.Data.MSSQL.Repositories
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using System.Linq;
    using System.Linq.Expressions;
    using MediaMonitoringSystem.Data.MSSQL.Contracts;

    public class GenericRepository<T> : IGenericRepository<T>
        where T : class
    {
        private IMediaMonitoringSystemDbContext dbContext;
        private IDbSet<T> set;

        public GenericRepository(IMediaMonitoringSystemDbContext dbContext)
        {
            this.dbContext = dbContext;
            this.set = dbContext.Set<T>();
        }

        public IQueryable<T> All()
        {
            return this.set.AsQueryable();
        }

        public void Add(T entity)
        {
            var entry = AttachIfDetached(entity);
            entry.State = EntityState.Added;
        }

        public void Update(T entity)
        {
            var entry = AttachIfDetached(entity);
            entry.State = EntityState.Modified;
        }

        public void Delete(T entity)
        {
            var entry = AttachIfDetached(entity);
            entry.State = EntityState.Deleted;
        }

        public void Detach(T entity)
        {
            var entry = AttachIfDetached(entity);
            entry.State = EntityState.Detached;
        }

        private DbEntityEntry AttachIfDetached(T entity)
        {
            var entry = this.dbContext.Entry(entity);
            if (entry.State == EntityState.Detached)
            {
                this.set.Attach(entity);
            }

            return entry;
        }
    }
}