/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"

#if SDL_VIDEO_DRIVER_WINRT

/* Windows-specific includes */
#include <Windows.h>
#include <agile.h>

/* SDL-specific includes */
#include <SDL.h>
#include "SDL_winrtevents_c.h"

extern "C" {
#include "../../events/scancodes_windows.h"
#include "../../events/SDL_keyboard_c.h"
}

static SDL_Scancode WinRT_Official_Keycodes[] = {
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.None -- 0 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.LeftButton -- 1 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.RightButton -- 2 */
    SDL_SCANCODE_CANCEL,        /* VirtualKey.Cancel -- 3 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.MiddleButton -- 4 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.XButton1 -- 5 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.XButton2 -- 6 */
    SDL_SCANCODE_UNKNOWN,       /* -- 7 */
    SDL_SCANCODE_BACKSPACE,     /* VirtualKey.Back -- 8 */
    SDL_SCANCODE_TAB,           /* VirtualKey.Tab -- 9 */
    SDL_SCANCODE_UNKNOWN,       /* -- 10 */
    SDL_SCANCODE_UNKNOWN,       /* -- 11 */
    SDL_SCANCODE_CLEAR,         /* VirtualKey.Clear -- 12 */
    SDL_SCANCODE_RETURN,        /* VirtualKey.Enter -- 13 */
    SDL_SCANCODE_UNKNOWN,       /* -- 14 */
    SDL_SCANCODE_UNKNOWN,       /* -- 15 */
    SDL_SCANCODE_LSHIFT,        /* VirtualKey.Shift -- 16 */
    SDL_SCANCODE_LCTRL,         /* VirtualKey.Control -- 17 */
    SDL_SCANCODE_MENU,          /* VirtualKey.Menu -- 18 */
    SDL_SCANCODE_PAUSE,         /* VirtualKey.Pause -- 19 */
    SDL_SCANCODE_CAPSLOCK,      /* VirtualKey.CapitalLock -- 20 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Kana or VirtualKey.Hangul -- 21 */
    SDL_SCANCODE_UNKNOWN,       /* -- 22 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Junja -- 23 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Final -- 24 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Hanja or VirtualKey.Kanji -- 25 */
    SDL_SCANCODE_UNKNOWN,       /* -- 26 */
    SDL_SCANCODE_ESCAPE,        /* VirtualKey.Escape -- 27 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Convert -- 28 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.NonConvert -- 29 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Accept -- 30 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.ModeChange -- 31  (maybe SDL_SCANCODE_MODE ?) */
    SDL_SCANCODE_SPACE,         /* VirtualKey.Space -- 32 */
    SDL_SCANCODE_PAGEUP,        /* VirtualKey.PageUp -- 33 */
    SDL_SCANCODE_PAGEDOWN,      /* VirtualKey.PageDown -- 34 */
    SDL_SCANCODE_END,           /* VirtualKey.End -- 35 */
    SDL_SCANCODE_HOME,          /* VirtualKey.Home -- 36 */
    SDL_SCANCODE_LEFT,          /* VirtualKey.Left -- 37 */
    SDL_SCANCODE_UP,            /* VirtualKey.Up -- 38 */
    SDL_SCANCODE_RIGHT,         /* VirtualKey.Right -- 39 */
    SDL_SCANCODE_DOWN,          /* VirtualKey.Down -- 40 */
    SDL_SCANCODE_SELECT,        /* VirtualKey.Select -- 41 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Print -- 42  (maybe SDL_SCANCODE_PRINTSCREEN ?) */
    SDL_SCANCODE_EXECUTE,       /* VirtualKey.Execute -- 43 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Snapshot -- 44 */
    SDL_SCANCODE_INSERT,        /* VirtualKey.Insert -- 45 */
    SDL_SCANCODE_DELETE,        /* VirtualKey.Delete -- 46 */
    SDL_SCANCODE_HELP,          /* VirtualKey.Help -- 47 */
    SDL_SCANCODE_0,             /* VirtualKey.Number0 -- 48 */
    SDL_SCANCODE_1,             /* VirtualKey.Number1 -- 49 */
    SDL_SCANCODE_2,             /* VirtualKey.Number2 -- 50 */
    SDL_SCANCODE_3,             /* VirtualKey.Number3 -- 51 */
    SDL_SCANCODE_4,             /* VirtualKey.Number4 -- 52 */
    SDL_SCANCODE_5,             /* VirtualKey.Number5 -- 53 */
    SDL_SCANCODE_6,             /* VirtualKey.Number6 -- 54 */
    SDL_SCANCODE_7,             /* VirtualKey.Number7 -- 55 */
    SDL_SCANCODE_8,             /* VirtualKey.Number8 -- 56 */
    SDL_SCANCODE_9,             /* VirtualKey.Number9 -- 57 */
    SDL_SCANCODE_UNKNOWN,       /* -- 58 */
    SDL_SCANCODE_UNKNOWN,       /* -- 59 */
    SDL_SCANCODE_UNKNOWN,       /* -- 60 */
    SDL_SCANCODE_UNKNOWN,       /* -- 61 */
    SDL_SCANCODE_UNKNOWN,       /* -- 62 */
    SDL_SCANCODE_UNKNOWN,       /* -- 63 */
    SDL_SCANCODE_UNKNOWN,       /* -- 64 */
    SDL_SCANCODE_A,             /* VirtualKey.A -- 65 */
    SDL_SCANCODE_B,             /* VirtualKey.B -- 66 */
    SDL_SCANCODE_C,             /* VirtualKey.C -- 67 */
    SDL_SCANCODE_D,             /* VirtualKey.D -- 68 */
    SDL_SCANCODE_E,             /* VirtualKey.E -- 69 */
    SDL_SCANCODE_F,             /* VirtualKey.F -- 70 */
    SDL_SCANCODE_G,             /* VirtualKey.G -- 71 */
    SDL_SCANCODE_H,             /* VirtualKey.H -- 72 */
    SDL_SCANCODE_I,             /* VirtualKey.I -- 73 */
    SDL_SCANCODE_J,             /* VirtualKey.J -- 74 */
    SDL_SCANCODE_K,             /* VirtualKey.K -- 75 */
    SDL_SCANCODE_L,             /* VirtualKey.L -- 76 */
    SDL_SCANCODE_M,             /* VirtualKey.M -- 77 */
    SDL_SCANCODE_N,             /* VirtualKey.N -- 78 */
    SDL_SCANCODE_O,             /* VirtualKey.O -- 79 */
    SDL_SCANCODE_P,             /* VirtualKey.P -- 80 */
    SDL_SCANCODE_Q,             /* VirtualKey.Q -- 81 */
    SDL_SCANCODE_R,             /* VirtualKey.R -- 82 */
    SDL_SCANCODE_S,             /* VirtualKey.S -- 83 */
    SDL_SCANCODE_T,             /* VirtualKey.T -- 84 */
    SDL_SCANCODE_U,             /* VirtualKey.U -- 85 */
    SDL_SCANCODE_V,             /* VirtualKey.V -- 86 */
    SDL_SCANCODE_W,             /* VirtualKey.W -- 87 */
    SDL_SCANCODE_X,             /* VirtualKey.X -- 88 */
    SDL_SCANCODE_Y,             /* VirtualKey.Y -- 89 */
    SDL_SCANCODE_Z,             /* VirtualKey.Z -- 90 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.LeftWindows -- 91  (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_LGUI ?) */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.RightWindows -- 92  (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_RGUI ?) */
    SDL_SCANCODE_APPLICATION,   /* VirtualKey.Application -- 93 */
    SDL_SCANCODE_UNKNOWN,       /* -- 94 */
    SDL_SCANCODE_SLEEP,         /* VirtualKey.Sleep -- 95 */
    SDL_SCANCODE_KP_0,          /* VirtualKey.NumberPad0 -- 96 */
    SDL_SCANCODE_KP_1,          /* VirtualKey.NumberPad1 -- 97 */
    SDL_SCANCODE_KP_2,          /* VirtualKey.NumberPad2 -- 98 */
    SDL_SCANCODE_KP_3,          /* VirtualKey.NumberPad3 -- 99 */
    SDL_SCANCODE_KP_4,          /* VirtualKey.NumberPad4 -- 100 */
    SDL_SCANCODE_KP_5,          /* VirtualKey.NumberPad5 -- 101 */
    SDL_SCANCODE_KP_6,          /* VirtualKey.NumberPad6 -- 102 */
    SDL_SCANCODE_KP_7,          /* VirtualKey.NumberPad7 -- 103 */
    SDL_SCANCODE_KP_8,          /* VirtualKey.NumberPad8 -- 104 */
    SDL_SCANCODE_KP_9,          /* VirtualKey.NumberPad9 -- 105 */
    SDL_SCANCODE_KP_MULTIPLY,   /* VirtualKey.Multiply -- 106 */
    SDL_SCANCODE_KP_PLUS,       /* VirtualKey.Add -- 107 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Separator -- 108 */
    SDL_SCANCODE_KP_MINUS,      /* VirtualKey.Subtract -- 109 */
    SDL_SCANCODE_UNKNOWN,       /* VirtualKey.Decimal -- 110  (maybe SDL_SCANCODE_DECIMALSEPARATOR, SDL_SCANCODE_KP_DECIMAL, or SDL_SCANCODE_KP_PERIOD ?) */
    SDL_SCANCODE_KP_DIVIDE,     /* VirtualKey.Divide -- 111 */
    SDL_SCANCODE_F1,            /* VirtualKey.F1 -- 112 */
    SDL_SCANCODE_F2,            /* VirtualKey.F2 -- 113 */
    SDL_SCANCODE_F3,            /* VirtualKey.F3 -- 114 */
    SDL_SCANCODE_F4,            /* VirtualKey.F4 -- 115 */
    SDL_SCANCODE_F5,            /* VirtualKey.F5 -- 116 */
    SDL_SCANCODE_F6,            /* VirtualKey.F6 -- 117 */
    SDL_SCANCODE_F7,            /* VirtualKey.F7 -- 118 */
    SDL_SCANCODE_F8,            /* VirtualKey.F8 -- 119 */
    SDL_SCANCODE_F9,            /* VirtualKey.F9 -- 120 */
    SDL_SCANCODE_F10,           /* VirtualKey.F10 -- 121 */
    SDL_SCANCODE_F11,           /* VirtualKey.F11 -- 122 */
    SDL_SCANCODE_F12,           /* VirtualKey.F12 -- 123 */
    SDL_SCANCODE_F13,           /* VirtualKey.F13 -- 124 */
    SDL_SCANCODE_F14,           /* VirtualKey.F14 -- 125 */
    SDL_SCANCODE_F15,           /* VirtualKey.F15 -- 126 */
    SDL_SCANCODE_F16,           /* VirtualKey.F16 -- 127 */
    SDL_SCANCODE_F17,           /* VirtualKey.F17 -- 128 */
    SDL_SCANCODE_F18,           /* VirtualKey.F18 -- 129 */
    SDL_SCANCODE_F19,           /* VirtualKey.F19 -- 130 */
    SDL_SCANCODE_F20,           /* VirtualKey.F20 -- 131 */
    SDL_SCANCODE_F21,           /* VirtualKey.F21 -- 132 */
    SDL_SCANCODE_F22,           /* VirtualKey.F22 -- 133 */
    SDL_SCANCODE_F23,           /* VirtualKey.F23 -- 134 */
    SDL_SCANCODE_F24,           /* VirtualKey.F24 -- 135 */
    SDL_SCANCODE_UNKNOWN,       /* -- 136 */
    SDL_SCANCODE_UNKNOWN,       /* -- 137 */
    SDL_SCANCODE_UNKNOWN,       /* -- 138 */
    SDL_SCANCODE_UNKNOWN,       /* -- 139 */
    SDL_SCANCODE_UNKNOWN,       /* -- 140 */
    SDL_SCANCODE_UNKNOWN,       /* -- 141 */
    SDL_SCANCODE_UNKNOWN,       /* -- 142 */
    SDL_SCANCODE_UNKNOWN,       /* -- 143 */
    SDL_SCANCODE_NUMLOCKCLEAR,  /* VirtualKey.NumberKeyLock -- 144 */
    SDL_SCANCODE_SCROLLLOCK,    /* VirtualKey.Scroll -- 145 */
    SDL_SCANCODE_UNKNOWN,       /* -- 146 */
    SDL_SCANCODE_UNKNOWN,       /* -- 147 */
    SDL_SCANCODE_UNKNOWN,       /* -- 148 */
    SDL_SCANCODE_UNKNOWN,       /* -- 149 */
    SDL_SCANCODE_UNKNOWN,       /* -- 150 */
    SDL_SCANCODE_UNKNOWN,       /* -- 151 */
    SDL_SCANCODE_UNKNOWN,       /* -- 152 */
    SDL_SCANCODE_UNKNOWN,       /* -- 153 */
    SDL_SCANCODE_UNKNOWN,       /* -- 154 */
    SDL_SCANCODE_UNKNOWN,       /* -- 155 */
    SDL_SCANCODE_UNKNOWN,       /* -- 156 */
    SDL_SCANCODE_UNKNOWN,       /* -- 157 */
    SDL_SCANCODE_UNKNOWN,       /* -- 158 */
    SDL_SCANCODE_UNKNOWN,       /* -- 159 */
    SDL_SCANCODE_LSHIFT,        /* VirtualKey.LeftShift -- 160 */
    SDL_SCANCODE_RSHIFT,        /* VirtualKey.RightShift -- 161 */
    SDL_SCANCODE_LCTRL,         /* VirtualKey.LeftControl -- 162 */
    SDL_SCANCODE_RCTRL,         /* VirtualKey.RightControl -- 163 */
    SDL_SCANCODE_MENU,          /* VirtualKey.LeftMenu -- 164 */
    SDL_SCANCODE_MENU,          /* VirtualKey.RightMenu -- 165 */
    SDL_SCANCODE_AC_BACK,       /* VirtualKey.GoBack -- 166 : The go back key. */
    SDL_SCANCODE_AC_FORWARD,    /* VirtualKey.GoForward -- 167 : The go forward key. */
    SDL_SCANCODE_AC_REFRESH,    /* VirtualKey.Refresh -- 168 : The refresh key. */
    SDL_SCANCODE_AC_STOP,       /* VirtualKey.Stop -- 169 : The stop key. */
    SDL_SCANCODE_AC_SEARCH,     /* VirtualKey.Search -- 170 : The search key. */
    SDL_SCANCODE_AC_BOOKMARKS,  /* VirtualKey.Favorites -- 171 : The favorites key. */
    SDL_SCANCODE_AC_HOME        /* VirtualKey.GoHome -- 172 : The go home key. */
};

/* Attempt to translate a keycode that isn't listed in WinRT's VirtualKey enum.
 */
static SDL_Scancode
WINRT_TranslateUnofficialKeycode(int keycode)
{
    switch (keycode) {
        case 173: return SDL_SCANCODE_MUTE;         /* VK_VOLUME_MUTE */
        case 174: return SDL_SCANCODE_VOLUMEDOWN;   /* VK_VOLUME_DOWN */
        case 175: return SDL_SCANCODE_VOLUMEUP;     /* VK_VOLUME_UP */
        case 176: return SDL_SCANCODE_AUDIONEXT;    /* VK_MEDIA_NEXT_TRACK */
        case 177: return SDL_SCANCODE_AUDIOPREV;    /* VK_MEDIA_PREV_TRACK */
        // case 178: return ;                       /* VK_MEDIA_STOP */
        case 179: return SDL_SCANCODE_AUDIOPLAY;    /* VK_MEDIA_PLAY_PAUSE */
        case 180: return SDL_SCANCODE_MAIL;         /* VK_LAUNCH_MAIL */
        case 181: return SDL_SCANCODE_MEDIASELECT;  /* VK_LAUNCH_MEDIA_SELECT */
        // case 182: return ;                       /* VK_LAUNCH_APP1 */
        case 183: return SDL_SCANCODE_CALCULATOR;   /* VK_LAUNCH_APP2 */
        // case 184: return ;                       /* ... reserved ... */
        // case 185: return ;                       /* ... reserved ... */
        case 186: return SDL_SCANCODE_SEMICOLON;    /* VK_OEM_1, ';:' key on US standard keyboards */
        case 187: return SDL_SCANCODE_EQUALS;       /* VK_OEM_PLUS */
        case 188: return SDL_SCANCODE_COMMA;        /* VK_OEM_COMMA */
        case 189: return SDL_SCANCODE_MINUS;        /* VK_OEM_MINUS */
        case 190: return SDL_SCANCODE_PERIOD;       /* VK_OEM_PERIOD */
        case 191: return SDL_SCANCODE_SLASH;        /* VK_OEM_2, '/?' key on US standard keyboards */
        case 192: return SDL_SCANCODE_GRAVE;        /* VK_OEM_3, '`~' key on US standard keyboards */
        // ?
        // ... reserved or unassigned ...
        // ?
        case 219: return SDL_SCANCODE_LEFTBRACKET;  /* VK_OEM_4, '[{' key on US standard keyboards */
        case 220: return SDL_SCANCODE_BACKSLASH;    /* VK_OEM_5, '\|' key on US standard keyboards */
        case 221: return SDL_SCANCODE_RIGHTBRACKET; /* VK_OEM_6, ']}' key on US standard keyboards */
        case 222: return SDL_SCANCODE_APOSTROPHE;   /* VK_OEM_7, 'single/double quote' on US standard keyboards */
        default: break;
    }
    return SDL_SCANCODE_UNKNOWN;
}

static SDL_Scancode
WINRT_TranslateKeycode(int keycode, unsigned int nativeScancode)
{
    // TODO, WinRT: try filling out the WinRT keycode table as much as possible, using the Win32 table for interpretation hints

    SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;

    /* HACK ALERT: At least one VirtualKey constant (Shift) with a left/right
     * designation might not get reported with its correct handedness, however
     * its hardware scan code can fill in the gaps.  If this is detected,
     * use the hardware scan code to try telling if the left, or the right
     * side's key was used.
     *
     * If Microsoft ever allows MapVirtualKey or MapVirtualKeyEx to be used
     * in WinRT apps, or something similar to these (it doesn't appear to be,
     * at least not for Windows [Phone] 8/8.1, as of Oct 24, 2014), then this
     * hack might become deprecated, or obsolete.
     */
    if (nativeScancode < SDL_arraysize(windows_scancode_table)) {
        switch (keycode) {
            case 16:    // VirtualKey.Shift
                switch (windows_scancode_table[nativeScancode]) {
                    case SDL_SCANCODE_LSHIFT:
                    case SDL_SCANCODE_RSHIFT:
                        return windows_scancode_table[nativeScancode];
                }
                break;

            // Add others, as necessary.
            //
            // Unfortunately, this hack doesn't seem to work in determining
            // handedness with Control keys.

            default:
                break;
        }
    }

    /* Try to get a documented, WinRT, 'VirtualKey' next (as documented at
       http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.virtualkey.aspx ).
       If that fails, fall back to a Win32 virtual key.
       If that fails, attempt to fall back to a scancode-derived key.
    */
    if (keycode < SDL_arraysize(WinRT_Official_Keycodes)) {
        scancode = WinRT_Official_Keycodes[keycode];
    }
    if (scancode == SDL_SCANCODE_UNKNOWN) {
        scancode = WINRT_TranslateUnofficialKeycode(keycode);
    }
    if (scancode == SDL_SCANCODE_UNKNOWN) {
        if (nativeScancode < SDL_arraysize(windows_scancode_table)) {
            scancode = windows_scancode_table[nativeScancode];
        }
    }
    /*
    if (scancode == SDL_SCANCODE_UNKNOWN) {
        SDL_Log("WinRT TranslateKeycode, unknown keycode=%d\n", (int)keycode);
    }
    */
    return scancode;
}

void
WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args)
{
    SDL_Scancode sdlScancode = WINRT_TranslateKeycode((int)args->VirtualKey, args->KeyStatus.ScanCode);
#if 0
    SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
    SDL_Log("key down, handled=%s, ext?=%s, released?=%s, menu key down?=%s, "
            "repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, "
            "sdl scan code=%d (%s), sdl key code=%d (%s)\n",
        (args->Handled ? "1" : "0"),
        (args->KeyStatus.IsExtendedKey ? "1" : "0"),
        (args->KeyStatus.IsKeyReleased ? "1" : "0"),
        (args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
        args->KeyStatus.RepeatCount,
        args->KeyStatus.ScanCode,
        (args->KeyStatus.WasKeyDown ? "1" : "0"),
        args->VirtualKey,
        sdlScancode,
        SDL_GetScancodeName(sdlScancode),
        keycode,
        SDL_GetKeyName(keycode));
    //args->Handled = true;
#endif
    SDL_SendKeyboardKey(SDL_PRESSED, sdlScancode);
}

void
WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args)
{
    SDL_Scancode sdlScancode = WINRT_TranslateKeycode((int)args->VirtualKey, args->KeyStatus.ScanCode);
#if 0
    SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode);
    SDL_Log("key up, handled=%s, ext?=%s, released?=%s, menu key down?=%s, "
            "repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, "
            "sdl scan code=%d (%s), sdl key code=%d (%s)\n",
        (args->Handled ? "1" : "0"),
        (args->KeyStatus.IsExtendedKey ? "1" : "0"),
        (args->KeyStatus.IsKeyReleased ? "1" : "0"),
        (args->KeyStatus.IsMenuKeyDown ? "1" : "0"),
        args->KeyStatus.RepeatCount,
        args->KeyStatus.ScanCode,
        (args->KeyStatus.WasKeyDown ? "1" : "0"),
        args->VirtualKey,
        sdlScancode,
        SDL_GetScancodeName(sdlScancode),
        keycode,
        SDL_GetKeyName(keycode));
    //args->Handled = true;
#endif
    SDL_SendKeyboardKey(SDL_RELEASED, sdlScancode);
}

void
WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^args)
{
    wchar_t src_ucs2[2];
    char dest_utf8[16];
    int result;

    /* Setup src */
    src_ucs2[0] = args->KeyCode;
    src_ucs2[1] = L'\0';

    /* Convert the text, then send an SDL_TEXTINPUT event. */
    result = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)&src_ucs2, -1, (LPSTR)dest_utf8, sizeof(dest_utf8), NULL, NULL);
    if (result > 0) {
        SDL_SendKeyboardText(dest_utf8);
    }
}

#if NTDDI_VERSION >= NTDDI_WIN10

SDL_bool WINRT_HasScreenKeyboardSupport(_THIS)
{
    return SDL_TRUE;
}

void WINRT_ShowScreenKeyboard(_THIS, SDL_Window *window)
{
    using namespace Windows::UI::ViewManagement;
    InputPane ^ inputPane = InputPane::GetForCurrentView();
    if (inputPane) {
        inputPane->TryShow();
    }
}

void WINRT_HideScreenKeyboard(_THIS, SDL_Window *window)
{
    using namespace Windows::UI::ViewManagement;
    InputPane ^ inputPane = InputPane::GetForCurrentView();
    if (inputPane) {
        inputPane->TryHide();
    }
}

SDL_bool WINRT_IsScreenKeyboardShown(_THIS, SDL_Window *window)
{
    using namespace Windows::UI::ViewManagement;
    InputPane ^ inputPane = InputPane::GetForCurrentView();
    if (inputPane) {
        // dludwig@pobox.com: checking inputPane->Visible doesn't seem to detect visibility,
        //   at least not on the Windows Phone 10.0.10240.0 emulator.  Checking
        //   the size of inputPane->OccludedRect, however, does seem to work.
        Windows::Foundation::Rect rect = inputPane->OccludedRect;
        if (rect.Width > 0 && rect.Height > 0) {
            return SDL_TRUE;
        }
    }
    return SDL_FALSE;
}

#endif  // NTDDI_VERSION >= ...

#endif // SDL_VIDEO_DRIVER_WINRT


//
// arch/x86_64/rsp/rsp.h
//
// Extern declarations for host RSP functions.
//
// This file is subject to the terms and conditions defined in
// 'LICENSE', which is part of this source code package.
//

#ifndef __arch_rsp_h__
#define __arch_rsp_h__

#ifdef __ARM_NEON
#define __SSSE3__
#include "SSE2NEON.h"
#elif defined(__SSE4_2__)
#include <nmmintrin.h>
#elif defined(__SSE4_1__)
#include <smmintrin.h>
#elif defined(__SSSE3__)
#include <tmmintrin.h>
#elif defined(__SSE3__)
#include <pmmintrin.h>
#else
#include <emmintrin.h>
#endif

#include <stdint.h>

typedef __m128i rsp_vect_t;

namespace RSP
{
struct CPUState;
}

// Loads and shuffles a 16x8 vector according to element.
#ifdef __SSSE3__
extern const uint16_t shuffle_keys[16][8];

static inline __m128i rsp_vect_load_and_shuffle_operand(const uint16_t *src, unsigned element)
{
	__m128i operand = _mm_load_si128((__m128i *)src);
	__m128i key = _mm_load_si128((__m128i *)shuffle_keys[element]);

	return _mm_shuffle_epi8(operand, key);
}
#else
__m128i rsp_vect_load_and_shuffle_operand(const uint16_t *src, unsigned element);
#endif

// Loads a vector without shuffling its elements.
static inline __m128i rsp_vect_load_unshuffled_operand(const uint16_t *src)
{
	return _mm_load_si128((__m128i *)src);
}

// Writes an operand back to memory.
static inline void rsp_vect_write_operand(uint16_t *dest, __m128i src)
{
	_mm_store_si128((__m128i *)dest, src);
}

static inline __m128i read_acc_lo(const uint16_t *acc)
{
	return rsp_vect_load_unshuffled_operand(acc + 16);
}
static inline __m128i read_acc_md(const uint16_t *acc)
{
	return rsp_vect_load_unshuffled_operand(acc + 8);
}
static inline __m128i read_acc_hi(const uint16_t *acc)
{
	return rsp_vect_load_unshuffled_operand(acc);
}
static inline __m128i read_vcc_lo(const uint16_t *vcc)
{
	return rsp_vect_load_unshuffled_operand(vcc + 8);
}
static inline __m128i read_vcc_hi(const uint16_t *vcc)
{
	return rsp_vect_load_unshuffled_operand(vcc);
}
static inline __m128i read_vco_lo(const uint16_t *vco)
{
	return rsp_vect_load_unshuffled_operand(vco + 8);
}
static inline __m128i read_vco_hi(const uint16_t *vco)
{
	return rsp_vect_load_unshuffled_operand(vco);
}
static inline __m128i read_vce(const uint16_t *vce)
{
	return rsp_vect_load_unshuffled_operand(vce + 8);
}
static inline void write_acc_lo(uint16_t *acc, __m128i acc_lo)
{
	rsp_vect_write_operand(acc + 16, acc_lo);
}
static inline void write_acc_md(uint16_t *acc, __m128i acc_md)
{
	rsp_vect_write_operand(acc + 8, acc_md);
}
static inline void write_acc_hi(uint16_t *acc, __m128i acc_hi)
{
	rsp_vect_write_operand(acc, acc_hi);
}
static inline void write_vcc_lo(uint16_t *vcc, __m128i vcc_lo)
{
	rsp_vect_write_operand(vcc + 8, vcc_lo);
}
static inline void write_vcc_hi(uint16_t *vcc, __m128i vcc_hi)
{
	rsp_vect_write_operand(vcc, vcc_hi);
}
static inline void write_vco_lo(uint16_t *vco, __m128i vco_lo)
{
	rsp_vect_write_operand(vco + 8, vco_lo);
}
static inline void write_vco_hi(uint16_t *vco, __m128i vco_hi)
{
	rsp_vect_write_operand(vco, vco_hi);
}
static inline void write_vce(uint16_t *vce, __m128i vce_r)
{
	rsp_vect_write_operand(vce + 8, vce_r);
}

// Returns scalar bitmasks for VCO/VCC/VCE.
static inline int16_t rsp_get_flags(const uint16_t *flags)
{
	return (int16_t)_mm_movemask_epi8(
	    _mm_packs_epi16(_mm_load_si128((__m128i *)(flags + 8)), _mm_load_si128((__m128i *)(flags + 0))));
}

void rsp_set_flags(uint16_t *flags, uint16_t rt);

// Zeroes out a vector register.
static inline __m128i rsp_vzero(void)
{
	return _mm_setzero_si128();
}

extern const uint16_t vdiv_mask_table[8][8];

#define HES(x) ((x) ^ 2)
#define BES(x) ((x) ^ 3)
#define MES(x) ((x) ^ 1)

#define READ_MEM_U8(mem, addr) (reinterpret_cast<const uint8_t *>(mem)[BES(addr)])
#define READ_MEM_U16(mem, addr) (reinterpret_cast<const uint16_t *>(mem)[HES(addr) >> 1])
#define READ_MEM_U32(mem, addr) (reinterpret_cast<const uint32_t *>(mem)[addr >> 2])

#define WRITE_MEM_U8(mem, addr, data) (reinterpret_cast<uint8_t *>(mem)[BES(addr)] = data)
#define WRITE_MEM_U16(mem, addr, data) (reinterpret_cast<uint16_t *>(mem)[HES(addr) >> 1] = data)
#define WRITE_MEM_U32(mem, addr, data) (reinterpret_cast<uint32_t *>(mem)[addr >> 2] = data)

#endif


<?hh // strict
/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

/**
 * This file was moved from fbsource to www. View old history in diffusion:
 * https://fburl.com/aa279jbn
 */
namespace Facebook\ShipIt;

use namespace HH\Lib\Str;

final class ShipItSyncPhase extends ShipItPhase {
  private ?string $firstCommit = null;
  private keyset<string> $skippedSourceCommits = keyset[];
  private ?string $patchesDirectory = null;
  private ?string $statsFilename = null;
  private bool $shouldDoSubmodules = true;

  public function __construct(
    private ShipItSyncConfig::TFilterFn $filter,
    private keyset<string> $destinationRoots = keyset[],
    private ?ShipItSyncConfig::TPostFilterChangesetsFn $postFilterChangesets =
      null,
    private ?bool $allowEmptyCommit = false,
  ) {}

  <<__Override>>
  protected function isProjectSpecific(): bool {
    return false;
  }

  <<__Override>>
  public function getReadableName(): string {
    return 'Synchronize commits';
  }

  <<__Override>>
  public function getCLIArguments(): vec<ShipItCLIArgument> {
    return vec[
      shape(
        'long_name' => 'skip-sync-commits',
        'description' => "Don't copy any commits. Handy for testing.",
        'write' => $_ ==> $this->skip(),
      ),
      shape(
        'long_name' => 'first-commit::',
        'description' => 'Hash of first commit that needs to be synced',
        'write' => $x ==> {
          $this->firstCommit = $x;
          return $this->firstCommit;
        },
      ),
      shape(
        'long_name' => 'save-patches-to::',
        'description' =>
          'Directory to copy created patches to. Useful for '.'debugging',
        'write' => $x ==> {
          $this->patchesDirectory = $x;
          return $this->patchesDirectory;
        },
      ),
      shape(
        'long_name' => 'skip-source-commits::',
        'description' => "Comma-separate list of source commit IDs to skip.",
        'write' => $x ==> {
          $this->skippedSourceCommits = keyset(Str\split($x, ','));
          foreach ($this->skippedSourceCommits as $commit) {
            // 7 happens to be the usual output
            if (Str\length($commit) < ShipItChangeset::SHORT_REV_LENGTH) {
              throw new ShipItException(
                'Skipped rev '.
                $commit.
                ' is potentially ambiguous; use a '.
                'longer id instead.',
              );
            }
          }
          return true;
        },
      ),
      shape(
        'long_name' => 'log-sync-stats-to::',
        'description' => 'The filename to log a JSON-encoded file with stats '.
          'about the sync, or a directory name to log a file '.
          'for each configured branch.',
        'write' => $x ==> {
          $this->statsFilename = $x;
          return $this->statsFilename;
        },
      ),
      shape(
        'long_name' => 'skip-post-filter-changesets',
        'description' =>
          'Skip any custom definitions for processing changesets after syncing',
        'write' => $_ ==> {
          $this->postFilterChangesets = null;
          return $this->postFilterChangesets;
        },
      ),
      shape(
        'long_name' => 'skip-submodules',
        'description' => 'Don\'t sync submodules',
        'write' => $_ ==> {
          $this->shouldDoSubmodules = false;
          return $this->shouldDoSubmodules;
        },
      ),
    ];
  }

  <<__Override>>
  protected function runImpl(ShipItManifest $manifest): void {
    $sync = (
      new ShipItSyncConfig(
        $manifest->getSourceRoots(),
        $this->filter,
        $this->postFilterChangesets,
      )
    )
      ->withDestinationRoots($this->destinationRoots)
      ->withFirstCommit($this->firstCommit)
      ->withSkippedSourceCommits($this->skippedSourceCommits)
      ->withPatchesDirectory($this->patchesDirectory)
      ->withStatsFilename($this->statsFilename)
      ->withAllowEmptyCommits($this->allowEmptyCommit)
      ->withShouldDoSubmodules($this->shouldDoSubmodules);

    (new ShipItSync($manifest, $sync))->run();
  }
}


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>content</key>
	<string>max-width: ${1:20}${2:px};$0</string>
	<key>name</key>
	<string>max-width: length</string>
	<key>scope</key>
	<string>source.css</string>
	<key>tabTrigger</key>
	<string>mw</string>
	<key>uuid</key>
	<string>1AAF1317-1228-4A37-844B-B096A8ABEB41</string>
</dict>
</plist>


## DBsubject(Calculus - multivariable)
## DBchapter(Vector calculus)
## DBsection(Line integrals)
## Institution(W.H.Freeman)
## Author(JustAsk - Kobi Fonarov)
## MLT(my_new_Line_Integrals)
## Level(3)
## MO(1)
## TitleText1('Calculus: Early Transcendentals')
## AuthorText1('Rogawski')
## EditionText1('2')
## Section1('16.2')
## Problem1('21')
## KEYWORDS('calculus')
## RESOURCES('image_16_2_25.png')

DOCUMENT();

loadMacros(
  "PGstandard.pl",
  "Parser.pl",
  "freemanMacros.pl",
  "PGgraphmacros.pl",
  "PGchoicemacros.pl",
  "PGcourse.pl"
);

TEXT(beginproblem());

Context()->texStrings;

$r=random(1,9);
$r2=$r**2;
$a=random(2,9);
$ar=$a*$r;
$ar2=$ar*$r;

$curve="\mathcal{C}";
$path="\mathbf{c}";
$FF="\mathbf{F}";
$answer=Real($ar2*2*$PI);

BEGIN_TEXT
\{ textbook_ref_exact("Rogawski ET 2e", "16.2","21") \}
$PAR
Compute the line integral of the vector field \(\mathbf{F}=\left< $a y,-$a x\right> \) over the circle \(x^2+y^2=$r2\) oriented clockwise

$PAR
\(\int_{$curve} $FF \cdot \,d\mathbf{\,s}  =\) \{ans_rule()\}
$PAR

END_TEXT
Context()->normalStrings;

ANS($answer->cmp);

Context()->texStrings;
SOLUTION(EV3(<<'END_SOLUTION'));
$PAR
$SOL $BR
\{image("image_16_2_25.png", width=>220, height=>221)\} With \(r_0=$r\)
$PAR
The oriented path is parametrized by $PAR
\(\mathbf{c}(t)=($r\cos t,$r\sin t); \quad t\) is changing from \(2\pi \) to \(0\). $PAR
We compute the integrand:
\[
$FF \left(\mathbf{c}(t)\right) =
\left<$a y,- $a x \right> =
\left< $ar \sin t,-$ar \cos t \right>
\]
\[\mathbf{c}'(t)= \left< -$r  \sin t,$r  \cos t \right> \]
\[
$FF \left(\mathbf{c}(t)\right)\cdot {\mathbf{c}}'(t) =
\left< $ar \sin t,-$ar \cos t \right> \cdot \left< -$r  \sin t,$r  \cos t\right>=
\]\[
-$ar2 \sin^2t -$ar2\cos^2t =-$ar2
\]
Hence,
\[
\int_{$curve} $FF \cdot \,d\mathbf{\,s}  =
\int_{2\pi }^0 $FF \left(\mathbf{c}(t)\right)\cdot {\mathbf{c}}'(t) \,dt=
\int_{2\pi }^0 -$ar2 \,dt=
\]\[
-$ar2 t \bigg|_{2\pi}^0=
\{$ar2*2\} \pi
\]

END_SOLUTION

ENDDOCUMENT();


<?php
/**
 * Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 * http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

namespace Aws\Common\Model\MultipartUpload;

use Aws\Common\Exception\InvalidArgumentException;

/**
 * An object that encapsulates the data for an upload part
 */
abstract class AbstractUploadPart implements UploadPartInterface
{
    /**
     * @var array A map of external array keys to internal property names
     */
    protected static $keyMap = array();

    /**
     * @var int The number of the upload part representing its order in the overall upload
     */
    protected $partNumber;

    /**
     * {@inheritdoc}
     */
    public static function fromArray($data)
    {
        $part = new static();
        $part->loadData($data);

        return $part;
    }

    /**
     * {@inheritdoc}
     */
    public function getPartNumber()
    {
        return $this->partNumber;
    }

    /**
     * {@inheritdoc}
     */
    public function toArray()
    {
        $array = array();
        foreach (static::$keyMap as $key => $property) {
            $array[$key] = $this->{$property};
        }

        return $array;
    }

    /**
     * {@inheritdoc}
     */
    public function serialize()
    {
        return serialize($this->toArray());
    }

    /**
     * {@inheritdoc}
     */
    public function unserialize($serialized)
    {
        $this->loadData(unserialize($serialized));
    }

    /**
     * Loads an array of data into the upload part by extracting only the needed keys
     *
     * @param array|\Traversable $data Data to load into the upload part value object
     *
     * @throws InvalidArgumentException if a required key is missing
     */
    protected function loadData($data)
    {
        foreach (static::$keyMap as $key => $property) {
            if (isset($data[$key])) {
                $this->{$property} = $data[$key];
            } else {
                throw new InvalidArgumentException("A required key [$key] was missing from the upload part.");
            }
        }
    }
}


// Copyright (C) 2016  Arista Networks, Inc.
// Use of this source code is governed by the Apache License 2.0

// Package monotime provides a fast monotonic clock source.

package monotime

import (
	"testing"
)

func TestNow(t *testing.T) {
	for i := 0; i < 100; i++ {
		t1 := Now()
		t2 := Now()
		// I honestly thought that we needed >= here, but in some environments
		// two consecutive calls can return the same value!
		if t1 > t2 {
			t.Fatalf("t1=%d should have been less than or equal to t2=%d", t1, t2)
		}
	}
}


<?xml version="1.0" encoding="UTF-8"?>
<Workspace
   version = "1.0">
   <FileRef
      location = "self:OwnTracks.xcodeproj">
   </FileRef>
</Workspace>


#logo {
  width: 100px;
  height: 100px;
  background: url('../assets/logo.png');
}


`vim2hs ⦂ Vim → Haskell`
========================

*"Vim to Haskell": A collection of vimscripts for Haskell development.*

Features
--------

* Written from scratch for clean and organized code, though some parts are
  borrowed from existing vimscripts.
* Highlights Haskell code in GitHub Flavored Markdown, and Literate Haskell
  documents as Markdown.
* Improved syntax highlighting including Haddock markup in comments,
  support for HSP and many quasi-quotes such as jmacro, shqq, regex, sql,
  string interpolation...
* Liberal syntax highlighting for Cabal package descriptions, yielding less
  false-positives for mistakes than other syntax files for Cabal.
* Makes Vim aware of Haskell modules and imports allowing you to `gf` with
  the cursor on a module to "go" to its source "file", etc.
* Support for using HLint both as a compiler and a command, integrated into
  the quickfix system in Vim.
* Unicode conceals for various operators and syntax, such as lambda and
  function composition.
* Integrates with third-party plugins, but doesn't require them:
  snippets for UltiSnips and patterns for Tabular.
* Posts buffers and line-ranges to [hpaste.org](http://hpaste.org).
* Highly configurable, most of the above can be disabled if it gets in the
  way.

Installation
------------

You need at least Vim 7.3, and for the HPaste command Python 2, not too
ancient.  Beyond that, just clone this repo and add it to your
`'runtimepath'`.  [Vundle](https://github.com/gmarik/vundle) is great for
automating that, [Pathogen](https://github.com/tpope/vim-pathogen) is also
popular.

See Also
--------

Here are some other Vimscripts that complement vim2hs nicely:

* Omni completion: [neco-ghc](https://github.com/ujihisa/neco-ghc)
* Syntax checking and linting:
  [syntastic](https://github.com/scrooloose/syntastic)
* Type inspection:
  [haskellmode](https://github.com/lukerandall/haskellmode-vim) or (better)
  [ghcmod](https://github.com/eagletmt/ghcmod-vim)
* Shakespeare templates highlighting:
  [html-template-syntax](https://github.com/pbrisbin/html-template-syntax)
* Layout as text objects:
  [textobj-indent](https://github.com/kana/vim-textobj-indent) *(vim2hs
  includes a less powerful version of this that I wrote before I discovered
  this Vimscript; it might be removed in favor of this one in the future)*

Overview
--------

### Top-level Definitions

The syntax highlighting of top-level definitions are improved in vim2hs:

![Bindings screenshot](https://github.com/dag/vim2hs/raw/master/screenshots/bindings.png)

This screenshot showcases a number of nice features:

* Type signatures are highlighted as a whole, even if spanning multiple
  lines.
* In function definitions, the name of the function is highlighted
  differently from its arguments, even if the equal sign is on another line
  (most or all other syntax highlighters get this wrong).
* Top-level definitions such as functions, classes and instances and data
  declarations form folds, as you can see in the `foldcolumn` to the left
  of the line numbers.  Closed folds are given a consistent `foldtext`
  producing a nice overview of the code.  Type signatures are intentionally
  not included in the folds, so as to allow you to read the type of folded
  definitions.

In this screenshot, "wide conceals" are enabled, which is what makes the
type colons and function arrows display as unicode.  This option is
disabled by default, since it can mess up the visual alignment between
lines.  To enable it like I have done here, try this:

```vim
let g:haskell_conceal_wide = 1
```

Other options like this that are safer are enabled by default, and can be
disabled should you so desire:

```vim
" disable all conceals, including the simple ones like
" lambda and composition
let g:haskell_conceal              = 0

" disable concealing of "enumerations": commatized lists like
" deriving clauses and LANGUAGE pragmas,
" otherwise collapsed into a single ellipsis
let g:haskell_conceal_enumerations = 0
```

### Quasi Quoting

Haskell supports embedding arbitrary syntax that is processed at
compile-time.  Vim supports embedding external syntax highlighting.

![Quasi Quotes screenshot](https://github.com/dag/vim2hs/raw/master/screenshots/quasi.png)

These are all enabled by default but you can selectively opt out by adding
the relevant configuration overrides to your `~/.vimrc`:

```vim
let g:haskell_quasi         = 0
let g:haskell_interpolation = 0
let g:haskell_regex         = 0
let g:haskell_jmacro        = 0
let g:haskell_shqq          = 0
let g:haskell_sql           = 0
let g:haskell_json          = 0
let g:haskell_xml           = 0
```

### HSP & Heist

[Haskell Server Pages](http://hackage.haskell.org/package/hsp) and
[Haskell Source with XML](http://hackage.haskell.org/package/hsx)
pre-processes literal XML in Haskell source code into function application
and vim2hs provides limited support for this syntax - I have yet to figure
out how to highlight the body of XML elements differently while still
highlighting the attributes as Haskell.

![HSP screenshot](https://github.com/dag/vim2hs/raw/master/screenshots/hsp.png)

This is enabled by default and can be disabled thusly:

```vim
let g:haskell_hsp = 0
```

[Heist](http://hackage.haskell.org/package/heist) is a simple XML/HTML
templating system; simple enough that you could simply use the `xml` or
`html` filetype in Vim for these templates.  However, it includes a number
of pre-defined "splices" and a special syntax for "splice interpolation" in
attributes.  Included with vim2hs is a syntax file for Heist HTML templates
and automatic filetype detection for `*.tpl` files.

![Heist screenshot](https://github.com/dag/vim2hs/raw/master/screenshots/heist.png)

### Strings

Haskell actually supports multi-line strings by escaping the newline, but I
don't think it's a widely used feature and I think quasi quoting is better
for such purposes.  Thus, by default, I have opted to keep string literals from
crossing lines so half your source file doesn't highlight as a string while
you're entering one. Instead, string literals without a matching end quote
highlight as errors.

![Strings screenshot](https://github.com/dag/vim2hs/raw/master/screenshots/strings.png)

There is a configuration option for this. To enable multi-line strings, use
this:

```vim
:let g:haskell_multiline_strings = 1
```

### HLint

HLint is provided as a compiler for Vim.

```vim
:compiler hlint
:make
```

As a convenience there's also a command that does the above and then resets
the compiler to its previous value.

```vim
:HLint
```

Either way any HLint suggestions and warnings will be put in Vim's quickfix
list and you can jump between them with `:cn` and `:cp`, although I
recommend setting up
[FuzzyFinder](https://github.com/vim-scripts/FuzzyFinder) and using its
`:FufQuickfix` command instead.

### HPaste

To pastebin the contents of the current buffer do this:

```vim
:HPaste
```

The newly created paste URL will be put in the `+` register, meaning your
normal desktop clipboard.

Alternatively, you can select a range of lines with Vim's VISUAL modes and
type the same as above, which should result in this:

```
:'<,'>HPaste
```

Which of course will paste the selected lines only.

If you get tired of entering your author name every time you can configure
it globally like so:

```vim
let g:hpaste_author = 'donri'
```

### UltiSnips

If you're using the excellent
[UltiSnips](https://github.com/sirver/ultisnips) Vimscript, vim2hs provides
some useful snippets for Haskell programming.  You can list all active
snippets by hitting `Ctrl+Tab` in INPUT mode.

### Tabular

Another useful Vimscript is
[Tabular](https://github.com/godlygeek/tabular).  If it's installed, vim2hs
adds some named patterns useful for maintaining layout in Haskell code.
You can list all named patterns by tab-completing after entering the
`:Tabularize` command.  You probably want to configure some mappings or
commands for the ones you find useful.

To disable them, use this configuration:

```vim
let g:haskell_tabular = 0
```


/*
 * Tencent is pleased to support the open source community by making TKEStack
 * available.
 *
 * Copyright (C) 2012-2019 Tencent. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
 * this file except in compliance with the License. You may obtain a copy of the
 * License at
 *
 * https://opensource.org/licenses/Apache-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OF ANY KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations under the License.
 */

// +k8s:deepcopy-gen=package
// +groupName=notify.tkestack.io

// Package notify is the internal version of the API.
package notify // import "tkestack.io/tke/api/notify"


h1, h2 { padding: 3px; }
h1 { background-color: #DB944D;}
h2 { background-color: lightGrey;}
p { margin-left: 1em; }
p.expl { margin-left: 2em; }
code { color: #191970 }

pre {
		background-color: #F0F0F0;
		padding: 3px;
		margin-left: 1em;
}

table {
	border: 2px solid black;
	border-collapse: collapse;
	margin-left: 1em;
}

table td, th {
	border: 1px black solid;
	padding: 5px;
}


function [newIndex] = cycle(index, cycleLength)
%function [newIndex] = cycle(index, cycleLength)
%function to facilitate indexing on cyclical structures.
%The new index if the index cycled around on a structure of length cycleLength.
%e.g.: cycle(11, 10) = 1, cycle(12, 10) = 2, cycle(9, 10) = 9, etc.
%'index' can be a vector.
%JOD, Feb 02.
%
% Copyright 2010, Joseph O. Deasy, on behalf of the CERR development team.
%
% This file is part of The Computational Environment for Radiotherapy Research (CERR).
%
% CERR development has been led by:  Aditya Apte, Divya Khullar, James Alaly, and Joseph O. Deasy.
%
% CERR has been financially supported by the US National Institutes of Health under multiple grants.
%
% CERR is distributed under the terms of the Lesser GNU Public License.
%
%     This version of CERR is free software: you can redistribute it and/or modify
%     it under the terms of the GNU General Public License as published by
%     the Free Software Foundation, either version 3 of the License, or
%     (at your option) any later version.
%
% CERR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
% without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
% See the GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with CERR.  If not, see <http://www.gnu.org/licenses/>.

newIndex = zeros(size(index));

for i = 1 : length(index)
  if index(i) > cycleLength
    newIndex(i) = index(i) - cycleLength;
  elseif index(i) < 1
    newIndex(i) = cycleLength + index(i);
  else
    newIndex(i) = index(i);
  end
end


import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';

import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

import { AuthService } from '../services';

@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
  constructor(private router: Router, private authService: AuthService) {}

  canActivate(): Observable<boolean> {
    return this.authService.getUser().pipe(
      map(user => {
        if (user !== null) {
          return true;
        }

        this.router.navigateByUrl('/auth/login');
        return false;
      })
    );
  }
}


/*
 * Copyright (C) 2012 Igalia S.L.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "WebKitHitTestResult.h"

#include "WebHitTestResultData.h"
#include "WebKitHitTestResultPrivate.h"
#include <glib/gi18n-lib.h>
#include <wtf/text/CString.h>

using namespace WebKit;

/**
 * SECTION: WebKitHitTestResult
 * @Short_description: Result of a Hit Test
 * @Title: WebKitHitTestResult
 * @See_also: #WebKitWebView
 *
 * A Hit Test is an operation to get context information about a given
 * point in a #WebKitWebView. #WebKitHitTestResult represents the
 * result of a Hit Test. It provides context information about what is
 * at the coordinates of the Hit Test, such as if there's a link,
 * an image or a media.
 *
 * You can get the context of the HitTestResult with
 * webkit_hit_test_result_get_context() that returns a bitmask of
 * #WebKitHitTestResultContext flags. You can also use
 * webkit_hit_test_result_context_is_link(), webkit_hit_test_result_context_is_image() and
 * webkit_hit_test_result_context_is_media() to determine whether there's
 * a link, image or a media element at the coordinates of the Hit Test.
 * Note that it's possible that several #WebKitHitTestResultContext flags
 * are active at the same time, for example if there's a link containing an image.
 *
 * When the mouse is moved over a #WebKitWebView a Hit Test is performed
 * for the mouse coordinates and #WebKitWebView::mouse-target-changed
 * signal is emitted with a #WebKitHitTestResult.
 *
 */

enum {
    PROP_0,

    PROP_CONTEXT,
    PROP_LINK_URI,
    PROP_LINK_TITLE,
    PROP_LINK_LABEL,
    PROP_IMAGE_URI,
    PROP_MEDIA_URI
};

struct _WebKitHitTestResultPrivate {
    unsigned int context;
    CString linkURI;
    CString linkTitle;
    CString linkLabel;
    CString imageURI;
    CString mediaURI;
};

WEBKIT_DEFINE_TYPE(WebKitHitTestResult, webkit_hit_test_result, G_TYPE_OBJECT)

static void webkitHitTestResultGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
{
    WebKitHitTestResult* hitTestResult = WEBKIT_HIT_TEST_RESULT(object);

    switch (propId) {
    case PROP_CONTEXT:
        g_value_set_uint(value, webkit_hit_test_result_get_context(hitTestResult));
        break;
    case PROP_LINK_URI:
        g_value_set_string(value, webkit_hit_test_result_get_link_uri(hitTestResult));
        break;
    case PROP_LINK_TITLE:
        g_value_set_string(value, webkit_hit_test_result_get_link_title(hitTestResult));
        break;
    case PROP_LINK_LABEL:
        g_value_set_string(value, webkit_hit_test_result_get_link_label(hitTestResult));
        break;
    case PROP_IMAGE_URI:
        g_value_set_string(value, webkit_hit_test_result_get_image_uri(hitTestResult));
        break;
    case PROP_MEDIA_URI:
        g_value_set_string(value, webkit_hit_test_result_get_media_uri(hitTestResult));
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
    }
}

static void webkitHitTestResultSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
{
    WebKitHitTestResult* hitTestResult = WEBKIT_HIT_TEST_RESULT(object);

    switch (propId) {
    case PROP_CONTEXT:
        hitTestResult->priv->context = g_value_get_uint(value);
        break;
    case PROP_LINK_URI:
        hitTestResult->priv->linkURI = g_value_get_string(value);
        break;
    case PROP_LINK_TITLE:
        hitTestResult->priv->linkTitle = g_value_get_string(value);
        break;
    case PROP_LINK_LABEL:
        hitTestResult->priv->linkLabel = g_value_get_string(value);
        break;
    case PROP_IMAGE_URI:
        hitTestResult->priv->imageURI = g_value_get_string(value);
        break;
    case PROP_MEDIA_URI:
        hitTestResult->priv->mediaURI = g_value_get_string(value);
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
    }
}

static void webkit_hit_test_result_class_init(WebKitHitTestResultClass* hitTestResultClass)
{
    GObjectClass* objectClass = G_OBJECT_CLASS(hitTestResultClass);
    objectClass->get_property = webkitHitTestResultGetProperty;
    objectClass->set_property = webkitHitTestResultSetProperty;

    GParamFlags paramFlags = static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);

    /**
     * WebKitHitTestResult:context:
     *
     * Bitmask of #WebKitHitTestResultContext flags representing
     * the context of the #WebKitHitTestResult.
     */
    g_object_class_install_property(objectClass,
                                    PROP_CONTEXT,
                                    g_param_spec_uint("context",
                                                      _("Context"),
                                                      _("Flags with the context of the WebKitHitTestResult"),
                                                      0, G_MAXUINT, 0,
                                                      paramFlags));

    /**
     * WebKitHitTestResult:link-uri:
     *
     * The URI of the link if flag %WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK
     * is present in #WebKitHitTestResult:context
     */
    g_object_class_install_property(objectClass,
                                    PROP_LINK_URI,
                                    g_param_spec_string("link-uri",
                                                        _("Link URI"),
                                                        _("The link URI"),
                                                        0,
                                                        paramFlags));
    /**
     * WebKitHitTestResult:link-title:
     *
     * The title of the link if flag %WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK
     * is present in #WebKitHitTestResult:context
     */
    g_object_class_install_property(objectClass,
                                    PROP_LINK_TITLE,
                                    g_param_spec_string("link-title",
                                                        _("Link Title"),
                                                        _("The link title"),
                                                        0,
                                                        paramFlags));
    /**
     * WebKitHitTestResult:link-label:
     *
     * The label of the link if flag %WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK
     * is present in #WebKitHitTestResult:context
     */
    g_object_class_install_property(objectClass,
                                    PROP_LINK_LABEL,
                                    g_param_spec_string("link-label",
                                                        _("Link Label"),
                                                        _("The link label"),
                                                        0,
                                                        paramFlags));
    /**
     * WebKitHitTestResult:image-uri:
     *
     * The URI of the image if flag %WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE
     * is present in #WebKitHitTestResult:context
     */
    g_object_class_install_property(objectClass,
                                    PROP_IMAGE_URI,
                                    g_param_spec_string("image-uri",
                                                        _("Image URI"),
                                                        _("The image URI"),
                                                        0,
                                                        paramFlags));
    /**
     * WebKitHitTestResult:media-uri:
     *
     * The URI of the media if flag %WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA
     * is present in #WebKitHitTestResult:context
     */
    g_object_class_install_property(objectClass,
                                    PROP_MEDIA_URI,
                                    g_param_spec_string("media-uri",
                                                        _("Media URI"),
                                                        _("The media URI"),
                                                        0,
                                                        paramFlags));
}

WebKitHitTestResult* webkitHitTestResultCreate(const WebHitTestResultData& hitTestResult)
{
    unsigned context = WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT;

    if (!hitTestResult.absoluteLinkURL.isEmpty())
        context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK;

    if (!hitTestResult.absoluteImageURL.isEmpty())
        context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE;

    if (!hitTestResult.absoluteMediaURL.isEmpty())
        context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA;

    if (hitTestResult.isContentEditable)
        context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE;

    if (hitTestResult.isScrollbar)
        context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR;

    if (hitTestResult.isSelected)
        context |= WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION;

    return WEBKIT_HIT_TEST_RESULT(g_object_new(WEBKIT_TYPE_HIT_TEST_RESULT,
        "context", context,
        "link-uri", context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK ? hitTestResult.absoluteLinkURL.utf8().data() : nullptr,
        "image-uri", context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE ? hitTestResult.absoluteImageURL.utf8().data() : nullptr,
        "media-uri", context & WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA ? hitTestResult.absoluteMediaURL.utf8().data() : nullptr,
        "link-title", !hitTestResult.linkTitle.isEmpty() ? hitTestResult.linkTitle.utf8().data() : nullptr,
        "link-label", !hitTestResult.linkLabel.isEmpty() ? hitTestResult.linkLabel.utf8().data() : nullptr,
        nullptr));
}

static bool stringIsEqualToCString(const String& string, const CString& cString)
{
    return ((string.isEmpty() && cString.isNull()) || (string.utf8() == cString));
}

bool webkitHitTestResultCompare(WebKitHitTestResult* hitTestResult, const WebHitTestResultData& webHitTestResult)
{
    WebKitHitTestResultPrivate* priv = hitTestResult->priv;
    return webHitTestResult.isContentEditable == webkit_hit_test_result_context_is_editable(hitTestResult)
        && webHitTestResult.isScrollbar == webkit_hit_test_result_context_is_scrollbar(hitTestResult)
        && webHitTestResult.isSelected == webkit_hit_test_result_context_is_selection(hitTestResult)
        && stringIsEqualToCString(webHitTestResult.absoluteLinkURL, priv->linkURI)
        && stringIsEqualToCString(webHitTestResult.linkTitle, priv->linkTitle)
        && stringIsEqualToCString(webHitTestResult.linkLabel, priv->linkLabel)
        && stringIsEqualToCString(webHitTestResult.absoluteImageURL, priv->imageURI)
        && stringIsEqualToCString(webHitTestResult.absoluteMediaURL, priv->mediaURI);
}

/**
 * webkit_hit_test_result_get_context:
 * @hit_test_result: a #WebKitHitTestResult
 *
 * Gets the value of the #WebKitHitTestResult:context property.
 *
 * Returns: a bitmask of #WebKitHitTestResultContext flags
 */
guint webkit_hit_test_result_get_context(WebKitHitTestResult* hitTestResult)
{
    g_return_val_if_fail(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult), 0);

    return hitTestResult->priv->context;
}

/**
 * webkit_hit_test_result_context_is_link:
 * @hit_test_result: a #WebKitHitTestResult
 *
 * Gets whether %WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK flag is present in
 * #WebKitHitTestResult:context.
 *
 * Returns: %TRUE if there's a link element in the coordinates of the Hit Test,
 *    or %FALSE otherwise
 */
gboolean webkit_hit_test_result_context_is_link(WebKitHitTestResult* hitTestResult)
{
    g_return_val_if_fail(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult), FALSE);

    return hitTestResult->priv->context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK;
}

/**
 * webkit_hit_test_result_context_is_image:
 * @hit_test_result: a #WebKitHitTestResult
 *
 * Gets whether %WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE flag is present in
 * #WebKitHitTestResult:context.
 *
 * Returns: %TRUE if there's an image element in the coordinates of the Hit Test,
 *    or %FALSE otherwise
 */
gboolean webkit_hit_test_result_context_is_image(WebKitHitTestResult* hitTestResult)
{
    g_return_val_if_fail(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult), FALSE);

    return hitTestResult->priv->context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE;
}

/**
 * webkit_hit_test_result_context_is_media:
 * @hit_test_result: a #WebKitHitTestResult
 *
 * Gets whether %WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA flag is present in
 * #WebKitHitTestResult:context.
 *
 * Returns: %TRUE if there's a media element in the coordinates of the Hit Test,
 *    or %FALSE otherwise
 */
gboolean webkit_hit_test_result_context_is_media(WebKitHitTestResult* hitTestResult)
{
    g_return_val_if_fail(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult), FALSE);

    return hitTestResult->priv->context & WEBKIT_HIT_TEST_RESULT_CONTEXT_MEDIA;
}

/**
 * webkit_hit_test_result_context_is_editable:
 * @hit_test_result: a #WebKitHitTestResult
 *
 * Gets whether %WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE flag is present in
 * #WebKitHitTestResult:context.
 *
 * Returns: %TRUE if there's an editable element at the coordinates of the @hit_test_result,
 *    or %FALSE otherwise
 */
gboolean webkit_hit_test_result_context_is_editable(WebKitHitTestResult* hitTestResult)
{
    g_return_val_if_fail(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult), FALSE);

    return hitTestResult->priv->context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE;
}

/**
 * webkit_hit_test_result_context_is_selection:
 * @hit_test_result: a #WebKitHitTestResult
 *
 * Gets whether %WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION flag is present in
 * #WebKitHitTestResult:context.
 *
 * Returns: %TRUE if there's a selected element at the coordinates of the @hit_test_result,
 *    or %FALSE otherwise
 *
 * Since: 2.8
 */
gboolean webkit_hit_test_result_context_is_selection(WebKitHitTestResult* hitTestResult)
{
    g_return_val_if_fail(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult), FALSE);

    return hitTestResult->priv->context & WEBKIT_HIT_TEST_RESULT_CONTEXT_SELECTION;
}

/**
 * webkit_hit_test_result_get_link_uri:
 * @hit_test_result: a #WebKitHitTestResult
 *
 * Gets the value of the #WebKitHitTestResult:link-uri property.
 *
 * Returns: the URI of the link element in the coordinates of the Hit Test,
 *    or %NULL if there ins't a link element in @hit_test_result context
 */
const gchar* webkit_hit_test_result_get_link_uri(WebKitHitTestResult* hitTestResult)
{
    g_return_val_if_fail(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult), 0);

    return hitTestResult->priv->linkURI.data();
}

/**
 * webkit_hit_test_result_get_link_title:
 * @hit_test_result: a #WebKitHitTestResult
 *
 * Gets the value of the #WebKitHitTestResult:link-title property.
 *
 * Returns: the title of the link element in the coordinates of the Hit Test,
 *    or %NULL if there ins't a link element in @hit_test_result context or the
 *    link element doesn't have a title
 */
const gchar* webkit_hit_test_result_get_link_title(WebKitHitTestResult* hitTestResult)
{
    g_return_val_if_fail(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult), 0);

    return hitTestResult->priv->linkTitle.data();
}

/**
 * webkit_hit_test_result_get_link_label:
 * @hit_test_result: a #WebKitHitTestResult
 *
 * Gets the value of the #WebKitHitTestResult:link-label property.
 *
 * Returns: the label of the link element in the coordinates of the Hit Test,
 *    or %NULL if there ins't a link element in @hit_test_result context or the
 *    link element doesn't have a label
 */
const gchar* webkit_hit_test_result_get_link_label(WebKitHitTestResult* hitTestResult)
{
    g_return_val_if_fail(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult), 0);

    return hitTestResult->priv->linkLabel.data();
}

/**
 * webkit_hit_test_result_get_image_uri:
 * @hit_test_result: a #WebKitHitTestResult
 *
 * Gets the value of the #WebKitHitTestResult:image-uri property.
 *
 * Returns: the URI of the image element in the coordinates of the Hit Test,
 *    or %NULL if there ins't an image element in @hit_test_result context
 */
const gchar* webkit_hit_test_result_get_image_uri(WebKitHitTestResult* hitTestResult)
{
    g_return_val_if_fail(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult), 0);

    return hitTestResult->priv->imageURI.data();
}

/**
 * webkit_hit_test_result_get_media_uri:
 * @hit_test_result: a #WebKitHitTestResult
 *
 * Gets the value of the #WebKitHitTestResult:media-uri property.
 *
 * Returns: the URI of the media element in the coordinates of the Hit Test,
 *    or %NULL if there ins't a media element in @hit_test_result context
 */
const gchar* webkit_hit_test_result_get_media_uri(WebKitHitTestResult* hitTestResult)
{
    g_return_val_if_fail(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult), 0);

    return hitTestResult->priv->mediaURI.data();
}

/**
 * webkit_hit_test_result_context_is_scrollbar:
 * @hit_test_result: a #WebKitHitTestResult
 *
 * Gets whether %WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR flag is present in
 * #WebKitHitTestResult:context.
 *
 * Returns: %TRUE if there's a scrollbar element at the coordinates of the @hit_test_result,
 *    or %FALSE otherwise
 */
gboolean webkit_hit_test_result_context_is_scrollbar(WebKitHitTestResult* hitTestResult)
{
    g_return_val_if_fail(WEBKIT_IS_HIT_TEST_RESULT(hitTestResult), FALSE);

    return hitTestResult->priv->context & WEBKIT_HIT_TEST_RESULT_CONTEXT_SCROLLBAR;
}


package nlreturn

import (
	"fmt"
	"go/ast"
	"go/token"

	"golang.org/x/tools/go/analysis"
)

const (
	linterName = "nlreturn"
	linterDoc  = `Linter requires a new line before return and branch statements except when the return is alone inside a statement group (such as an if statement) to increase code clarity.`
)

// NewAnalyzer returns a new nlreturn analyzer.
func NewAnalyzer() *analysis.Analyzer {
	return &analysis.Analyzer{
		Name: linterName,
		Doc:  linterDoc,
		Run:  run,
	}
}

func run(pass *analysis.Pass) (interface{}, error) {
	for _, f := range pass.Files {
		ast.Inspect(f, func(node ast.Node) bool {
			switch c := node.(type) {
			case *ast.CaseClause:
				inspectBlock(pass, c.Body)
			case *ast.CommClause:
				inspectBlock(pass, c.Body)
			case *ast.BlockStmt:
				inspectBlock(pass, c.List)
			}

			return true
		})
	}

	return nil, nil
}

func inspectBlock(pass *analysis.Pass, block []ast.Stmt) {
	for i, stmt := range block {
		switch stmt.(type) {
		case *ast.BranchStmt, *ast.ReturnStmt:
			if i == 0 {
				return
			}

			if line(pass, stmt.Pos())-line(pass, block[i-1].End()) <= 1 {
				pass.Report(analysis.Diagnostic{
					Pos:     stmt.Pos(),
					Message: fmt.Sprintf("%s with no blank line before", name(stmt)),
					SuggestedFixes: []analysis.SuggestedFix{
						{
							TextEdits: []analysis.TextEdit{
								{
									Pos:     stmt.Pos(),
									NewText: []byte("\n"),
									End:     stmt.Pos(),
								},
							},
						},
					},
				})
			}
		}
	}
}

func name(stmt ast.Stmt) string {
	switch c := stmt.(type) {
	case *ast.BranchStmt:
		return c.Tok.String()
	case *ast.ReturnStmt:
		return "return"
	default:
		return "unknown"
	}
}

func line(pass *analysis.Pass, pos token.Pos) int {
	return pass.Fset.Position(pos).Line
}


/* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
 *
 * You can redistribute this program and/or modify it under the terms of
 * the GNU Lesser Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 */
using System;
using System.Collections.Generic;
using System.Text;
using SMBLibrary.SMB1;
using Utilities;

namespace SMBLibrary.Server.SMB1
{
    internal partial class SMB1FileStoreHelper
    {
        public static NTStatus GetFileSystemInformation(out QueryFSInformation result, INTFileStore fileStore, QueryFSInformationLevel informationLevel)
        {
            result = null;
            FileSystemInformationClass informationClass;
            try
            {
                informationClass = QueryFSInformationHelper.ToFileSystemInformationClass(informationLevel);
            }
            catch (UnsupportedInformationLevelException)
            {
                return NTStatus.STATUS_OS2_INVALID_LEVEL;
            }

            FileSystemInformation fsInfo;
            NTStatus status = fileStore.GetFileSystemInformation(out fsInfo, informationClass);
            if (status != NTStatus.STATUS_SUCCESS)
            {
                return status;
            }

            result = QueryFSInformationHelper.FromFileSystemInformation(fsInfo);
            return NTStatus.STATUS_SUCCESS;
        }
    }
}


/*
 *  /MathJax/jax/input/MathML/entities/scr.js
 *
 *  Copyright (c) 2012 Design Science, Inc.
 *
 *  Part of the MathJax library.
 *  See http://www.mathjax.org for details.
 *
 *  Licensed under the Apache License, Version 2.0;
 *  you may not use this file except in compliance with the License.
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 */

(function(a){MathJax.Hub.Insert(a.Parse.Entity,{Ascr:"\uD835\uDC9C",Bscr:"\u212C",Cscr:"\uD835\uDC9E",Dscr:"\uD835\uDC9F",Escr:"\u2130",Fscr:"\u2131",Gscr:"\uD835\uDCA2",Hscr:"\u210B",Iscr:"\u2110",Jscr:"\uD835\uDCA5",Kscr:"\uD835\uDCA6",Lscr:"\u2112",Mscr:"\u2133",Nscr:"\uD835\uDCA9",Oscr:"\uD835\uDCAA",Pscr:"\uD835\uDCAB",Qscr:"\uD835\uDCAC",Rscr:"\u211B",Sscr:"\uD835\uDCAE",Tscr:"\uD835\uDCAF",Uscr:"\uD835\uDCB0",Vscr:"\uD835\uDCB1",Wscr:"\uD835\uDCB2",Xscr:"\uD835\uDCB3",Yscr:"\uD835\uDCB4",Zscr:"\uD835\uDCB5",ascr:"\uD835\uDCB6",bscr:"\uD835\uDCB7",cscr:"\uD835\uDCB8",dscr:"\uD835\uDCB9",escr:"\u212F",fscr:"\uD835\uDCBB",gscr:"\u210A",hscr:"\uD835\uDCBD",iscr:"\uD835\uDCBE",jscr:"\uD835\uDCBF",kscr:"\uD835\uDCC0",lscr:"\uD835\uDCC1",mscr:"\uD835\uDCC2",nscr:"\uD835\uDCC3",oscr:"\u2134",pscr:"\uD835\uDCC5",qscr:"\uD835\uDCC6",rscr:"\uD835\uDCC7",sscr:"\uD835\uDCC8",tscr:"\uD835\uDCC9",uscr:"\uD835\uDCCA",vscr:"\uD835\uDCCB",wscr:"\uD835\uDCCC",xscr:"\uD835\uDCCD",yscr:"\uD835\uDCCE",zscr:"\uD835\uDCCF"});MathJax.Ajax.loadComplete(a.entityDir+"/scr.js")})(MathJax.InputJax.MathML);


.c-record-list {
  .c-record:not(:last-child) {
    border-bottom: 1px solid $hr-border-color;
    margin-bottom: 1rem;
    padding-bottom: 1rem;
  }
}