text:
DEFINE_GUID(GUID_DEVINTERFACE_DISK,
			0x53f56307L, 0xb6bf, 0x11d0, 0x94, 0xf2,
			0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);

void EnumRegKeys(HKEY hkey)
{
    BYTE name[1024];
	int i;

	for (i=0; ; i++) {
		DWORD nbytes = sizeof(name);
		LONG rc = RegEnumKeyEx(hkey, i, name, &nbytes,
			NULL, NULL, NULL, NULL);
		if (rc == ERROR_NO_MORE_ITEMS)
			break;
		printf("key %s\n", name);
	}
}

void EnumRegValues(HKEY hkey)
{
    BYTE name[1024];
    BYTE data[1024];
	int i;

	for (i=0; ; i++) {
		DWORD name_size = sizeof(name);
		DWORD data_size = sizeof(data);
		DWORD type;
		LONG rc = RegEnumValue(hkey, i, name, &name_size, NULL,
			&type, data, &data_size);
		if (rc == ERROR_NO_MORE_ITEMS)
			break;
		printf("value %s = %s\n", name, data);
	}
}

void DumpKey(HKEY hkey)
{
	EnumRegKeys(hkey);
	EnumRegValues(hkey);;
}

int main()
{
    // We will try to get device information set for all USB devices that have a
    // device interface and are currently present on the system (plugged in).
    HDEVINFO dev_set = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DISK,
        NULL, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
//    HDEVINFO dev_set = SetupDiGetClassDevs(0, "USBSTOR", 0,
//		DIGCF_ALLCLASSES | DIGCF_PRESENT);
    if (dev_set == INVALID_HANDLE_VALUE) {
        printf("Cannot get list of disks!\n");
        exit(-1);
    }

    // Prepare to enumerate all device interfaces for the device information
    // set that we retrieved with SetupDiGetClassDevs(..)
    SP_DEVICE_INTERFACE_DATA dev_intf;
    dev_intf.cbSize = sizeof(dev_intf);

    // Next, we will keep calling this SetupDiEnumDeviceInterfaces(..) until this
    // function causes GetLastError() to return  ERROR_NO_MORE_ITEMS. With each
    // call the idx value needs to be incremented to retrieve the next
    // device interface information.
    DWORD idx;
    for (idx=0; ; idx++) {
        SetupDiEnumDeviceInterfaces(dev_set, NULL,
            &GUID_DEVINTERFACE_DISK, idx, &dev_intf);

        if (GetLastError() == ERROR_NO_MORE_ITEMS)
            break;

        // Get the required buffer size.
        DWORD nbytes;
        SetupDiGetDeviceInterfaceDetail(dev_set, &dev_intf, NULL, 0,
            &nbytes, NULL);
        //printf("%u: nbytes = %u\n", (int)idx, (int)nbytes);

        // As a last step we will need to get some more details for each
        // of device interface information we are able to retrieve. This
        // device interface detail gives us the information we need to identify
        // the device (VID/PID), and decide if it's useful to us. It will also
        // provide a DEVINFO_DATA structure which we can use to know the serial
        // port name for a virtual com port.
		char buf[1024];
        PSP_DEVICE_INTERFACE_DETAIL_DATA intf_detail = (void*)buf;
        intf_detail->cbSize = sizeof(*intf_detail);

        SP_DEVINFO_DATA dev_instance;
        dev_instance.cbSize = sizeof(dev_instance);

        if (! SetupDiGetDeviceInterfaceDetail(dev_set, &dev_intf,
                intf_detail, nbytes, &nbytes, &dev_instance))
        {
            printf("Cannot get device interface details!\n");
            continue;
        }

        printf("\n(%u)\n%s\n", (int)idx, intf_detail->DevicePath);

        // Check the registry for the port name

        HKEY hKey = SetupDiOpenDevRegKey(dev_set, &dev_instance,
            DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ);
		DumpKey(hKey);
#if 0
        BYTE port_name[1024];
        nbytes = sizeof(port_name);
        DWORD dwType = REG_SZ;
        RegQueryValueEx(hKey, _T("DriverDesc"), NULL, &dwType, port_name, &nbytes);
        printf("Port name = '%s'\n", port_name);
#endif
        RegCloseKey(hKey);
    }
    SetupDiDestroyDeviceInfoList(dev_set);

    return 0;
}

#if 0
//#include <Ntddstor.h>

//#pragma comment( lib, "setupapi.lib" )

#include <iostream>
#include <string>

#define START_ERROR_CHK()           \
    DWORD error = ERROR_SUCCESS;    \
    DWORD failedLine;               \
    string failedApi;

#define CHK( expr, api )            \
    if ( !( expr ) ) {              \
        error = GetLastError( );    \
        failedLine = __LINE__;      \
        failedApi = ( api );        \
        goto Error_Exit;            \
    }

#define END_ERROR_CHK()             \
    error = ERROR_SUCCESS;          \
    Error_Exit:                     \
    if ( ERROR_SUCCESS != error ) { \
        cout << failedApi << " failed at " << failedLine << " : Error Code - " << error << endl;    \
    }

int main( int argc, char **argv ) {

    HDEVINFO diskClassDevices;
    GUID diskClassDeviceInterfaceGuid = GUID_DEVINTERFACE_DISK;
    SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
    PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData;
    DWORD requiredSize;
    DWORD deviceIndex;

    HANDLE disk = INVALID_HANDLE_VALUE;
    STORAGE_DEVICE_NUMBER diskNumber;
    DWORD bytesReturned;

    START_ERROR_CHK();

    //
    // Get the handle to the device information set for installed
    // disk class devices. Returns only devices that are currently
    // present in the system and have an enabled disk device
    // interface.
    //
    diskClassDevices = SetupDiGetClassDevs( &diskClassDeviceInterfaceGuid,
                                            NULL,
                                            NULL,
                                            DIGCF_PRESENT |
                                            DIGCF_DEVICEINTERFACE );
    CHK( INVALID_HANDLE_VALUE != diskClassDevices,
         "SetupDiGetClassDevs" );

    ZeroMemory( &deviceInterfaceData, sizeof( SP_DEVICE_INTERFACE_DATA ) );
    deviceInterfaceData.cbSize = sizeof( SP_DEVICE_INTERFACE_DATA );
    deviceIndex = 0;

    while ( SetupDiEnumDeviceInterfaces( diskClassDevices,
                                         NULL,
                                         &diskClassDeviceInterfaceGuid,
                                         deviceIndex,
                                         &deviceInterfaceData ) ) {

        ++deviceIndex;

        SetupDiGetDeviceInterfaceDetail( diskClassDevices,
                                         &deviceInterfaceData,
                                         NULL,
                                         0,
                                         &requiredSize,
                                         NULL );
        CHK( ERROR_INSUFFICIENT_BUFFER == GetLastError( ),
             "SetupDiGetDeviceInterfaceDetail - 1" );

        deviceInterfaceDetailData = ( PSP_DEVICE_INTERFACE_DETAIL_DATA ) malloc( requiredSize );
        CHK( NULL != deviceInterfaceDetailData,
             "malloc" );

        ZeroMemory( deviceInterfaceDetailData, requiredSize );
        deviceInterfaceDetailData->cbSize = sizeof( SP_DEVICE_INTERFACE_DETAIL_DATA );

        CHK( SetupDiGetDeviceInterfaceDetail( diskClassDevices,
                                              &deviceInterfaceData,
                                              deviceInterfaceDetailData,
                                              requiredSize,
                                              NULL,
                                              NULL ),
             "SetupDiGetDeviceInterfaceDetail - 2" );

        disk = CreateFile( deviceInterfaceDetailData->DevicePath,
                           GENERIC_READ,
                           FILE_SHARE_READ | FILE_SHARE_WRITE,
                           NULL,
                           OPEN_EXISTING,
                           FILE_ATTRIBUTE_NORMAL,
                           NULL );
        CHK( INVALID_HANDLE_VALUE != disk,
             "CreateFile" );

        CHK( DeviceIoControl( disk,
                              IOCTL_STORAGE_GET_DEVICE_NUMBER,
                              NULL,
                              0,
                              &diskNumber,
                              sizeof( STORAGE_DEVICE_NUMBER ),
                              &bytesReturned,
                              NULL ),
             "IOCTL_STORAGE_GET_DEVICE_NUMBER" );

        CloseHandle( disk );
        disk = INVALID_HANDLE_VALUE;

        cout << deviceInterfaceDetailData->DevicePath << endl;
        cout << "\\\\?\\PhysicalDrive" << diskNumber.DeviceNumber << endl;
        cout << endl;
    }
    CHK( ERROR_NO_MORE_ITEMS == GetLastError( ),
         "SetupDiEnumDeviceInterfaces" );

    END_ERROR_CHK();

Exit:

    if ( INVALID_HANDLE_VALUE != diskClassDevices ) {
        SetupDiDestroyDeviceInfoList( diskClassDevices );
    }

    if ( INVALID_HANDLE_VALUE != disk ) {
        CloseHandle( disk );
    }

    return error;
}
#endif


text:
// The MIT License (MIT)
//
// Copyright (c) 2015 Alexander Grebenyuk (github.com/kean).
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#import "DFImageManaging.h"
#import <Foundation/Foundation.h>

/*! The DFCompositeImageManager is a dynamic dispatcher that constructs a chain of responsibility from multiple image manager. Each image manager added to the composite defines which image requests it can handle. The DFCompositeImageManager dispatches image requests starting with the first image manager in a chain. If the image manager can't handle the request it is passes to the next image manager in the chain and so on.
 @note Composite image manager itself conforms to DFImageManaging protocol and can be added to other composite image managers, forming a tree structure.
 */
@interface DFCompositeImageManager : NSObject <DFImageManaging>

/*! Initializes composite image manager with an array of image managers.
 */
- (instancetype)initWithImageManagers:(NSArray /* id<DFImageManaging> */ *)imageManagers NS_DESIGNATED_INITIALIZER;

/*! Adds image manager to the end of the chain.
 */
- (void)addImageManager:(id<DFImageManaging>)imageManager;

/*! Adds image managers to the end of the chain.
 */
- (void)addImageManagers:(NSArray /* <DFImageManaging> */ *)imageManagers;

/*! Removes image manager from the chain.
 */
- (void)removeImageManager:(id<DFImageManaging>)imageManager;

/*! Removes image managers from the chain.
 */
- (void)removeImageManagers:(NSArray /* <DFImageManaging> */ *)imageManagers;

@end

redpajama_set_name: RedPajamaGithub


text:
A simple application made with angujarjs, nodejs and mongodb.

### Description ###

Using Angular.js, make a web app that fulfills these user stories:

* I want to view a list of products.
* I want to view a single product.
* I want to comment on a product.
* I want to view other comments when I view a product.
* I want to create a product with a name, description, and price (assume USD).
* Communicate with HTTP to a backend. (Note: can be mocked for this exercise - use ngMockE2E and
$httpBackend)
* Structure your code sanely. Use directives, services, controllers, etc. where appropriate.

OPTIONAL BONUS POINTS:
* Build the backend using node.js - if you use loopback.io or another set of CRUD generators, it should be a
breeze.
* Persist the product/comment data to an actual database. (You could just store the data in memory for this
exercise)

### How to run the app ###

1. Navigate to the anm folder
2. run in console node .


text:
#include "../../SDL_internal.h"

#if SDL_VIDEO_DRIVER_COCOA

#include "SDL_cocoavideo.h"
#include "../../events/SDL_clipboardevents_c.h"

static NSString *
GetTextFormat(_THIS)
{
    if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5) {
        return NSPasteboardTypeString;
    } else {
        return NSStringPboardType;
    }
}

int
Cocoa_SetClipboardText(_THIS, const char *text)
{ @autoreleasepool
{
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
    NSPasteboard *pasteboard;
    NSString *format = GetTextFormat(_this);

    pasteboard = [NSPasteboard generalPasteboard];
    data->clipboard_count = [pasteboard declareTypes:[NSArray arrayWithObject:format] owner:nil];
    [pasteboard setString:[NSString stringWithUTF8String:text] forType:format];

    return 0;
}}

char *
Cocoa_GetClipboardText(_THIS)
{ @autoreleasepool
{
    NSPasteboard *pasteboard;
    NSString *format = GetTextFormat(_this);
    NSString *available;
    char *text;

    pasteboard = [NSPasteboard generalPasteboard];
    available = [pasteboard availableTypeFromArray: [NSArray arrayWithObject:format]];
    if ([available isEqualToString:format]) {
        NSString* string;
        const char *utf8;

        string = [pasteboard stringForType:format];
        if (string == nil) {
            utf8 = "";
        } else {
            utf8 = [string UTF8String];
        }
        text = SDL_strdup(utf8);
    } else {
        text = SDL_strdup("");
    }

    return text;
}}

SDL_bool
Cocoa_HasClipboardText(_THIS)
{
    SDL_bool result = SDL_FALSE;
    char *text = Cocoa_GetClipboardText(_this);
    if (text) {
        result = text[0] != '\0' ? SDL_TRUE : SDL_FALSE;
        SDL_free(text);
    }
    return result;
}

void
Cocoa_CheckClipboardUpdate(struct SDL_VideoData * data)
{ @autoreleasepool
{
    NSPasteboard *pasteboard;
    NSInteger count;

    pasteboard = [NSPasteboard generalPasteboard];
    count = [pasteboard changeCount];
    if (count != data->clipboard_count) {
        if (data->clipboard_count) {
            SDL_SendClipboardUpdate();
        }
        data->clipboard_count = count;
    }
}}

#endif /* SDL_VIDEO_DRIVER_COCOA */

/* vi: set ts=4 sw=4 expandtab: */


text:
#include "GrResourceCache2.h"
#include "GrGpuResource.h"

#include "SkChecksum.h"
#include "SkGr.h"
#include "SkMessageBus.h"

DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage);

//////////////////////////////////////////////////////////////////////////////

GrScratchKey::ResourceType GrScratchKey::GenerateResourceType() {
    static int32_t gType = kInvalidResourceType + 1;

    int32_t type = sk_atomic_inc(&gType);
    if (type > SK_MaxU16) {
        SkFAIL("Too many Resource Types");
    }

    return static_cast<ResourceType>(type);
}

void GrScratchKey::Builder::finish() {
    if (NULL == fKey) {
        return;
    }
    GR_STATIC_ASSERT(0 == kHash_MetaDataIdx);
    fKey->fKey[kHash_MetaDataIdx] =
        SkChecksum::Compute(&fKey->fKey[kHash_MetaDataIdx + 1], fKey->size() - sizeof(uint32_t));
    fKey = NULL;
}

//////////////////////////////////////////////////////////////////////////////

class GrResourceCache2::AutoValidate : ::SkNoncopyable {
public:
    AutoValidate(GrResourceCache2* cache) : fCache(cache) { cache->validate(); }
    ~AutoValidate() { fCache->validate(); }
private:
    GrResourceCache2* fCache;
};

 //////////////////////////////////////////////////////////////////////////////

static const int kDefaultMaxCount = 2 * (1 << 10);
static const size_t kDefaultMaxSize = 96 * (1 << 20);

GrResourceCache2::GrResourceCache2()
    : fMaxCount(kDefaultMaxCount)
    , fMaxBytes(kDefaultMaxSize)
#if GR_CACHE_STATS
    , fHighWaterCount(0)
    , fHighWaterBytes(0)
    , fBudgetedHighWaterCount(0)
    , fBudgetedHighWaterBytes(0)
#endif
    , fCount(0)
    , fBytes(0)
    , fBudgetedCount(0)
    , fBudgetedBytes(0)
    , fPurging(false)
    , fNewlyPurgableResourceWhilePurging(false)
    , fOverBudgetCB(NULL)
    , fOverBudgetData(NULL) {
}

GrResourceCache2::~GrResourceCache2() {
    this->releaseAll();
}

void GrResourceCache2::setLimits(int count, size_t bytes) {
    fMaxCount = count;
    fMaxBytes = bytes;
    this->purgeAsNeeded();
}

void GrResourceCache2::insertResource(GrGpuResource* resource) {
    SkASSERT(resource);
    SkASSERT(!resource->wasDestroyed());
    SkASSERT(!this->isInCache(resource));
    SkASSERT(!fPurging);
    fResources.addToHead(resource);

    size_t size = resource->gpuMemorySize();
    ++fCount;
    fBytes += size;
#if GR_CACHE_STATS
    fHighWaterCount = SkTMax(fCount, fHighWaterCount);
    fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes);
#endif
    if (resource->cacheAccess().isBudgeted()) {
        ++fBudgetedCount;
        fBudgetedBytes += size;
#if GR_CACHE_STATS
        fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount);
        fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes);
#endif
    }
    if (resource->cacheAccess().getScratchKey().isValid()) {
        SkASSERT(!resource->cacheAccess().isWrapped());
        fScratchMap.insert(resource->cacheAccess().getScratchKey(), resource);
    }

    this->purgeAsNeeded();
}

void GrResourceCache2::removeResource(GrGpuResource* resource) {
    SkASSERT(this->isInCache(resource));

    size_t size = resource->gpuMemorySize();
    --fCount;
    fBytes -= size;
    if (resource->cacheAccess().isBudgeted()) {
        --fBudgetedCount;
        fBudgetedBytes -= size;
    }

    fResources.remove(resource);
    if (resource->cacheAccess().getScratchKey().isValid()) {
        fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource);
    }
    if (const GrResourceKey* contentKey = resource->cacheAccess().getContentKey()) {
        fContentHash.remove(*contentKey);
    }
    this->validate();
}

void GrResourceCache2::abandonAll() {
    AutoValidate av(this);

    SkASSERT(!fPurging);
    while (GrGpuResource* head = fResources.head()) {
        SkASSERT(!head->wasDestroyed());
        head->cacheAccess().abandon();
        // abandon should have already removed this from the list.
        SkASSERT(head != fResources.head());
    }
    SkASSERT(!fScratchMap.count());
    SkASSERT(!fContentHash.count());
    SkASSERT(!fCount);
    SkASSERT(!fBytes);
    SkASSERT(!fBudgetedCount);
    SkASSERT(!fBudgetedBytes);
}

void GrResourceCache2::releaseAll() {
    AutoValidate av(this);

    SkASSERT(!fPurging);
    while (GrGpuResource* head = fResources.head()) {
        SkASSERT(!head->wasDestroyed());
        head->cacheAccess().release();
        // release should have already removed this from the list.
        SkASSERT(head != fResources.head());
    }
    SkASSERT(!fScratchMap.count());
    SkASSERT(!fCount);
    SkASSERT(!fBytes);
    SkASSERT(!fBudgetedCount);
    SkASSERT(!fBudgetedBytes);
}

class GrResourceCache2::AvailableForScratchUse {
public:
    AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendingIO) { }

    bool operator()(const GrGpuResource* resource) const {
        if (resource->internalHasRef() || !resource->cacheAccess().isScratch()) {
            return false;
        }
        return !fRejectPendingIO || !resource->internalHasPendingIO();
    }

private:
    bool fRejectPendingIO;
};

GrGpuResource* GrResourceCache2::findAndRefScratchResource(const GrScratchKey& scratchKey,
                                                           uint32_t flags) {
    SkASSERT(!fPurging);
    SkASSERT(scratchKey.isValid());

    GrGpuResource* resource;
    if (flags & (kPreferNoPendingIO_ScratchFlag | kRequireNoPendingIO_ScratchFlag)) {
        resource = fScratchMap.find(scratchKey, AvailableForScratchUse(true));
        if (resource) {
            resource->ref();
            this->makeResourceMRU(resource);
            this->validate();
            return resource;
        } else if (flags & kRequireNoPendingIO_ScratchFlag) {
            return NULL;
        }
        // TODO: fail here when kPrefer is specified, we didn't find a resource without pending io,
        // but there is still space in our budget for the resource.
    }
    resource = fScratchMap.find(scratchKey, AvailableForScratchUse(false));
    if (resource) {
        resource->ref();
        this->makeResourceMRU(resource);
        this->validate();
    }
    return resource;
}

void GrResourceCache2::willRemoveScratchKey(const GrGpuResource* resource) {
    SkASSERT(resource->cacheAccess().isScratch());
    fScratchMap.remove(resource->cacheAccess().getScratchKey(), resource);
}

bool GrResourceCache2::didSetContentKey(GrGpuResource* resource) {
    SkASSERT(!fPurging);
    SkASSERT(resource);
    SkASSERT(this->isInCache(resource));
    SkASSERT(resource->cacheAccess().getContentKey());

    GrGpuResource* res = fContentHash.find(*resource->cacheAccess().getContentKey());
    if (NULL != res) {
        return false;
    }

    fContentHash.add(resource);
    this->validate();
    return true;
}

void GrResourceCache2::makeResourceMRU(GrGpuResource* resource) {
    SkASSERT(!fPurging);
    SkASSERT(resource);
    SkASSERT(this->isInCache(resource));
    fResources.remove(resource);
    fResources.addToHead(resource);
}

void GrResourceCache2::notifyPurgable(GrGpuResource* resource) {
    SkASSERT(resource);
    SkASSERT(this->isInCache(resource));
    SkASSERT(resource->isPurgable());

    // We can't purge if in the middle of purging because purge is iterating. Instead record
    // that additional resources became purgable.
    if (fPurging) {
        fNewlyPurgableResourceWhilePurging = true;
        return;
    }

    // Purge the resource if we're over budget
    bool overBudget = fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxBytes;

    // Also purge if the resource has neither a valid scratch key nor a content key.
    bool noKey = !resource->cacheAccess().isScratch() &&
                 (NULL == resource->cacheAccess().getContentKey());

    // Only cached resources should ever have a key.
    SkASSERT(noKey || resource->cacheAccess().isBudgeted());

    if (overBudget || noKey) {
        SkDEBUGCODE(int beforeCount = fCount;)
        resource->cacheAccess().release();
        // We should at least free this resource, perhaps dependent resources as well.
        SkASSERT(fCount < beforeCount);
    }

    this->validate();
}

void GrResourceCache2::didChangeGpuMemorySize(const GrGpuResource* resource, size_t oldSize) {
    // SkASSERT(!fPurging); GrPathRange increases size during flush. :(
    SkASSERT(resource);
    SkASSERT(this->isInCache(resource));

    ptrdiff_t delta = resource->gpuMemorySize() - oldSize;

    fBytes += delta;
#if GR_CACHE_STATS
    fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes);
#endif
    if (resource->cacheAccess().isBudgeted()) {
        fBudgetedBytes += delta;
#if GR_CACHE_STATS
        fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes);
#endif
    }

    this->purgeAsNeeded();
    this->validate();
}

void GrResourceCache2::didChangeBudgetStatus(GrGpuResource* resource) {
    SkASSERT(!fPurging);
    SkASSERT(resource);
    SkASSERT(this->isInCache(resource));

    size_t size = resource->gpuMemorySize();

    if (resource->cacheAccess().isBudgeted()) {
        ++fBudgetedCount;
        fBudgetedBytes += size;
#if GR_CACHE_STATS
        fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes);
        fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount);
#endif
        this->purgeAsNeeded();
    } else {
        --fBudgetedCount;
        fBudgetedBytes -= size;
    }

    this->validate();
}

void GrResourceCache2::internalPurgeAsNeeded() {
    SkASSERT(!fPurging);
    SkASSERT(!fNewlyPurgableResourceWhilePurging);
    SkASSERT(fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxBytes);

    fPurging = true;

    bool overBudget = true;
    do {
        fNewlyPurgableResourceWhilePurging = false;
        ResourceList::Iter resourceIter;
        GrGpuResource* resource = resourceIter.init(fResources,
                                                    ResourceList::Iter::kTail_IterStart);

        while (resource) {
            GrGpuResource* prev = resourceIter.prev();
            if (resource->isPurgable()) {
                resource->cacheAccess().release();
            }
            resource = prev;
            if (fBudgetedCount <= fMaxCount && fBudgetedBytes <= fMaxBytes) {
                overBudget = false;
                resource = NULL;
            }
        }

        if (!fNewlyPurgableResourceWhilePurging && overBudget && fOverBudgetCB) {
            // Despite the purge we're still over budget. Call our over budget callback.
            (*fOverBudgetCB)(fOverBudgetData);
        }
    } while (overBudget && fNewlyPurgableResourceWhilePurging);

    fNewlyPurgableResourceWhilePurging = false;
    fPurging = false;
    this->validate();
}

void GrResourceCache2::purgeAllUnlocked() {
    SkASSERT(!fPurging);
    SkASSERT(!fNewlyPurgableResourceWhilePurging);

    fPurging = true;

    do {
        fNewlyPurgableResourceWhilePurging = false;
        ResourceList::Iter resourceIter;
        GrGpuResource* resource =
            resourceIter.init(fResources, ResourceList::Iter::kTail_IterStart);

        while (resource) {
            GrGpuResource* prev = resourceIter.prev();
            if (resource->isPurgable()) {
                resource->cacheAccess().release();
            }
            resource = prev;
        }

        if (!fNewlyPurgableResourceWhilePurging && fCount && fOverBudgetCB) {
            (*fOverBudgetCB)(fOverBudgetData);
        }
    } while (fNewlyPurgableResourceWhilePurging);
    fPurging = false;
    this->validate();
}

#ifdef SK_DEBUG
void GrResourceCache2::validate() const {
    size_t bytes = 0;
    int count = 0;
    int budgetedCount = 0;
    size_t budgetedBytes = 0;
    int locked = 0;
    int scratch = 0;
    int couldBeScratch = 0;
    int content = 0;

    ResourceList::Iter iter;
    GrGpuResource* resource = iter.init(fResources, ResourceList::Iter::kHead_IterStart);
    for ( ; resource; resource = iter.next()) {
        bytes += resource->gpuMemorySize();
        ++count;

        if (!resource->isPurgable()) {
            ++locked;
        }

        if (resource->cacheAccess().isScratch()) {
            SkASSERT(NULL == resource->cacheAccess().getContentKey());
            ++scratch;
            SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchKey()));
            SkASSERT(!resource->cacheAccess().isWrapped());
        } else if (resource->cacheAccess().getScratchKey().isValid()) {
            SkASSERT(NULL != resource->cacheAccess().getContentKey());
            ++couldBeScratch;
            SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchKey()));
            SkASSERT(!resource->cacheAccess().isWrapped());
        }

        if (const GrResourceKey* contentKey = resource->cacheAccess().getContentKey()) {
            ++content;
            SkASSERT(fContentHash.find(*contentKey) == resource);
            SkASSERT(!resource->cacheAccess().isWrapped());
        }

        if (resource->cacheAccess().isBudgeted()) {
            ++budgetedCount;
            budgetedBytes += resource->gpuMemorySize();
        }
    }

    SkASSERT(fBudgetedCount <= fCount);
    SkASSERT(fBudgetedBytes <= fBudgetedBytes);
    SkASSERT(bytes == fBytes);
    SkASSERT(count == fCount);
    SkASSERT(budgetedBytes == fBudgetedBytes);
    SkASSERT(budgetedCount == fBudgetedCount);
#if GR_CACHE_STATS
    SkASSERT(fBudgetedHighWaterCount <= fHighWaterCount);
    SkASSERT(fBudgetedHighWaterBytes <= fHighWaterBytes);
    SkASSERT(bytes <= fHighWaterBytes);
    SkASSERT(count <= fHighWaterCount);
    SkASSERT(budgetedBytes <= fBudgetedHighWaterBytes);
    SkASSERT(budgetedCount <= fBudgetedHighWaterCount);
#endif
    SkASSERT(content == fContentHash.count());
    SkASSERT(scratch + couldBeScratch == fScratchMap.count());

    // This assertion is not currently valid because we can be in recursive notifyIsPurgable()
    // calls. This will be fixed when subresource registration is explicit.
    // bool overBudget = budgetedBytes > fMaxBytes || budgetedCount > fMaxCount;
    // SkASSERT(!overBudget || locked == count || fPurging);
}
#endif

#if GR_CACHE_STATS
void GrResourceCache2::printStats() const {
    this->validate();

    int locked = 0;
    int scratch = 0;
    int wrapped = 0;
    size_t unbudgetedSize = 0;

    ResourceList::Iter iter;
    GrGpuResource* resource = iter.init(fResources, ResourceList::Iter::kHead_IterStart);

    for ( ; resource; resource = iter.next()) {
        if (!resource->isPurgable()) {
            ++locked;
        }
        if (resource->cacheAccess().isScratch()) {
            ++scratch;
        }
        if (resource->cacheAccess().isWrapped()) {
            ++wrapped;
        }
        if (!resource->cacheAccess().isBudgeted()) {
            unbudgetedSize += resource->gpuMemorySize();
        }
    }

    float countUtilization = (100.f * fBudgetedCount) / fMaxCount;
    float byteUtilization = (100.f * fBudgetedBytes) / fMaxBytes;

    SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes);
    SkDebugf("\t\tEntry Count: current %d"
             " (%d budgeted, %d wrapped, %d locked, %d scratch %.2g%% full), high %d\n",
        fCount, fBudgetedCount, wrapped, locked, scratch, countUtilization, fHighWaterCount);
    SkDebugf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudgeted) high %d\n",
                fBytes, fBudgetedBytes, byteUtilization, unbudgetedSize, fHighWaterBytes);
}

#endif


text:
module Reflect

  export anonymous_type, anonymous_module, define_function

  # Stores the ID of the next anonymous type.
  global __counter = zero(Int)
  global __counter_mod = zero(Int)

  # Generates and returns the name of the next anonymous type.
  fresh() = "Anon$(global __counter += 1)"
  fresh_mod() = "AnonMod$(global __counter_mod += 1)"

  # Generates an empty anonymous type.
  anonymous_type(m::Module) = anonymous_type(m, "type;end")

  # Generates an anonymous module from a provided definition.
  function anonymous_module(d::AbstractString)
    name = fresh_mod()
    d = "module $(name)\n$(d)\nend"
    eval(Base.parse(d))
    return eval(Base.parse(name))
  end

  # Generates an anonymous type from a provided definition.
  function anonymous_type(m::Module, d::AbstractString)
    # Insert the name of the type after the first modifier.
    name = fresh()
    d = replace(d, r"(?<=\w)\b", " $(name)", 1)

    # Format the constructors using the name of the type.
    d = replace(d, r"constructor(?=\()", name)

    eval(m, Base.parse(d))
    return eval(m, Base.parse(name))
  end
end


text:
import React, { Component } from 'react'
import { Link } from 'react-router'
import { prefixLink } from 'gatsby-helpers'
import DocumentTitle from 'react-document-title'
import { config } from 'config'
import WrapperComponent from 'src/components/WrapperComponent'

export default class PageBbl extends Component {
  render() {
    return (
      <DocumentTitle title={config.siteTitle}>
        <WrapperComponent className={'PageBbl'}>

Qu'est-ce qu'un BBL ?

            Un Brown Bag Lunch c'est une présentation technique à l'heure du
            déjeuner. Le brown bag fait en effet référence à ce sac en carton
            marron que l'on utilise pour transporter son déjeuner sur son lieu
            de travail. L'idée est donc simple : une personne vient faire une
            présentation, pendant que l'assistance l'écoute en dégustant un bon
            sandwich (ça marche aussi avec une salade, d'ailleurs). On joint
            ainsi l'utile à l'agréable.

        </WrapperComponent>
      </DocumentTitle>
    )
  }
}


text:
module SpreeBankTransfer
  class Engine < Rails::Engine
    require 'spree/core'
    isolate_namespace Spree
    engine_name 'spree_bank_transfer'

    config.autoload_paths += %W(#{config.root}/lib)

    # use rspec for tests
    config.generators do |g|
      g.test_framework :rspec
    end

    def self.activate
      Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
        Rails.configuration.cache_classes ? require(c) : load(c)
      end
    end

    initializer "spree.register.payment_methods" do |app|
      app.config.spree.payment_methods << Spree::PaymentMethod::BankTransfer
    end

    config.to_prepare &method(:activate).to_proc
  end
end


text:
Marquee
=======

The Marquee Club website


text:
#region license
// Copyright (c) 2005 - 2007 Ayende Rahien (ayende@ayende.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//     * Neither the name of Ayende Rahien nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion

using System;
using Xunit;
using Rhino.Mocks.Constraints;

namespace Rhino.Mocks.Tests.Constraints
{

	public class ContraintsErrorConditions
	{
		[Fact]
		public void ComparingConstraintsWhenParameterIsNotIComparable()
		{
			Assert.False(Is.GreaterThan(4).Eval(new object()));
		}

		[Fact]
		public void TextWhenParameterIsNotString()
		{
			Assert.False(Text.Contains("one").Eval(1));
			Assert.False(Text.EndsWith("one").Eval(1));
			Assert.False(Text.StartsWith("one").Eval(1));
			Assert.False(Text.Like("one").Eval(1));
		}

		[Fact]
		public void PropertyIsWhenParameterIsNull()
		{
			Assert.False(Property.Value("Capacity",500).Eval(null));
		}
	}
}


text:
//
//  ResumeViewController.m
//  RunErrands
//
//  Created by Jinfu Wang on 2015/7/27.
//  Copyright (c) 2015年 Jinfu Wang. All rights reserved.
//

#import "ResumeViewController.h"
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#import <Parse/Parse.h>
#import "MBProgressHUD.h"

@interface ResumeViewController ()<MBProgressHUDDelegate>
{
    NSMutableArray *imagearray;
    NSMutableArray *textarray;
    MBProgressHUD *HUD;

}
@property (weak, nonatomic) IBOutlet UIBarButtonItem *displayinvitedBtn;
@property (weak, nonatomic) IBOutlet UIImageView *avatarImageView;

@end

@implementation ResumeViewController
@synthesize user;

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    imagearray = [[NSMutableArray alloc] initWithObjects:@"vcard_color_64x64.png",@"ffffound_color_64x64.png",@"tumbrl_color_64x64.png",@"wiki_color_64x64.png",@"aim_color_64x64.png", nil];

    textarray = [[NSMutableArray alloc] initWithObjects:
                         @"姓名:", @"性別:", @"生日:",@"電話:", @"信箱:",nil];

    HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
    [self.navigationController.view addSubview:HUD];

    HUD.delegate = self;
    HUD.labelText = @"Loading";

    [self initResumeStatus];
//
//    //宣告一個按鈕
//    button = [[UIButton alloc]init];
//
//    //設定按鈕類型
//    button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//
//    //位置,大小
//    button.frame = CGRectMake(115,590,150,100);
//    [button setTitleColor:[UIColor whiteColor]forState:UIControlStateNormal];
//    [button.titleLabel setFont:[UIFont fontWithName:@"GillSans-Light"size:21]];
//
//    //按鈕文字
//    [button setTitle:@"邀請" forState:UIControlStateNormal];
    //攔截按鈕的訊息,並觸發button方法
//    [button addTarget:self action:@selector(buttonpress:) forControlEvents:(UIControlEventTouchUpInside)];
//    [self.view addSubview:button];

}

-(void) initResumeStatus
{
    PFQuery *query = [PFQuery queryWithClassName:@"ApplyManageTable"];

    [query whereKey:@"apply_id" equalTo:self.user.objectId];
    [query whereKey:@"case_id" equalTo:self.caseObject.objectId];

    [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error){
        if (!error) {
            PFObject *object = [objects lastObject];
            NSString *status = object[@"status"];
            if ([status isEqualToString:@"應徵"]) {

            }else
            {
                self.displayinvitedBtn.enabled = false;
                self.displayinvitedBtn.title = @"已邀請";
            }
        }

    }];

    PFFile *userImageFile = self.user[@"avatar"];

    if (userImageFile != nil)
    {

        [userImageFile getDataInBackgroundWithBlock:^(NSData *imageData, NSError *error) {
            if (!error) {
                if (imageData) {
                    UIImage *image = [UIImage imageWithData:imageData];
                    self.avatarImageView.image = image;
                }

            }else
            {
                NSLog(@"%@", error.description);
            }
            [MBProgressHUD hideHUDForView:self.view animated:YES];
        }];
    }else
    {
        [MBProgressHUD hideHUDForView:self.view animated:YES];
    }

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return 5;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    SettingTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"resumeCell"];

    //cell.dataTextField.delegate = self;
    NSArray *view = [[NSBundle mainBundle] loadNibNamed:@"SettingCells"owner:nil options:nil];

    cell = (SettingTableViewCell *)[view lastObject];

    //履歷圖示初始化
    cell.iconTitle.image = [UIImage imageNamed:imagearray[indexPath.row]];

    cell.titleLabel.hidden = NO;
    cell.iconTitle.hidden = NO;

    //履歷文字初始化 index.row讀取陣列的資料
    cell.titleLabel.text = textarray[indexPath.row];

    switch (indexPath.row) {
        case RE_USER_NICKNAME:
            cell.dataLabel.text = user[@"nickname"];
            break;
        case RE_USER_GENDER:
            cell.dataLabel.text = user[@"gender"];
            break;
        case RE_USER_BIRTHDAY:
            cell.dataLabel.text = user[@"birthday"];
            break;
        case RE_USER_PHONE:
            cell.dataLabel.text = user[@"phone"];
            break;
        case RE_USER_EMAIL:
            cell.dataLabel.text = user[@"email"];
            break;
        default:
            break;
    }
    return cell;
}
- (IBAction)InviteBtnAction:(id)sender
{
    NSLog(@"button press");
    NSString *ownerID = [PFUser currentUser].objectId;
    NSString *jobSeekerID = self.user.objectId;
    NSString *caseID = self.caseObject.objectId;

    PFQuery *query = [PFQuery queryWithClassName:@"ApplyManageTable"];
    [query whereKey:@"owner_id" equalTo:ownerID];
    [query whereKey:@"apply_id" equalTo:jobSeekerID];
    [query whereKey:@"case_id" equalTo:caseID];

    [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (!error) {
            NSLog(@"ApplyManageTable record neumber error %ld", (unsigned long)objects.count);

            for (int i=0; i<(objects.count - 1); i++) {
                PFObject *record = [objects objectAtIndex:i];
                record[@"status"] = @"邀請";
                [record saveInBackground];
            }

            PFObject *record = [objects lastObject];
            record[@"status"] = @"邀請";
            [record saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error){
                if (succeeded) {
                    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"應徵訊息" message:@"已發送應徵訊息" preferredStyle:UIAlertControllerStyleAlert];

                    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:
                                               ^(UIAlertAction *action)
                                               {
                                                   self.displayinvitedBtn.enabled = false;
                                                   self.displayinvitedBtn.title = @"已邀請";
                                               }];
                    [alertController addAction:okAction];
                    [self presentViewController:alertController animated:YES completion:nil];
                }
                else
                {
                    NSLog(@"Resume: saveInBackgroundWithBlock %@",error.description);
                }
                [MBProgressHUD hideHUDForView:self.view animated:YES];
            }];

        }
        else
        {
            NSLog(@"Resume: findObjectsInBackgroundWithBlock %@",error.description);
        }
    }];

}

// -(void)buttonpress:(id)sender
//{
//
//}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end


text:
#if defined(__ENGINE_PUSH_H__)
#error "Pop must be included to pop warnings, please use #include \"warnings/pop.h\""
#endif

#pragma once
#ifndef __ENGINE_PUSH_H__
#define __ENGINE_PUSH_H__

#undef __ENGINE_POP_H__

#if defined(__clang__)
#   pragma clang diagnostic push
#endif

#if defined(_MSC_VER)
#   pragma warning(push)
#endif

#if defined(__GNUC__) && !defined(__clang__)
#   pragma GCC diagnostic push
#endif

#if defined(__ICL)
#   pragma warning push
#endif

#endif


text:
//===--- SILProfiler.cpp - Instrumentation based profiling ----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/SIL/SILProfiler.h"
#include "swift/AST/ASTWalker.h"
#include "swift/AST/Decl.h"
#include "swift/AST/Expr.h"
#include "swift/AST/Module.h"
#include "swift/AST/SourceFile.h"
#include "swift/AST/Stmt.h"
#include "swift/Parse/Lexer.h"
#include "swift/SIL/FormalLinkage.h"
#include "swift/SIL/SILModule.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/ProfileData/Coverage/CoverageMapping.h"
#include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"
#include "llvm/ProfileData/InstrProf.h"

#include <forward_list>

#define DEBUG_TYPE "SILProfiler"

using namespace swift;

/// Check if a closure has a body.
static bool doesClosureHaveBody(AbstractClosureExpr *ACE) {
  if (auto *CE = dyn_cast<ClosureExpr>(ACE))
    return CE->getBody();
  if (auto *autoCE = dyn_cast<AutoClosureExpr>(ACE))
    return autoCE->getBody();
  return false;
}

/// Check whether a root AST node is unmapped, i.e not profiled.
static bool isUnmapped(ASTNode N) {
  // Do not map AST nodes with invalid source locations.
  if (N.getStartLoc().isInvalid() || N.getEndLoc().isInvalid()) {
    LLVM_DEBUG(llvm::dbgs()
               << "Skipping ASTNode: invalid start/end locations\n");
    return true;
  }

  if (auto *E = N.dyn_cast<Expr *>()) {
    if (auto *CE = dyn_cast<AbstractClosureExpr>(E)) {
      // Only map closure expressions with bodies.
      if (!doesClosureHaveBody(CE)) {
        LLVM_DEBUG(llvm::dbgs() << "Skipping ASTNode: closure without body\n");
        return true;
      }

      // Don't map implicit closures, unless they're autoclosures.
      if (!isa<AutoClosureExpr>(CE) && CE->isImplicit()) {
        LLVM_DEBUG(llvm::dbgs() << "Skipping ASTNode: implicit closure expr\n");
        return true;
      }
    }

    // Map all other kinds of expressions.
    return false;
  }

  auto *D = N.get<Decl *>();
  if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D)) {
    // Don't map functions without bodies.
    if (!AFD->hasBody()) {
      LLVM_DEBUG(llvm::dbgs() << "Skipping ASTNode: function without body\n");
      return true;
    }

    // Map implicit getters.
    if (auto *accessor = dyn_cast<AccessorDecl>(AFD))
      if (accessor->isImplicit() && accessor->isGetter())
        return false;
  }

  // Skip any remaining implicit, or otherwise unsupported decls.
  if (D->isImplicit() || isa<EnumCaseDecl>(D)) {
    LLVM_DEBUG(llvm::dbgs() << "Skipping ASTNode: implicit/unsupported decl\n");
    return true;
  }

  return false;
}

namespace swift {
bool doesASTRequireProfiling(SILModule &M, ASTNode N) {
  return M.getOptions().GenerateProfile && !isUnmapped(N);
}
} // namespace swift

/// Get the DeclContext for the decl referenced by \p forDecl.
DeclContext *getProfilerContextForDecl(ASTNode N, SILDeclRef forDecl) {
  if (auto *D = N.dyn_cast<Decl *>())
    if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D))
      return TLCD;
  assert(!forDecl.isNull() && "Expected a nonnull SILDeclRef");
  if (auto *ACE = forDecl.getAbstractClosureExpr())
    return ACE;
  return forDecl.getDecl()->getDeclContext();
}

static Stmt *getProfilerStmtForCase(CaseStmt *caseStmt) {
  switch (caseStmt->getParentKind()) {
  case CaseParentKind::Switch:
    return caseStmt;
  case CaseParentKind::DoCatch:
    return caseStmt->getBody();
  }
  llvm_unreachable("invalid parent kind");
}

/// Check that the input AST has at least been type-checked.
LLVM_ATTRIBUTE_UNUSED
static bool hasASTBeenTypeChecked(ASTNode N, SILDeclRef forDecl) {
  DeclContext *DC = getProfilerContextForDecl(N, forDecl);
  SourceFile *SF = DC->getParentSourceFile();
  return !SF || SF->ASTStage >= SourceFile::TypeChecked;
}

/// Check whether a mapped AST node requires a new profiler.
static bool canCreateProfilerForAST(ASTNode N, SILDeclRef forDecl) {
  assert(hasASTBeenTypeChecked(N, forDecl) &&
         "Cannot use this AST for profiling");

  if (auto *D = N.dyn_cast<Decl *>()) {
    if (isa<AbstractFunctionDecl>(D))
      return true;

    if (isa<TopLevelCodeDecl>(D))
      return true;
  } else if (N.get<Expr *>()) {
    if (forDecl.isStoredPropertyInitializer() ||
        forDecl.isPropertyWrapperBackingInitializer() ||
        forDecl.getAbstractClosureExpr())
      return true;
  }
  return false;
}

SILProfiler *SILProfiler::create(SILModule &M, ForDefinition_t forDefinition,
                                 ASTNode N, SILDeclRef forDecl) {
  // Avoid generating profiling state for declarations.
  if (!forDefinition)
    return nullptr;

  const auto &Opts = M.getOptions();
  if (!doesASTRequireProfiling(M, N) && Opts.UseProfile.empty())
    return nullptr;

  if (!canCreateProfilerForAST(N, forDecl)) {
    N.dump(llvm::errs());
    llvm_unreachable("Invalid AST node for profiling");
  }

  auto *Buf = M.allocate<SILProfiler>(1);
  auto *SP =
      ::new (Buf) SILProfiler(M, N, forDecl, Opts.EmitProfileCoverageMapping);
  SP->assignRegionCounters();
  return SP;
}

namespace {

/// Special logic for handling function visitation.
///
/// To avoid creating duplicate mappings, a function decl is only profiled if
/// it hasn't been reached via recursive walk.
///
/// Apply \p Func if the function can be visited.
template <typename F>
bool visitFunctionDecl(ASTWalker &Walker, AbstractFunctionDecl *AFD, F Func) {
  bool continueWalk = Walker.Parent.isNull();
  if (continueWalk)
    Func();
  return continueWalk;
}

/// Whether to skip visitation of an expression. Children of skipped exprs
/// should still be visited.
static bool skipExpr(Expr *E) {
  return !E->getStartLoc().isValid() || !E->getEndLoc().isValid();
}

/// Whether the children of an unmapped decl should still be walked.
static bool shouldWalkUnmappedDecl(const Decl *D) {
  // We want to walk into the initializer for a pattern binding decl. This
  // allows us to map LazyInitializerExprs.
  return isa<PatternBindingDecl>(D);
}

/// An ASTWalker that maps ASTNodes to profiling counters.
struct MapRegionCounters : public ASTWalker {
  /// The next counter value to assign.
  unsigned NextCounter = 0;

  /// The map of statements to counters.
  llvm::DenseMap<ASTNode, unsigned> &CounterMap;

  MapRegionCounters(llvm::DenseMap<ASTNode, unsigned> &CounterMap)
      : CounterMap(CounterMap) {}

  LazyInitializerWalking getLazyInitializerWalkingBehavior() override {
    // We want to walk lazy initializers present in the synthesized getter for
    // a lazy variable.
    return LazyInitializerWalking::InAccessor;
  }

  void mapRegion(ASTNode N) {
    CounterMap[N] = NextCounter;

    LLVM_DEBUG({
      llvm::dbgs() << "Assigned counter #" << NextCounter << " to: ";
      auto *E = N.dyn_cast<Expr *>();
      if (E)
        llvm::dbgs() << Expr::getKindName(E->getKind()) << "\n";
      auto *S = N.dyn_cast<Stmt *>();
      if (S)
        llvm::dbgs() << Stmt::getKindName(S->getKind()) << "\n";
    });

    ++NextCounter;
  }

  bool walkToDeclPre(Decl *D) override {
    if (isUnmapped(D))
      return shouldWalkUnmappedDecl(D);

    if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D)) {
      return visitFunctionDecl(*this, AFD, [&] { mapRegion(AFD->getBody()); });
    } else if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D)) {
      mapRegion(TLCD->getBody());
    }
    return true;
  }

  std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
    if (auto *IS = dyn_cast<IfStmt>(S)) {
      mapRegion(IS->getThenStmt());
    } else if (auto *US = dyn_cast<GuardStmt>(S)) {
      mapRegion(US->getBody());
    } else if (auto *WS = dyn_cast<WhileStmt>(S)) {
      mapRegion(WS->getBody());
    } else if (auto *RWS = dyn_cast<RepeatWhileStmt>(S)) {
      mapRegion(RWS->getBody());
    } else if (auto *FES = dyn_cast<ForEachStmt>(S)) {
      mapRegion(FES->getBody());
    } else if (auto *CS = dyn_cast<CaseStmt>(S)) {
      mapRegion(getProfilerStmtForCase(CS));
    }
    return {true, S};
  }

  std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
    if (skipExpr(E))
      return {true, E};

    // Profiling for closures should be handled separately. Do not visit
    // closure expressions twice.
    if (isa<AbstractClosureExpr>(E) && !Parent.isNull())
      return {false, E};

    // If AST visitation begins with an expression, the counter map must be
    // empty. Set up a counter for the root.
    if (Parent.isNull()) {
      assert(CounterMap.empty() && "Mapped a region before visiting the root?");
      mapRegion(E);
    }

    if (auto *IE = dyn_cast<IfExpr>(E)) {
      mapRegion(IE->getThenExpr());
    }

    if (isa<LazyInitializerExpr>(E))
      mapRegion(E);

    return {true, E};
  }
};

/// A node in an expression tree of counters.
class CounterExpr {
  enum class Kind { Node, Add, Sub, Zero, Ref };
  Kind K;
  ASTNode Node;
  const CounterExpr *LHS;
  const CounterExpr *RHS;

  CounterExpr(Kind K) : K(K) {
    assert((K == Kind::Zero) && "only valid for Zero");
  }

  CounterExpr(Kind K, ASTNode Node) : K(K), Node(Node) {
    assert(K == Kind::Node && "only valid for Node");
  }

  CounterExpr(Kind K, const CounterExpr &LHS) : K(K), LHS(&LHS) {
    assert((K == Kind::Ref) && "only valid for Ref");
  }

  CounterExpr(Kind K, const CounterExpr &LHS, const CounterExpr &RHS)
      : K(K), LHS(&LHS), RHS(&RHS) {
    assert((K == Kind::Add || K == Kind::Sub) && "only valid for operators");
  }

public:
  // Move only.
  CounterExpr(const CounterExpr &) = delete;
  void operator=(const CounterExpr &) = delete;
  CounterExpr(CounterExpr &&Other) = default;
  CounterExpr &operator=(CounterExpr &&RHS) = default;

  static CounterExpr Leaf(ASTNode Node) {
    return CounterExpr(Kind::Node, Node);
  }
  static CounterExpr Add(const CounterExpr &LHS, const CounterExpr &RHS) {
    return CounterExpr(Kind::Add, LHS, RHS);
  }
  static CounterExpr Sub(const CounterExpr &LHS, const CounterExpr &RHS) {
    return CounterExpr(Kind::Sub, LHS, RHS);
  }
  static CounterExpr Zero() { return CounterExpr(Kind::Zero); }
  static CounterExpr Ref(const CounterExpr &LHS) {
    return CounterExpr(Kind::Ref, LHS);
  }

  /// Return the referenced node, or null if this is not a Ref type.
  const CounterExpr *getReferencedNode() const {
    return K == Kind::Ref ? LHS : nullptr;
  }

  /// Returns true if this is a Zero node.
  bool isZero() const { return K == Kind::Zero; }

  /// Returns true if the counter is semantically a Zero node. This considers
  /// the simplified version of the counter that has eliminated redundant
  /// operations.
  bool isSemanticallyZero() const {
    // Run the counter through the counter builder to simplify it, using a dummy
    // mapping of unique counter indices for each node reference. The value of
    // the indices doesn't matter, but we need to ensure that e.g subtraction
    // of a node from itself cancels out.
    llvm::coverage::CounterExpressionBuilder Builder;
    llvm::DenseMap<ASTNode, unsigned> DummyIndices;
    unsigned LastIdx = 0;
    auto Counter = expand(Builder, [&](auto Node) {
      if (!DummyIndices.count(Node)) {
        DummyIndices[Node] = LastIdx;
        LastIdx += 1;
      }
      return DummyIndices[Node];
    });
    return Counter.isZero();
  }

  /// Expand this node into an llvm::coverage::Counter.
  ///
  /// Updates \c Builder with any expressions that are needed to represent this
  /// counter.
  llvm::coverage::Counter
  expand(llvm::coverage::CounterExpressionBuilder &Builder,
         llvm::function_ref<unsigned(ASTNode)> GetCounterIdx) const {
    switch (K) {
    case Kind::Zero:
      return llvm::coverage::Counter::getZero();
    case Kind::Node:
      return llvm::coverage::Counter::getCounter(GetCounterIdx(Node));
    case Kind::Add:
      return Builder.add(LHS->expand(Builder, GetCounterIdx),
                         RHS->expand(Builder, GetCounterIdx));
    case Kind::Sub:
      return Builder.subtract(LHS->expand(Builder, GetCounterIdx),
                              RHS->expand(Builder, GetCounterIdx));
    case Kind::Ref:
      return LHS->expand(Builder, GetCounterIdx);
    }

    llvm_unreachable("Unhandled Kind in switch.");
  }

  /// Expand this node into an llvm::coverage::Counter.
  ///
  /// Updates \c Builder with any expressions that are needed to represent this
  /// counter.
  llvm::coverage::Counter
  expand(llvm::coverage::CounterExpressionBuilder &Builder,
         const llvm::DenseMap<ASTNode, unsigned> &Counters) const {
    return expand(Builder, [&](auto Node) {
      auto Result = Counters.find(Node);
      assert(Result != Counters.end() && "Counter not found");
      return Result->second;
    });
  }

  void print(raw_ostream &OS) const {
    switch (K) {
    case Kind::Zero:
      OS << "zero";
      return;
    case Kind::Node:
      OS << "node(" << Node.getOpaqueValue() << ")";
      return;
    case Kind::Add:
    case Kind::Sub:
      LHS->print(OS);
      OS << ' ' << ((K == Kind::Add) ? '+' : '-') << ' ';
      RHS->print(OS);
      return;
    case Kind::Ref:
      OS << "ref(";
      LHS->print(OS);
      OS << ")";
      return;
    }
    llvm_unreachable("Unhandled Kind in switch.");
  }

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); }
#endif
};

/// A region of source code that can be mapped to a counter.
class SourceMappingRegion {
  ASTNode Node;

  CounterExpr *Count;

  /// The region's starting location.
  Optional<SourceLoc> StartLoc;

  /// The region's ending location.
  Optional<SourceLoc> EndLoc;

public:
  SourceMappingRegion(ASTNode Node, CounterExpr &Count,
                      Optional<SourceLoc> StartLoc, Optional<SourceLoc> EndLoc)
      : Node(Node), Count(&Count), StartLoc(StartLoc), EndLoc(EndLoc) {
    assert((!StartLoc || StartLoc->isValid()) &&
           "Expected start location to be valid");
    assert((!EndLoc || EndLoc->isValid()) &&
           "Expected end location to be valid");
  }

  SourceMappingRegion(SourceMappingRegion &&Region) = default;
  SourceMappingRegion &operator=(SourceMappingRegion &&RHS) = default;

  ASTNode getNode() const { return Node; }

  CounterExpr &getCounter() const { return *Count; }

  bool hasStartLoc() const { return StartLoc.hasValue(); }

  void setStartLoc(SourceLoc Loc) {
    assert(Loc.isValid());
    StartLoc = Loc;
  }

  const SourceLoc &getStartLoc() const {
    assert(StartLoc && "Region has no start location");
    return *StartLoc;
  }

  bool hasEndLoc() const { return EndLoc.hasValue(); }

  void setEndLoc(SourceLoc Loc) {
    assert(Loc.isValid());
    EndLoc = Loc;
  }

  const SourceLoc &getEndLoc() const {
    assert(EndLoc && "Region has no end location");
    return *EndLoc;
  }

  void print(llvm::raw_ostream &OS, const SourceManager &SM) const {
    OS << "[";
    if (hasStartLoc())
      getStartLoc().print(OS, SM);
    else
      OS << "?";
    OS << ", ";
    if (hasEndLoc())
      getEndLoc().print(OS, SM);
    else
      OS << "?";
    OS << "]";
  }
};

/// An ASTWalker that maps ASTNodes to profiling counters.
///
/// TODO: We ought to be able to leverage the CounterExprs from the
/// CoverageMapping walker to recompute the correct counter information
/// for this walker.
struct PGOMapping : public ASTWalker {
  /// The counter indices for AST nodes.
  const llvm::DenseMap<ASTNode, unsigned> &CounterMap;

  /// The loaded counter data.
  const llvm::InstrProfRecord &LoadedCounts;

  /// The output map of statements to counters.
  llvm::DenseMap<ASTNode, ProfileCounter> &LoadedCounterMap;
  llvm::DenseMap<ASTNode, ASTNode> &CondToParentMap;

  PGOMapping(const llvm::DenseMap<ASTNode, unsigned> &CounterMap,
             const llvm::InstrProfRecord &LoadedCounts,
             llvm::DenseMap<ASTNode, ProfileCounter> &LoadedCounterMap,
             llvm::DenseMap<ASTNode, ASTNode> &RegionCondToParentMap)
      : CounterMap(CounterMap), LoadedCounts(LoadedCounts),
        LoadedCounterMap(LoadedCounterMap),
        CondToParentMap(RegionCondToParentMap) {}

  /// Retrieve the counter index for a leaf node.
  unsigned getCounterIndex(ASTNode Node) const {
    auto result = CounterMap.find(Node);
    assert(result != CounterMap.end() && "Unmapped node?");
    return result->second;
  }

  unsigned getParentCounter() const {
    if (Parent.isNull())
      return 0;
    else if (Parent.getKind() == ASTWalker::ParentKind::Decl) {
      auto it = CounterMap.find(Parent.getAsDecl());
      return (it != CounterMap.end()) ? it->getSecond() : 0;
    } else if (Parent.getKind() == ASTWalker::ParentKind::Stmt) {
      auto it = CounterMap.find(Parent.getAsStmt());
      return (it != CounterMap.end()) ? it->getSecond() : 0;
    } else if (Parent.getKind() == ASTWalker::ParentKind::Expr) {
      auto it = CounterMap.find(Parent.getAsExpr());
      return (it != CounterMap.end()) ? it->getSecond() : 0;
    }
    return 0;
  }

  ProfileCounter subtract(ProfileCounter L, ProfileCounter R) {
    if (!L.hasValue() || !R.hasValue()) {
      return L;
    }
    uint64_t LV = L.getValue();
    uint64_t RV = R.getValue();
    assert(LV >= RV && "Invalid counter subtraction");
    return LV - RV;
  }

  /// Load the execution count corresponding to \p Node from a profile, if one
  /// is available.
  ProfileCounter loadExecutionCount(ASTNode Node) {
    if (!Node)
      return ProfileCounter();

    auto CounterIt = CounterMap.find(Node);
    assert(CounterIt != CounterMap.end() &&
           "region does not have an associated counter");

    unsigned CounterIndexForFunc = CounterIt->second;
    return LoadedCounts.Counts[CounterIndexForFunc];
  }

  /// Record the execution count for a leaf node.
  void setKnownExecutionCount(ASTNode Node) {
    LoadedCounterMap[Node] = loadExecutionCount(Node);
  }

  /// Record a computed execution count for a node.
  void setExecutionCount(ASTNode Node, ProfileCounter count) {
    LoadedCounterMap[Node] = count;
  }

  bool walkToDeclPre(Decl *D) override {
    if (isUnmapped(D))
      return shouldWalkUnmappedDecl(D);
    if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D)) {
      return visitFunctionDecl(*this, AFD, [&] {
        setKnownExecutionCount(AFD->getBody());
      });
    }
    if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D))
      setKnownExecutionCount(TLCD->getBody());

    return true;
  }

  LazyInitializerWalking getLazyInitializerWalkingBehavior() override {
    // We want to walk lazy initializers present in the synthesized getter for
    // a lazy variable.
    return LazyInitializerWalking::InAccessor;
  }

  std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
    unsigned parent = getParentCounter();
    auto parentCount = LoadedCounts.Counts[parent];
    if (auto *IS = dyn_cast<IfStmt>(S)) {
      auto thenStmt = IS->getThenStmt();
      auto thenCount = loadExecutionCount(thenStmt);
      setExecutionCount(thenStmt, thenCount);
      if (auto elseStmt = IS->getElseStmt()) {
        auto count = parentCount;
        if (!parent) {
          auto thenVal = thenCount.getValue();
          for (auto pCount = getCounterIndex(thenStmt); pCount > 0; --pCount) {
            auto cCount = LoadedCounts.Counts[pCount];
            if (cCount > thenVal) {
              count = cCount;
              break;
            }
          }
        }
        setExecutionCount(elseStmt, subtract(count, thenCount));
        auto Cond = IS->getCond();
        for (const auto &elt : Cond) {
          if (elt.getKind() ==
              StmtConditionElement::ConditionKind::CK_PatternBinding) {
            CondToParentMap[elt.getInitializer()] = IS;
          }
        }
      }
    } else if (auto *GS = dyn_cast<GuardStmt>(S)) {
      auto guardBody = GS->getBody();
      auto guardCount = loadExecutionCount(guardBody);
      setExecutionCount(guardBody, guardCount);
      setExecutionCount(GS, subtract(parentCount, guardCount));
    } else if (auto *WS = dyn_cast<WhileStmt>(S)) {
      setKnownExecutionCount(WS->getBody());
      setExecutionCount(WS, parentCount);
    } else if (auto *RWS = dyn_cast<RepeatWhileStmt>(S)) {
      setKnownExecutionCount(RWS->getBody());
      setExecutionCount(RWS, parentCount);
    } else if (auto *FES = dyn_cast<ForEachStmt>(S)) {
      setKnownExecutionCount(FES->getBody());
      setExecutionCount(FES, parentCount);
    } else if (auto *CS = dyn_cast<CaseStmt>(S)) {
      setKnownExecutionCount(getProfilerStmtForCase(CS));
    }
    return {true, S};
  }

  std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
    if (skipExpr(E))
      return {true, E};

    // Profiling for closures should be handled separately. Do not visit
    // closure expressions twice.
    if (isa<AbstractClosureExpr>(E) && !Parent.isNull())
      return {false, E};

    unsigned parent = getParentCounter();

    if (Parent.isNull())
      setKnownExecutionCount(E);

    if (auto *IE = dyn_cast<IfExpr>(E)) {
      auto thenExpr = IE->getThenExpr();
      auto thenCount = loadExecutionCount(thenExpr);
      setExecutionCount(thenExpr, thenCount);
      auto elseExpr = IE->getElseExpr();
      assert(elseExpr && "An if-expr must have an else subexpression");
      auto count = LoadedCounts.Counts[parent];
      if (!parent) {
        auto thenVal = thenCount.getValue();
        for (auto pCount = getCounterIndex(thenExpr); pCount > 0; --pCount) {
          auto cCount = LoadedCounts.Counts[pCount];
          if (cCount > thenVal) {
            count = cCount;
            break;
          }
        }
      }
      setExecutionCount(elseExpr, subtract(count, thenCount));
    }
    if (isa<LazyInitializerExpr>(E))
      setKnownExecutionCount(E);

    return {true, E};
  }
};

/// Produce coverage mapping information for a function. This involves taking
/// the counters computed by MapRegionCounters, and annotating the source with
/// regions that are defined in terms of those counters.
struct CoverageMapping : public ASTWalker {
private:
  const SourceManager &SM;

  /// Storage for counter expressions.
  std::forward_list<CounterExpr> Exprs;

  /// The map of statements to counter expressions.
  llvm::DenseMap<ASTNode, CounterExpr *> CounterMap;

  /// The source mapping regions for this function.
  std::vector<SourceMappingRegion> SourceRegions;

  /// A stack of currently live regions.
  std::vector<SourceMappingRegion> RegionStack;

  /// A stack of active repeat-while loops.
  std::vector<RepeatWhileStmt *> RepeatWhileStack;

  /// A stack of active do-catch statements.
  std::vector<DoCatchStmt *> DoCatchStack;

  CounterExpr *ExitCounter = nullptr;

  Stmt *ImplicitTopLevelBody = nullptr;

  /// Return true if \c Node has an associated counter.
  bool hasCounter(ASTNode Node) { return CounterMap.count(Node); }

  /// Return the region counter for \c Node.
  ///
  /// This should only be called on statements that have a dedicated counter.
  CounterExpr &getCounter(ASTNode Node) {
    assert(CounterMap.count(Node) && "No counter found");
    return *CounterMap[Node];
  }

  /// Create a counter expression.
  CounterExpr &createCounter(CounterExpr &&Expr) {
    Exprs.push_front(std::move(Expr));
    return Exprs.front();
  }

  /// Create a counter expression for \c Node and add it to the map.
  CounterExpr &assignCounter(ASTNode Node, CounterExpr &&Expr) {
    assert(Node && "Assigning counter expression to non-existent AST node");
    CounterExpr &Result = createCounter(std::move(Expr));
    CounterMap[Node] = &Result;
    return Result;
  }

  /// Create a counter expression referencing \c Node's own counter.
  CounterExpr &assignCounter(ASTNode Node) {
    return assignCounter(Node, CounterExpr::Leaf(Node));
  }

  /// Add \c Expr to \c Node's counter.
  void addToCounter(ASTNode Node, CounterExpr &Expr) {
    CounterExpr &Counter = getCounter(Node);
    if (const CounterExpr *ReferencedCounter = Counter.getReferencedNode())
      Counter = CounterExpr::Add(*ReferencedCounter, Expr);
    else if (Counter.isZero())
      Counter = CounterExpr::Ref(Expr);
    else
      Counter = CounterExpr::Add(createCounter(std::move(Counter)), Expr);
  }

  /// Subtract \c Expr from \c Node's counter.
  void subtractFromCounter(ASTNode Node, CounterExpr &Expr) {
    CounterExpr &Counter = getCounter(Node);
    assert(!Counter.isZero() && "Cannot create a negative counter");
    if (const CounterExpr *ReferencedCounter = Counter.getReferencedNode())
      Counter = CounterExpr::Sub(*ReferencedCounter, Expr);
    else
      Counter = CounterExpr::Sub(createCounter(std::move(Counter)), Expr);
  }

  /// Return the current region's counter.
  CounterExpr &getCurrentCounter() { return getRegion().getCounter(); }

  /// Get the counter from the end of the most recent scope.
  CounterExpr &getExitCounter() {
    assert(ExitCounter && "no exit counter available");
    return *ExitCounter;
  }

  /// Set the exit count so we can leave the scope related to \c Node
  ///
  /// Returns the delta of the count on entering \c Node and exiting, or null if
  /// there was no change.
  CounterExpr *setExitCount(ASTNode Node) {
    ExitCounter = &getCurrentCounter();
    if (hasCounter(Node) && ExitCounter != &getCounter(Node))
      return &createCounter(CounterExpr::Sub(getCounter(Node), *ExitCounter));
    return nullptr;
  }

  /// Adjust the count for control flow when exiting a scope.
  void adjustForNonLocalExits(ASTNode Scope, CounterExpr *ControlFlowAdjust) {
    if (Parent.getAsDecl())
      return;

    CounterExpr *JumpsToLabel = nullptr;
    Stmt *ParentStmt = Parent.getAsStmt();
    if (ParentStmt) {
      if (isa<DoCatchStmt>(ParentStmt))
        return;
      auto caseStmt = dyn_cast_or_null<CaseStmt>(ParentStmt);
      if (caseStmt && caseStmt->getParentKind() == CaseParentKind::DoCatch)
        return;
      if (auto *LS = dyn_cast<LabeledStmt>(ParentStmt))
        JumpsToLabel = &getCounter(LS);
    }

    if (!ControlFlowAdjust && !JumpsToLabel)
      return;

    CounterExpr *Count = &getCurrentCounter();
    // Add the counts from jumps directly to the label (such as breaks)
    if (JumpsToLabel)
      Count = &createCounter(CounterExpr::Add(*Count, *JumpsToLabel));
    // Now apply any adjustments for control flow.
    if (ControlFlowAdjust)
      Count = &createCounter(CounterExpr::Sub(*Count, *ControlFlowAdjust));

    replaceCount(Count, getEndLoc(Scope));
  }

  /// Push a region covering \c Node onto the stack.
  void pushRegion(ASTNode Node) {
    RegionStack.emplace_back(Node, getCounter(Node), Node.getStartLoc(),
                             getEndLoc(Node));
    LLVM_DEBUG({
      llvm::dbgs() << "Pushed region: ";
      RegionStack.back().print(llvm::dbgs(), SM);
      llvm::dbgs() << "\n";
    });
  }

  /// Replace the current region at \p Start with a new counter. If \p Start is
  /// \c None, or the counter is semantically zero, an 'incomplete' region is
  /// formed, which is not recorded unless followed by additional AST nodes.
  void replaceCount(CounterExpr *Counter, Optional<SourceLoc> Start) {
    // If the counter is semantically zero, form an 'incomplete' region with
    // no starting location. This prevents forming unreachable regions unless
    // there is a following statement or expression to extend the region.
    if (Start && Counter->isSemanticallyZero())
      Start = None;

    RegionStack.emplace_back(ASTNode(), *Counter, Start, None);
  }

  /// Replace the current region at \p Start with a new counter. If \p Start is
  /// \c None, or the counter is semantically zero, an 'incomplete' region is
  /// formed, which is not recorded unless followed by additional AST nodes.
  void replaceCount(CounterExpr &&Expr, Optional<SourceLoc> Start) {
    replaceCount(&createCounter(std::move(Expr)), Start);
  }

  /// Get the location for the end of the last token in \c Node.
  SourceLoc getEndLoc(ASTNode Node) {
    return Lexer::getLocForEndOfToken(SM, Node.getEndLoc());
  }

  /// Pop regions from the stack into the function's list of regions.
  ///
  /// Adds all regions from \c ParentNode to the top of the stack to the
  /// function's \c SourceRegions.
  void popRegions(ASTNode ParentNode) {
    auto I = RegionStack.begin(), E = RegionStack.end();
    while (I != E &&
           I->getNode().getOpaqueValue() != ParentNode.getOpaqueValue())
      ++I;
    assert(I != E && "parent not in stack");
    auto ParentIt = I;
    SourceLoc EndLoc = ParentIt->getEndLoc();

    unsigned FirstPoppedIndex = SourceRegions.size();
    (void)FirstPoppedIndex;
    SourceRegions.push_back(std::move(*I++));
    for (; I != E; ++I) {
      if (!I->hasStartLoc())
        continue;
      if (!I->hasEndLoc())
        I->setEndLoc(EndLoc);
      SourceRegions.push_back(std::move(*I));
    }

    LLVM_DEBUG({
      for (unsigned Idx = FirstPoppedIndex; Idx < SourceRegions.size(); ++Idx) {
        llvm::dbgs() << "Popped region: ";
        SourceRegions[Idx].print(llvm::dbgs(), SM);
        llvm::dbgs() << "\n";
      }
    });

    RegionStack.erase(ParentIt, E);
  }

  /// Return the currently active region.
  SourceMappingRegion &getRegion() {
    assert(!RegionStack.empty() && "statement has no region");
    return RegionStack.back();
  }

  /// Ensure that \c S is included in the current region.
  void extendRegion(ASTNode S) {
    SourceMappingRegion &Region = getRegion();
    SourceLoc StartLoc = S.getStartLoc();
    if (!Region.hasStartLoc())
      Region.setStartLoc(StartLoc);
  }

  /// Mark \c S as a terminator, starting a zero region.
  void terminateRegion(ASTNode S) {
    SourceMappingRegion &Region = getRegion();
    if (!Region.hasEndLoc())
      Region.setEndLoc(getEndLoc(S));
    replaceCount(CounterExpr::Zero(), /*Start*/ None);
  }

  Expr *getConditionNode(StmtCondition SC) {
    assert(!SC.empty() && "Empty condition");
    return SC.front().getBooleanOrNull();
  }

public:
  CoverageMapping(const SourceManager &SM) : SM(SM) {}

  LazyInitializerWalking getLazyInitializerWalkingBehavior() override {
    // We want to walk lazy initializers present in the synthesized getter for
    // a lazy variable.
    return LazyInitializerWalking::InAccessor;
  }

  /// Generate the coverage counter mapping regions from collected
  /// source regions.
  SILCoverageMap *emitSourceRegions(
      SILModule &M, StringRef Name, StringRef PGOFuncName, uint64_t Hash,
      llvm::DenseMap<ASTNode, unsigned> &CounterIndices, StringRef Filename) {
    if (SourceRegions.empty())
      return nullptr;

    llvm::coverage::CounterExpressionBuilder Builder;
    std::vector<SILCoverageMap::MappedRegion> Regions;
    for (const auto &Region : SourceRegions) {
      assert(Region.hasStartLoc() && "invalid region");
      assert(Region.hasEndLoc() && "incomplete region");

      auto Start = SM.getLineAndColumnInBuffer(Region.getStartLoc());
      auto End = SM.getLineAndColumnInBuffer(Region.getEndLoc());
      assert(Start.first <= End.first && "region start and end out of order");

      Regions.emplace_back(Start.first, Start.second, End.first, End.second,
                           Region.getCounter().expand(Builder, CounterIndices));
    }
    return SILCoverageMap::create(M, Filename, Name, PGOFuncName, Hash, Regions,
                                  Builder.getExpressions());
  }

  bool walkToDeclPre(Decl *D) override {
    if (isUnmapped(D))
      return shouldWalkUnmappedDecl(D);

    if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D)) {
      return visitFunctionDecl(*this, AFD, [&] {
        assignCounter(AFD->getBody());
      });
    } else if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D)) {
      assignCounter(TLCD->getBody());
      ImplicitTopLevelBody = TLCD->getBody();
    }
    return true;
  }

  bool walkToDeclPost(Decl *D) override {
    if (isa<TopLevelCodeDecl>(D))
      ImplicitTopLevelBody = nullptr;
    return true;
  }

  std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
    if (S->isImplicit() && S != ImplicitTopLevelBody)
      return {true, S};

    // If we're in an 'incomplete' region, update it to include this node. This
    // ensures we only create the region if needed.
    if (!RegionStack.empty())
      extendRegion(S);

    if (auto *BS = dyn_cast<BraceStmt>(S)) {
      if (hasCounter(BS))
        pushRegion(BS);

    } else if (auto *IS = dyn_cast<IfStmt>(S)) {
      if (auto *Cond = getConditionNode(IS->getCond()))
        assignCounter(Cond, CounterExpr::Ref(getCurrentCounter()));

      // The counter for the if statement itself tracks the number of jumps to
      // it by break statements.
      assignCounter(IS, CounterExpr::Zero());

      // We emit a counter for the then block, and define the else block in
      // terms of it.
      CounterExpr &ThenCounter = assignCounter(IS->getThenStmt());
      if (IS->getElseStmt())
        assignCounter(IS->getElseStmt(),
                      CounterExpr::Sub(getCurrentCounter(), ThenCounter));
    } else if (auto *GS = dyn_cast<GuardStmt>(S)) {
      assignCounter(GS, CounterExpr::Zero());
      assignCounter(GS->getBody());

    } else if (auto *WS = dyn_cast<WhileStmt>(S)) {
      // The counter for the while statement itself tracks the number of jumps
      // to it by break and continue statements.
      assignCounter(WS, CounterExpr::Zero());

      if (auto *E = getConditionNode(WS->getCond()))
        assignCounter(E, CounterExpr::Ref(getCurrentCounter()));
      assignCounter(WS->getBody());

    } else if (auto *RWS = dyn_cast<RepeatWhileStmt>(S)) {
      // The counter for the while statement itself tracks the number of jumps
      // to it by break and continue statements.
      assignCounter(RWS, CounterExpr::Zero());

      CounterExpr &BodyCounter = assignCounter(RWS->getBody());
      assignCounter(RWS->getCond(), CounterExpr::Ref(BodyCounter));
      RepeatWhileStack.push_back(RWS);

    } else if (auto *FES = dyn_cast<ForEachStmt>(S)) {
      // The counter for the for statement itself tracks the number of jumps
      // to it by break and continue statements.
      assignCounter(FES, CounterExpr::Zero());
      assignCounter(FES->getBody());

    } else if (auto *SS = dyn_cast<SwitchStmt>(S)) {
      // The counter for the switch statement itself tracks the number of jumps
      // to it by break statements, including the implicit breaks at the end of
      // cases.
      assignCounter(SS, CounterExpr::Zero());

      assignCounter(SS->getSubjectExpr(),
                    CounterExpr::Ref(getCurrentCounter()));

      // Assign counters for cases so they're available for fallthrough.
      for (CaseStmt *Case : SS->getCases())
        assignCounter(Case);

    } else if (auto caseStmt = dyn_cast<CaseStmt>(S)) {
      if (caseStmt->getParentKind() == CaseParentKind::Switch)
        pushRegion(S);
    } else if (auto *DS = dyn_cast<DoStmt>(S)) {
      // The counter for the do statement itself tracks the number of jumps
      // to it by break statements.
      assignCounter(DS, CounterExpr::Zero());

      assignCounter(DS->getBody(), CounterExpr::Ref(getCurrentCounter()));

    } else if (auto *DCS = dyn_cast<DoCatchStmt>(S)) {
      // The do-catch body is visited the same number of times as its parent.
      assignCounter(DCS->getBody(), CounterExpr::Ref(getCurrentCounter()));

      for (CaseStmt *Catch : DCS->getCatches())
        assignCounter(Catch->getBody());

      // Initialize the exit count of the do-catch to the entry count, then
      // subtract off non-local exits as they are visited.
      assignCounter(DCS, CounterExpr::Ref(getCurrentCounter()));
      DoCatchStack.push_back(DCS);
    }
    return {true, S};
  }

  Stmt *walkToStmtPost(Stmt *S) override {
    if (S->isImplicit() && S != ImplicitTopLevelBody)
      return S;

    if (isa<BraceStmt>(S)) {
      if (hasCounter(S)) {
        CounterExpr *Adjust = setExitCount(S);
        popRegions(S);
        adjustForNonLocalExits(S, Adjust);
      }

    } else if (auto *WS = dyn_cast<WhileStmt>(S)) {
      // Update the condition with the backedge count.
      if (auto *E = getConditionNode(WS->getCond()))
        addToCounter(E, getExitCounter());

    } else if (auto *RWS = dyn_cast<RepeatWhileStmt>(S)) {
      assert(RepeatWhileStack.back() == RWS && "Malformed repeat-while stack");
      (void)RWS;
      RepeatWhileStack.pop_back();

    } else if (auto *CS = dyn_cast<ContinueStmt>(S)) {
      // Continues create extra backedges, add them to the appropriate counters.
      if (!isa<RepeatWhileStmt>(CS->getTarget()))
        addToCounter(CS->getTarget(), getCurrentCounter());
      if (auto *WS = dyn_cast<WhileStmt>(CS->getTarget())) {
        if (auto *E = getConditionNode(WS->getCond()))
          addToCounter(E, getCurrentCounter());
      }
      terminateRegion(S);

    } else if (auto *BS = dyn_cast<BreakStmt>(S)) {
      // When we break from a loop, we need to adjust the exit count.
      Stmt *BreakTarget = BS->getTarget();
      if (auto *RWS = dyn_cast<RepeatWhileStmt>(BreakTarget)) {
        subtractFromCounter(RWS->getCond(), getCurrentCounter());
      } else {
        // Update the exit counter for the target.
        addToCounter(BS->getTarget(), getCurrentCounter());
      }

      // The break also affects the exit counts of active do-catch statements.
      for (auto *DCS : DoCatchStack)
        subtractFromCounter(DCS, getCurrentCounter());

      terminateRegion(S);

    } else if (auto *FS = dyn_cast<FallthroughStmt>(S)) {
      addToCounter(FS->getFallthroughDest(), getCurrentCounter());
      terminateRegion(S);

    } else if (isa<SwitchStmt>(S)) {
      replaceCount(CounterExpr::Ref(getCounter(S)), getEndLoc(S));

    } else if (auto caseStmt = dyn_cast<CaseStmt>(S)) {
      if (caseStmt->getParentKind() == CaseParentKind::Switch) {
        // The end of a case block is an implicit break, update the exit
        // counter to reflect this.
        addToCounter(caseStmt->getParentStmt(), getCurrentCounter());
        popRegions(S);
      }
    } else if (auto *DCS = dyn_cast<DoCatchStmt>(S)) {
      assert(DoCatchStack.back() == DCS && "Malformed do-catch stack");
      DoCatchStack.pop_back();
      replaceCount(CounterExpr::Ref(getCounter(S)), getEndLoc(S));

    } else if (isa<ReturnStmt>(S) || isa<FailStmt>(S) || isa<ThrowStmt>(S)) {
      // When we return, adjust loop condition counts and do-catch exit counts
      // to reflect the early exit.
      if (isa<ReturnStmt>(S) || isa<FailStmt>(S)) {
        for (auto *RWS : RepeatWhileStack)
          subtractFromCounter(RWS->getCond(), getCurrentCounter());
        for (auto *DCS : DoCatchStack)
          subtractFromCounter(DCS, getCurrentCounter());
      }

      terminateRegion(S);
    }
    return S;
  }

  std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
    if (skipExpr(E))
      return {true, E};

    // Profiling for closures should be handled separately. Do not visit
    // closure expressions twice.
    if (isa<AbstractClosureExpr>(E) && !Parent.isNull())
      return {false, E};

    // If we're in an 'incomplete' region, update it to include this node. This
    // ensures we only create the region if needed.
    if (!RegionStack.empty())
      extendRegion(E);

    // If AST visitation begins with an expression, the region stack must be
    // empty. Set up a region for the root.
    if (Parent.isNull()) {
      assert(RegionStack.empty() &&
             "Mapped a region before visiting the root?");
      assignCounter(E);
      pushRegion(E);
    }

    // If there isn't an active region, we may be visiting a default
    // initializer for a function argument.
    if (!RegionStack.empty()) {
      if (auto *IE = dyn_cast<IfExpr>(E)) {
        CounterExpr &ThenCounter = assignCounter(IE->getThenExpr());
        assignCounter(IE->getElseExpr(),
                      CounterExpr::Sub(getCurrentCounter(), ThenCounter));
      }
    }

    if (isa<LazyInitializerExpr>(E))
      assignCounter(E);

    if (hasCounter(E) && !Parent.isNull())
      pushRegion(E);
    return {true, E};
  }

  Expr *walkToExprPost(Expr *E) override {
    if (hasCounter(E))
      popRegions(E);

    return E;
  }
};

} // end anonymous namespace

static llvm::GlobalValue::LinkageTypes
getEquivalentPGOLinkage(FormalLinkage Linkage) {
  switch (Linkage) {
  case FormalLinkage::PublicUnique:
  case FormalLinkage::PublicNonUnique:
    return llvm::GlobalValue::ExternalLinkage;

  case FormalLinkage::HiddenUnique:
  case FormalLinkage::Private:
    return llvm::GlobalValue::PrivateLinkage;
  }

  llvm_unreachable("Unhandled FormalLinkage in switch.");
}

static StringRef getCurrentFileName(ASTNode N, SILDeclRef forDecl) {
  DeclContext *Ctx = getProfilerContextForDecl(N, forDecl);
  if (auto *ParentFile = Ctx->getParentSourceFile())
    return ParentFile->getFilename();
  return {};
}

void SILProfiler::assignRegionCounters() {
  const auto &SM = M.getASTContext().SourceMgr;

  CurrentFileName = getCurrentFileName(Root, forDecl);

  MapRegionCounters Mapper(RegionCounterMap);

  std::string CurrentFuncName;
  FormalLinkage CurrentFuncLinkage;
  if (auto *D = Root.dyn_cast<Decl *>()) {
    if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D)) {
      CurrentFuncName = forDecl.mangle();
      CurrentFuncLinkage = getDeclLinkage(AFD);
    } else {
      auto *TLCD = cast<TopLevelCodeDecl>(D);
      llvm::raw_string_ostream OS{CurrentFuncName};
      OS << "__tlcd_";
      TLCD->getStartLoc().printLineAndColumn(OS, SM);
      CurrentFuncLinkage = FormalLinkage::HiddenUnique;
    }
  } else {
    CurrentFuncName = forDecl.mangle();
    CurrentFuncLinkage = FormalLinkage::HiddenUnique;
  }

  PGOFuncName = llvm::getPGOFuncName(
      CurrentFuncName, getEquivalentPGOLinkage(CurrentFuncLinkage),
      CurrentFileName);

  assert((!CurrentFuncName.empty() && !PGOFuncName.empty()) &&
         "Expected covered region to be named");

  LLVM_DEBUG(llvm::dbgs() << "Assigning counters to: " << CurrentFuncName
                          << "\n");
  Root.walk(Mapper);

  NumRegionCounters = Mapper.NextCounter;
  // TODO: Mapper needs to calculate a function hash as it goes.
  PGOFuncHash = 0x0;

  if (EmitCoverageMapping) {
    CoverageMapping Coverage(SM);
    Root.walk(Coverage);
    CovMap =
        Coverage.emitSourceRegions(M, CurrentFuncName, PGOFuncName, PGOFuncHash,
                                   RegionCounterMap, CurrentFileName);
  }

  if (llvm::IndexedInstrProfReader *IPR = M.getPGOReader()) {
    auto LoadedCounts = IPR->getInstrProfRecord(PGOFuncName, PGOFuncHash);
    if (auto E = LoadedCounts.takeError()) {
      llvm::handleAllErrors(std::move(E), [](const llvm::InstrProfError &Err) {
        Err.log(llvm::dbgs());
        return;
      });
      llvm::dbgs() << PGOFuncName << "\n";
      return;
    }
    PGOMapping pgoMapper(RegionCounterMap, LoadedCounts.get(),
                         RegionLoadedCounterMap, RegionCondToParentMap);
    Root.walk(pgoMapper);
  }
}

ProfileCounter SILProfiler::getExecutionCount(ASTNode Node) {
  if (!Node || !M.getPGOReader() || !hasRegionCounters()) {
    return ProfileCounter();
  }
  auto it = RegionLoadedCounterMap.find(Node);
  if (it == RegionLoadedCounterMap.end()) {
    return ProfileCounter();
  }
  return it->getSecond();
}

Optional<ASTNode> SILProfiler::getPGOParent(ASTNode Node) {
  if (!Node || !M.getPGOReader() || !hasRegionCounters()) {
    return None;
  }
  auto it = RegionCondToParentMap.find(Node);
  if (it == RegionCondToParentMap.end()) {
    return None;
  }
  return it->getSecond();
}


text:
<?php
/**
 * patForms Date subelement Meridiem
 *
 * Handles year input and validation for the date element
 *
 * $Id: Meridiem.php,v 1.1 2006/04/03 20:41:04 eric Exp $
 *
 * @access		public
 * @package		patForms
 * @subpackage	Element
 * @author		Sebastian 'The Argh' Mordziol <argh@php-tools.net>
 */

/**
 * Notice: the meridiem can only be used with the 12-hour date format.
 */
 define( 'PATFORMS_ELEMENT_DATE_ELEMENT_MERIDIEM_NOTICE_NOT_VALID_HERE', 'patForms:Element:Date:Element:Meridiem:01' );

/**
 * patForms Date subelement Meridiem
 *
 * Handles year input and validation for the date element
 *
 * $Id: Meridiem.php,v 1.1 2006/04/03 20:41:04 eric Exp $
 *
 * @access		public
 * @package		patForms
 * @subpackage	Element
 * @author		Sebastian 'The Argh' Mordziol <argh@php-tools.net>
 */
class patForms_Element_Date_Element_Meridiem extends patForms_Element_Date_Element
{
   /**
	* Stores all needed token configurations, i.e. the length and output
	* format of the corresponding values.
	*
	* @access	private
	* @var		array
	*/
	var $tokens = array(
		'a' => array(
			'length'	=>	2,
			'format'	=>	'%s',
		),
		'A' => array(
			'length'	=>	2,
			'format'	=>	'%s',
		),
	);

   /**
	* Stores display names for the meridiems in the available locales.
	*
	* @access	private
	* @var		array
	*/
	var $displayNames = array(
		'C' => array(
			'am' => 'am',
			'pm' => 'pm',
		),
		'de' => array(
			'am' => 'Vormittag',
			'pm' => 'Nachmittag',
		),
		'fr' => array(
			'am' => 'Matin',
			'pm' => 'Après-midi',
		)
	);

   /**
	* Retrieves values for the selector when using the preset mode.
	*
	* @access	private
	* @return	array	$values	Values list in patForms format
	*/
	function getValues()
	{
		$values = array();

		foreach( $this->displayNames[$this->locale] as $meridiem => $label ) {

			if( $this->token == 'A' ) {
				$label = strtoupper( $label );
			}

			array_push(
				$values,
				array(
					'label' => $label,
					'value' => $meridiem
				)
			);
		}

		return $values;
	}

   /**
	* Custom serialize method that checks fot the presence of the related
	* 12-hour format token. If not present, this will trigger a notice and
	* cancel the serialization process.
	*
	* @access	public
	* @return	string	$content	The serialized element
	*/
	function serialize()
	{
		$validTokens = array(
			'g',
			'h'
		);

		foreach( $validTokens as $token ) {
			if( $this->parent->tokenUsed( $token ) ) {
				return parent::serialize();
			}
		}

		patErrorManager::raiseNotice(
			PATFORMS_ELEMENT_DATE_ELEMENT_MERIDIEM_NOTICE_NOT_VALID_HERE,
			'You have used a meridiem in your date format, but a meridiem only makes sense if you also set the hour format to 12-hour format. Meridiem ignored.'
		);

		return '';
	}
}

?>


text:
Panel

Nombre:

Nivel:

Intentos:

		<button type="button" id="siguienteBtn" class="btn btn-primary btn-lg hidden">Siguiente Nivel</button>
		<button type="button" id="volverEmpezarBtn" class="btn btn-success btn-md hidden">Volver a empezar</button>
		<button type="button" id="reiniciarBtn" class="btn btn-warning btn-lg hidden">Reinicar Nivel</button>

Usuarios Conectados