text:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Threading.Tasks;
using Toggl.Phoebe.Data.DataObjects;
using Toggl.Phoebe.Data.Models;
using Toggl.Phoebe.Data.Utils;
using Toggl.Phoebe.Net;
using XPlatUtils;

namespace Toggl.Phoebe.Data.Views
{
    public class WorkspaceProjectsView : ICollectionDataView<object>, IDisposable
    {
        private readonly List<Workspace> workspacesList = new List<Workspace> ();
        private readonly List<ClientData> clientDataObjects = new List<ClientData> ();
        private readonly List<object> dataObjects = new List<object> ();
        private UserData userData;
        private Subscription<DataChangeMessage> subscriptionDataChange;
        private SortProjectsBy sortBy = SortProjectsBy.Clients;
        private Workspace filteredList;
        private string filter;
        private bool hasFilter;
        private bool isLoading;
        private bool hasMore;
        private int currentWorkspaceIndex;
        private int unfoldedProjectIndex;
        private Project unfoldedTaskProject;

        public WorkspaceProjectsView ()
        {
            userData = ServiceContainer.Resolve<AuthManager> ().User;
            var bus = ServiceContainer.Resolve<MessageBus> ();
            subscriptionDataChange = bus.Subscribe<DataChangeMessage> (OnDataChange);
        }

        public Project UnfoldedTaskProject
        {
            get {
                return unfoldedTaskProject;
            }
        }

        public SortProjectsBy SortBy
        {
            get {
                return sortBy;
            } set {
                sortBy = value;
                UpdateCollection ();
            }
        }

        public bool IsEmpty
        {
            get {
                return workspacesList [currentWorkspaceIndex].HasNoProjects;
            }
        }

        public void ShowTaskForProject (Project project, int position, out int collapsedTaskNumber)
        {
            collapsedTaskNumber = unfoldedTaskProject == null ? 0 : unfoldedTaskProject.Tasks.Count;

            if (unfoldedTaskProject == project) {
                collapsedTaskNumber = 0;
                unfoldedTaskProject = null;
            } else {
                unfoldedTaskProject = project;
            }

            if (unfoldedProjectIndex > position) {
                collapsedTaskNumber = 0;
            }

            unfoldedProjectIndex = position;
            UpdateCollection ();
        }

        public void Dispose ()
        {
            if (subscriptionDataChange != null) {
                var bus = ServiceContainer.Resolve<MessageBus> ();
                bus.Unsubscribe (subscriptionDataChange);
                subscriptionDataChange = null;
            }
        }

        private void OnDataChange (DataChangeMessage msg)
        {
            if (msg.Data is UserData) {
                OnDataChange ((UserData)msg.Data);
            } else if (msg.Data is WorkspaceData) {
                OnDataChange ((WorkspaceData)msg.Data, msg.Action);
            } else if (msg.Data is ProjectData) {
                OnDataChange ((ProjectData)msg.Data, msg.Action);
            } else if (msg.Data is TaskData) {
                OnDataChange ((TaskData)msg.Data, msg.Action);
            } else if (msg.Data is ClientData) {
                OnDataChange ((ClientData)msg.Data, msg.Action);
            }
        }

        private void OnDataChange (UserData data)
        {
            var existingData = userData;
            userData = data;
            if (existingData == null || existingData.DefaultWorkspaceId != data.DefaultWorkspaceId) {
                OnUpdated ();
            }
            userData = data;
        }

        private void OnDataChange (WorkspaceData data, DataAction action)
        {
            var isExcluded = action == DataAction.Delete
                             || data.DeletedAt.HasValue;

            Workspace workspace;

            if (isExcluded) {
                if (FindWorkspace (data.Id, out workspace)) {
                    workspacesList.Remove (workspace);
                    OnUpdated ();
                }
            } else {
                data = new WorkspaceData (data);

                if (FindWorkspace (data.Id, out workspace)) {
                    var existingData = workspace.Data;

                    workspace.Data = data;
                    if (existingData.Name != data.Name) {
                        SortWorkspaces (workspacesList);
                    }
                    OnUpdated ();
                } else {
                    workspace = new Workspace (data);
                    workspacesList.Add (workspace);
                    SortWorkspaces (workspacesList);
                    OnUpdated ();
                }
            }
        }

        private void OnDataChange (ProjectData data, DataAction action)
        {
            var isExcluded = action == DataAction.Delete
                             || data.DeletedAt.HasValue
                             || !data.IsActive;

            Workspace workspace;
            Project project;

            if (isExcluded) {
                if (FindProject (data.Id, out workspace, out project)) {
                    workspace.Projects.Remove (project);
                    UpdateCollection ();
                }
            } else {
                data = new ProjectData (data);

                if (FindProject (data.Id, out workspace, out project)) {
                    var existingData = project.Data;

                    var shouldReparent = existingData.WorkspaceId != data.WorkspaceId;
                    var shouldSort = existingData.Name != data.Name
                                     || existingData.ClientId != data.ClientId
                                     || shouldReparent;

                    project.Data = data;

                    if (shouldReparent) {
                        workspace.Projects.Remove (project);
                        if (FindWorkspace (data.WorkspaceId, out workspace)) {
                            workspace.Projects.Add (project);
                        }
                    }

                    if (shouldSort && workspace != null) {
                        SortProjects (workspace.Projects, clientDataObjects);
                    }
                    UpdateCollection ();
                } else if (FindWorkspace (data.WorkspaceId, out workspace)) {
                    project = new Project (data);

                    if (project.Data.ClientId == null) {
                        workspace.Clients.First ().Projects.Add (project);
                    } else {
                        workspace.Clients
                        .Where (r => r.Data != null)
                        .Where (r => r.Data.Id == project.Data.ClientId)
                        .First ().Projects.Add (project);
                    }
                    SortEverything ();
                    UpdateCollection();
                }
            }
        }

        private void OnDataChange (TaskData data, DataAction action)
        {
            var isExcluded = action == DataAction.Delete
                             || data.DeletedAt.HasValue
                             || !data.IsActive;

            Workspace workspace;
            Project project;
            TaskData existingData;

            if (isExcluded) {
                if (FindTask (data.Id, out workspace, out project, out existingData)) {
                    project.Tasks.Remove (existingData);
                    UpdateCollection ();
                }
            } else {
                data = new TaskData (data);

                if (FindTask (data.Id, out workspace, out project, out existingData)) {
                    var shouldReparent = existingData.ProjectId != data.ProjectId;
                    var shouldSort = existingData.Name != data.Name
                                     || shouldReparent;

                    if (shouldReparent) {
                        project.Tasks.Remove (existingData);

                        if (FindProject (data.ProjectId, out workspace, out project)) {
                            project.Tasks.Add (data);
                        }
                    } else {
                        project.Tasks.UpdateData (data);
                    }

                    if (shouldSort) {
                        SortTasks (project.Tasks);
                    }

                    UpdateCollection ();
                } else if (FindProject (data.ProjectId, out workspace, out project)) {
                    project.Tasks.Add (data);
                    SortTasks (project.Tasks);
                    UpdateCollection ();
                }
            }
        }

        private void OnDataChange (ClientData data, DataAction action)
        {
            var isExcluded = action == DataAction.Delete
                             || data.DeletedAt.HasValue;

            var existingData = clientDataObjects.FirstOrDefault (item => data.Matches (item));

            if (isExcluded) {
                if (existingData != null) {
                    clientDataObjects.Remove (existingData);
                    workspacesList[currentWorkspaceIndex].Clients.Remove (new Client (existingData));
                }
            } else {
                data = new ClientData (data);

                if (existingData != null) {
                    clientDataObjects.UpdateData (data);

                    var shouldSort = data.Name != existingData.Name;
                    if (shouldSort) {
                        Workspace workspace;
                        if (FindWorkspace (data.WorkspaceId, out workspace)) {
                            SortProjects (workspace.Projects, clientDataObjects);
                        }
                    }
                } else {
                    clientDataObjects.Add (data);
                    workspacesList[currentWorkspaceIndex].Clients.Add (new Client (data));

                }
            }
        }

        private bool FindWorkspace (Guid id, out Workspace workspace)
        {
            foreach (var ws in workspacesList) {
                if (ws.Data.Id == id) {
                    workspace = ws;
                    return true;
                }
            }

            workspace = null;
            return false;
        }

        private bool FindProject (Guid id, out Workspace workspace, out Project project)
        {
            foreach (var ws in workspacesList) {
                foreach (var proj in ws.Projects) {
                    if (proj.Data != null && proj.Data.Id == id) {
                        workspace = ws;
                        project = proj;
                        return true;
                    }
                }
            }

            workspace = null;
            project = null;
            return false;
        }

        private bool FindTask (Guid id, out Workspace workspace, out Project project, out TaskData existingData)
        {
            foreach (var ws in workspacesList) {
                foreach (var proj in ws.Projects) {
                    foreach (var task in proj.Tasks) {
                        if (task.Id == id) {
                            workspace = ws;
                            project = proj;
                            existingData = task;
                            return true;
                        }
                    }
                }
            }

            workspace = null;
            project = null;
            existingData = null;
            return false;
        }

        private void OnUpdated ()
        {
            DispatchCollectionEvent (CollectionEventBuilder.GetEvent (NotifyCollectionChangedAction.Reset, -1, -1));
        }

        public event NotifyCollectionChangedEventHandler CollectionChanged;

        private void DispatchCollectionEvent (NotifyCollectionChangedEventArgs args)
        {
            var handler = CollectionChanged;
            if (handler != null) {
                handler (this, args);
            }
        }

        public async Task ReloadAsync ()
        {
            if (IsLoading) {
                return;
            }

            var bus = ServiceContainer.Resolve<MessageBus> ();
            var shouldSubscribe = subscriptionDataChange != null;

            if (subscriptionDataChange != null) {
                bus.Unsubscribe (subscriptionDataChange);
                subscriptionDataChange = null;
                shouldSubscribe = true;
            }

            try {
                var store = ServiceContainer.Resolve<IDataStore> ();
                var userId = userData != null ? userData.Id : (Guid?)null;

                IsLoading = true;
                clientDataObjects.Clear ();

                var workspaceTask = store.Table<WorkspaceData> ()
                                    .QueryAsync (r => r.DeletedAt == null);
                var projectsTask = store.GetUserAccessibleProjects (userId ?? Guid.Empty);
                var mostUsedProjectsTask = store.GetMostUsedProjects (userId ?? Guid.Empty);

                var tasksTask = store.Table<TaskData> ()
                                .QueryAsync (r => r.DeletedAt == null && r.IsActive == true);
                var clientsTask = store.Table<ClientData> ()
                                  .QueryAsync (r => r.DeletedAt == null);

                await Task.WhenAll (mostUsedProjectsTask, workspaceTask, projectsTask, tasksTask, clientsTask);

                var wsList = workspaceTask.Result;
                workspacesList.Clear();
                foreach (var ws in wsList) {
                    var workspace = new Workspace (ws);
                    var projects = projectsTask.Result.Where (r => r.WorkspaceId == ws.Id);
                    var clients = new List<ClientData> ();

                    clients.Add (new ClientData());
                    clients.AddRange (clientsTask.Result.Where (r => r.WorkspaceId == ws.Id));
                    FillClientsBranchForWorkspace (workspace, clients, projects, tasksTask);
                    FillProjectsBranchForWorkspace (workspace, projects, tasksTask);

                    var mostUsed = mostUsedProjectsTask.Result.Where (r => r.WorkspaceId == workspace.Data.Id).Take (5).ToList();
                    if (mostUsed.Any ()) {
                        var mostUsedClient = new Client (workspace.Data);
                        mostUsedClient.IsMostUsed = true;
                        foreach (var p in mostUsed) {
                            var pr = new Project (p);
                            pr.Tasks.AddRange (tasksTask.Result.Where (t => t.ProjectId == p.Id).ToList());
                            mostUsedClient.Projects.Add (pr);
                        }
                        workspace.Clients.Add (mostUsedClient);
                    }

                    workspacesList.Add (workspace);
                }

                clientDataObjects.AddRange (clientsTask.Result);
                SortEverything();

            } finally {
                UpdateCollection ();
                IsLoading = false;

                if (shouldSubscribe) {
                    subscriptionDataChange = bus.Subscribe<DataChangeMessage> (OnDataChange);
                }
            }
        }

        private void FillClientsBranchForWorkspace (Workspace workspace, List<ClientData> clients, IEnumerable<ProjectData> projects, Task<List<TaskData>> tasksTask)
        {
            foreach (var clientData in clients) {
                Client client;
                IEnumerable<ProjectData> projectsOfClient;

                if (workspace.Clients.Count == 0) { // first element
                    client = new Client (workspace.Data);
                    client.IsNoClient = true;
                    client.Projects.Add (new Project (workspace.Data));
                    projectsOfClient = projects.Where (r => r.ClientId == null);
                } else {
                    client = new Client (clientData);
                    projectsOfClient = projects.Where (r => r.ClientId == clientData.Id);
                }

                foreach (var projectData in projectsOfClient) {
                    var project = new Project (projectData);

                    var tasks = tasksTask.Result.Where (r => r.ProjectId == projectData.Id);
                    project.Tasks.AddRange (tasks);

                    client.Projects.Add (project);
                }
                workspace.Clients.Add (client);
            }
        }

        private void FillProjectsBranchForWorkspace (Workspace workspace, IEnumerable<ProjectData> projects, Task<List<TaskData>> tasksTask)
        {
            foreach (var projectData in projects) {
                var project = new Project (projectData);

                var tasks = tasksTask.Result.Where (r => r.ProjectId == projectData.Id);
                project.Tasks.AddRange (tasks);

                workspace.Projects.Add (project);
            }
        }

        private void SortEverything()
        {
            SortWorkspaces (workspacesList);
            foreach (var ws in workspacesList) {

                SortProjects (ws.Projects, clientDataObjects);
                SortClients (ws.Clients);
                foreach (var client in ws.Clients) {
                    SortProjects (client.Projects, new List<ClientData> ());
                    foreach (var project in client.Projects) {
                        SortTasks (project.Tasks);
                    }
                }
            }
        }

        public bool ApplyNameFilter (string filterString)
        {
            hasFilter = filterString.Length > 0;

            //If no string, don't filter.
            if (!hasFilter) {
                UpdateCollection();
                return true;
            }

            Workspace source;

            // If old filter is contained in the new filter, search an already filtered list.
            var searchFromPrevious = filter != null && filteredList != null && workspacesList[currentWorkspaceIndex].Data.Id == filteredList.Data.Id && filterString.ToLower().Contains (filter);
            source = searchFromPrevious ? filteredList : workspacesList [currentWorkspaceIndex];

            filteredList = new Workspace (workspacesList[currentWorkspaceIndex].Data);
            filter = filterString.ToLower();

            switch (sortBy) {
            case SortProjectsBy.Clients:

                foreach (var client in source.Clients) {
                    Client cl;

                    if (client.Data == null) {
                        cl = new Client (workspacesList [currentWorkspaceIndex].Data);
                        if (cl.IsMostUsed) {
                            cl.IsMostUsed = client.IsMostUsed;
                        } else if (cl.IsNoClient) {
                            cl.IsNoClient = client.IsNoClient;
                        }
                    } else {
                        cl = new Client (client.Data);
                    }
                    if (client.Data != null && client.Data.Name.ToLower().Contains (filter)) {
                        cl.Projects.AddRange (client.Projects);
                    } else {
                        foreach (var project in client.Projects) {
                            if (project.Data != null && project.Data.Name != null && project.Data.Name.ToLower().Contains (filter)) {
                                cl.Projects.Add (project);
                            } else { // Maybe in the tasks
                                foreach (var task in project.Tasks) {
                                    if (task.Name != null && task.Name.ToLower().Contains (filter)) {
                                        cl.Projects.Add (project);
                                    }
                                }
                            }
                        }
                    }
                    if (cl.Projects.Count > 0) {
                        filteredList.Clients.Add (cl);
                    }
                }
                break;

            case SortProjectsBy.Projects:

                foreach (var project in source.Projects) {
                    if (project.Data == null) {
                        continue;
                    }
                    var projectModel = new ProjectModel (project.Data);
                    if (projectModel.Name.ToLower().Contains (filter)) {
                        filteredList.Projects.Add (project);
                        continue;
                    }

                    if (projectModel.Client != null && projectModel.Client.Name.ToLower().Contains (filter)) {
                        filteredList.Projects.Add (project);
                        continue;
                    }

                    foreach (var task in project.Tasks) {
                        if (task.Name.ToLower().Contains (filter)) {
                            filteredList.Projects.Add (project);
                            break;
                        }
                    }
                }
                break;
            }
            UpdateCollection();
            return filteredList.Clients.Count != 0 || filteredList.Projects.Count != 1;

        }

        private static void SortWorkspaces (List<Workspace> data)
        {
            var user = ServiceContainer.Resolve<AuthManager> ().User;
            data.Sort ((a, b) => {
                if (user != null) {
                    if (a.Data != null && a.Data.Id == user.DefaultWorkspaceId) {
                        return -1;
                    }
                    if (b.Data != null && b.Data.Id == user.DefaultWorkspaceId) {
                        return 1;
                    }
                }

                var aName = a.Data != null ? (a.Data.Name ?? String.Empty) : String.Empty;
                var bName = b.Data != null ? (b.Data.Name ?? String.Empty) : String.Empty;
                return String.Compare (aName, bName, StringComparison.Ordinal);
            });
        }

        private void SortProjects (List<Project> data, List<ClientData> clients)
        {
            data.Sort ((a, b) => {
                if (a.IsNoProject != b.IsNoProject) {
                    return a.IsNoProject ? -1 : 1;
                }
                var res = 0;

                if (sortBy == SortProjectsBy.Clients) {
                    var aName = a.Data != null ? (a.Data.Name ?? String.Empty) : String.Empty;
                    var bName = b.Data != null ? (b.Data.Name ?? String.Empty) : String.Empty;
                    res = String.Compare (aName, bName, StringComparison.InvariantCulture);
                } else {
                    // Try to order by client name when same project name
                    var aClient = a.Data != null ? clients.FirstOrDefault (r => r.Id == a.Data.ClientId) : null;
                    var bClient = b.Data != null ? clients.FirstOrDefault (r => r.Id == b.Data.ClientId) : null;

                    var aClientName = aClient != null ? aClient.Name ?? String.Empty : String.Empty;
                    var bClientName = bClient != null ? bClient.Name ?? String.Empty : String.Empty;

                    res = String.Compare (aClientName, bClientName, StringComparison.InvariantCulture);
                }

                return res;
            });
        }

        private static void SortClients (List<Client> data)
        {
            data.Sort ((a, b) => {
                if (data.IndexOf (a) == data.IndexOf (b)) {
                    return 0;
                }

                if (a.IsMostUsed != b.IsMostUsed) {
                    return a.IsMostUsed ? -1 : 1;
                }

                if (a.IsNoClient != b.IsNoClient) {
                    return a.IsNoClient ? -1 : 1;
                }

                return String.Compare (
                           a.Data.Name ?? String.Empty,
                           b.Data.Name ?? String.Empty,StringComparison.InvariantCulture
                       );
            });
        }

        private static void SortTasks (List<TaskData> data)
        {
            data.Sort ((a, b) => String.Compare (
                           a.Name ?? String.Empty,
                           b.Name ?? String.Empty,
                           StringComparison.InvariantCulture
                       ));
        }

        public Task LoadMoreAsync () { return null; }

        private void UpdateCollection ()
        {
            dataObjects.Clear ();

            if (workspacesList == null) {
                return;
            }

            Workspace ws;
            ws = hasFilter ? filteredList : workspacesList [currentWorkspaceIndex];
            switch (sortBy) {
            case SortProjectsBy.Clients:

                foreach (var client in ws.Clients) {
                    if (client.Projects.Count == 0) {
                        continue;
                    }

                    dataObjects.Add (client);
                    foreach (var project in client.Projects) {
                        dataObjects.Add (project);
                        if (unfoldedTaskProject != null && project == unfoldedTaskProject) {
                            foreach (var task in project.Tasks) {
                                dataObjects.Add (task);
                            }
                        }
                    }
                }
                break;
            default:

                foreach (var project in ws.Projects) {
                    dataObjects.Add (project);
                    if (unfoldedTaskProject != null && project == unfoldedTaskProject) {
                        foreach (var task in project.Tasks) {
                            dataObjects.Add (task);
                        }
                    }
                }
                var mostUsedClientList = ws.Clients.Where (c => c.IsMostUsed);
                if (mostUsedClientList.Any ()) {
                    var mostUsedClient = mostUsedClientList.First ();
                    dataObjects.InsertRange (1, mostUsedClient.Projects);
                }
                break;
            }

            OnUpdated ();
        }

        public IEnumerable<object> Data
        {
            get {
                return dataObjects;
            }
        }

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

        public int CountWorkspaces
        {
            get {
                return workspacesList.Count;
            }
        }

        public List<Workspace> Workspaces
        {
            get {
                return workspacesList;
            }
        }

        public int CurrentWorkspaceIndex
        {
            get {
                return currentWorkspaceIndex;
            } set {
                if (workspacesList.Count > value) {
                    currentWorkspaceIndex = value;
                }
                UpdateCollection ();
            }
        }

        public event EventHandler HasMoreChanged;

        public bool HasMore
        {
            get {
                return hasMore;
            }
            private set {
                hasMore = value;
                if (HasMoreChanged != null) {
                    HasMoreChanged (this, EventArgs.Empty);
                }
            }
        }

        public event EventHandler IsLoadingChanged;

        public bool IsLoading
        {
            get {
                return isLoading;
            }
            private set {
                isLoading = value;
                if (IsLoadingChanged != null) {
                    IsLoadingChanged (this, EventArgs.Empty);
                }
            }
        }

        public class Workspace
        {
            private WorkspaceData dataObject;
            private readonly List<Project> projects = new List<Project> ();
            private readonly List<Client> clients = new List<Client> ();

            public Workspace (WorkspaceData dataObject)
            {
                this.dataObject = dataObject;
                projects.Add (new Project (dataObject));
            }

            public WorkspaceData Data
            {
                get { return dataObject; }
                set {
                    if (value == null) {
                        throw new ArgumentNullException ("value");
                    }
                    if (dataObject.Id != value.Id) {
                        throw new ArgumentException ("Cannot change Id of the workspace.", "value");
                    }
                    dataObject = value;
                }
            }

            public List<Project> Projects
            {
                get { return projects; }
            }

            public bool HasNoProjects
            {
                get {
                    return Projects.Count == 1 && Projects[0].IsNoProject;
                }
            }
            public List<Client> Clients
            {
                get { return clients; }
            }
        }

        public class Client
        {
            private ClientData dataObject;
            private readonly Guid workspaceId;
            private readonly List<Project> projects = new List<Project> ();

            public Client (ClientData dataObject)
            {
                this.dataObject = dataObject;
                workspaceId = dataObject.WorkspaceId;
            }

            public Client (WorkspaceData workspaceData)
            {
                dataObject = null;
                workspaceId = workspaceData.Id;
            }

            public bool IsNoClient { get; set; }

            public bool IsMostUsed { get; set; }

            public Guid WorkspaceId
            {
                get { return dataObject != null ? dataObject.WorkspaceId : workspaceId; }
            }

            public ClientData Data
            {
                get { return dataObject; }
                set {
                    if (value == null) {
                        throw new ArgumentNullException ("value");
                    }

                    if (dataObject.Id != value.Id) {
                        throw new ArgumentException ("Cannot change Id of the project.", "value");
                    }
                    dataObject = value;
                }
            }

            public List<Project> Projects
            {
                get { return projects; }
            }
        }

        public class Project
        {
            private ProjectData dataObject;
            private readonly List<TaskData> tasks = new List<TaskData> ();
            private readonly Guid workspaceId;

            public Project (ProjectData dataObject)
            {
                this.dataObject = dataObject;
                workspaceId = dataObject.WorkspaceId;
            }

            public Project (WorkspaceData workspaceData)
            {
                dataObject = null;
                workspaceId = workspaceData.Id;
            }

            public bool IsNoProject
            {
                get { return dataObject == null; }
            }

            public bool IsNewProject
            {
                get { return dataObject != null && dataObject.Id == Guid.Empty; }
            }

            public Guid WorkspaceId
            {
                get { return dataObject != null ? dataObject.WorkspaceId : workspaceId; }
            }

            public ProjectData Data
            {
                get { return dataObject; }
                set {
                    if (value == null) {
                        throw new ArgumentNullException ("value");
                    }
                    if (dataObject.Id != value.Id) {
                        throw new ArgumentException ("Cannot change Id of the project.", "value");
                    }
                    dataObject = value;
                }
            }

            public List<TaskData> Tasks
            {
                get { return tasks; }
            }
        }

        public enum SortProjectsBy {
            Projects,
            Clients
        }
    }
}


text:
<?php

namespace Salexandru\Api\Middleware;

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Salexandru\Api\Server\Exception\InvalidAccessTokenException;
use Salexandru\Api\Server\Exception\InvalidJsonSyntaxException;
use Salexandru\Api\Server\Exception\MissingAccessTokenException;
use Salexandru\Api\Server\Exception\MissingContentTypeException;
use Salexandru\Api\Server\Exception\UnsupportedMediaTypeException;
use Salexandru\Jwt\AdapterInterface as JwtAdapter;
use Salexandru\Util\PsrHttp as PsrHttpUtilities;

class RequestVettingMiddleware
{

    private $jwtAdapter;
    private $requiresAccessToken;
    private $expectedMediaType;

    public function __construct(JwtAdapter $jwtAdapter, array $options = null)
    {
        $this->jwtAdapter = $jwtAdapter;

        $defaults = [
            'requiresAccessToken' => true,
            'expectedMediaType' => 'application/json'
        ];

        if (null === $options) {
            $options = $defaults;
        } else {
            $options = array_merge($defaults, $options);
        }

        $this->setOptions($options);
    }

    public function __invoke(Request $req, Response $res, callable $next)
    {
        $req = $this->ensureRequirementsAreMetFor($req);
        $res = $next($req, $res);

        return $res;
    }

    private function ensureRequirementsAreMetFor(Request $request)
    {
        if ($request->getMethod() === 'POST' || $request->getMethod() === 'PUT') {
            $this->ensureExpectedMediaType($mediaType = PsrHttpUtilities::retrieveMediaTypeFrom($request));
            if ($mediaType === 'application/json') {
                try {
                    $parsedBody = $request->getParsedBody();
                } catch (\RuntimeException $e) {
                    $parsedBody = null;
                }
                $this->ensureValidJsonBody($parsedBody);
            }
        }

        if ($this->requiresAccessToken) {
            $token = $this->extractAccessTokenFrom($request);
            if (null === $token) {
                throw new MissingAccessTokenException('An access token is required to access this resource');
            }

            if (!$this->jwtAdapter->isValidToken($token)) {
                throw new InvalidAccessTokenException('Provided access token is invalid');
            }

            $request = $request->withAttribute('accessToken', $token);
        }

        return $request;
    }

    private function ensureExpectedMediaType($mediaType)
    {
        if (null === $mediaType) {
            throw new MissingContentTypeException('POST and PUT requests are required to have a content-type header');
        }

        if (null !== $this->expectedMediaType && $this->expectedMediaType !== $mediaType) {
            throw new UnsupportedMediaTypeException(
                "Unexpected content type; expected '$this->expectedMediaType' got '$mediaType'"
            );
        }
    }

    private function ensureValidJsonBody($parsedBody)
    {
        if (!is_array($parsedBody) && !is_object($parsedBody)) {
            throw new InvalidJsonSyntaxException('The provided request body is not valid JSON');
        }
    }

    private function extractAccessTokenFrom(Request $req)
    {
        $authorization = null;
        $result = $req->getHeader('authorization');
        if ($result) {
            $authorization = $result ? $result[0] : null;
        }

        if ($authorization) {
            preg_match('!bearer\s+(.+?)\s*$!i', $authorization, $matches);
            if (is_array($matches) && isset($matches[1])) {
                return $matches[1];
            }
        }

        return null;
    }

    private function setOptions(array $options)
    {
        $requiresAccessToken = true;
        $expectedMediaType = null;

        extract($options);

        $this->requiresAccessToken = ($requiresAccessToken == true);
        $this->expectedMediaType = $expectedMediaType;
    }
}

redpajama_set_name: RedPajamaGithub


text:
/*
 * ==============================================================================
 *  Name        : OgreSamplesBrowserAppUi.cpp
 *  Part of     : OgreSamplesBrowser
 *
 * ==============================================================================
 */

// INCLUDE FILES
#include "OgreSamplesBrowserAppUi.h"
#include "OgreSamplesBrowserContainer.h"
#include <OgreSamplesBrowser.rsg>
#include "ogresamplesbrowser.hrh"

#include <avkon.hrh>

// ================= MEMBER FUNCTIONS =======================
//
// ----------------------------------------------------------
// COgreSamplesBrowserAppUi::ConstructL()
// ----------------------------------------------------------
//
void COgreSamplesBrowserAppUi::ConstructL()
    {
    BaseConstructL();
    iAppContainer = new (ELeave) COgreSamplesBrowserContainer;
    iAppContainer->SetMopParent(this);
    iAppContainer->ConstructL( ClientRect(), this );
    AddToStackL( iAppContainer );
    }

// ----------------------------------------------------
// COgreSamplesBrowserAppUi::~COgreSamplesBrowserAppUi()
// Destructor. Frees any reserved resources.
// ----------------------------------------------------
//
COgreSamplesBrowserAppUi::~COgreSamplesBrowserAppUi()
	{
    if ( iAppContainer )
		{
        RemoveFromStack( iAppContainer );
        delete iAppContainer;
		}
	}

// ------------------------------------------------------------------------------
// COgreSamplesBrowserAppUi::::DynInitMenuPaneL(TInt aResourceId,CEikMenuPane* aMenuPane)
//  This function is called by the EIKON framework just before it displays
//  a menu pane. Its default implementation is empty, and by overriding it,
//  the application can set the state of menu items dynamically according
//  to the state of application data.
// ------------------------------------------------------------------------------
//
void COgreSamplesBrowserAppUi::DynInitMenuPaneL(
    TInt /*aResourceId*/,CEikMenuPane* /*aMenuPane*/)
    {
    }

// ----------------------------------------------------
// COgreSamplesBrowserAppUi::HandleKeyEventL(
//     const TKeyEvent& aKeyEvent,TEventCode /*aType*/)
// ----------------------------------------------------
//
TKeyResponse COgreSamplesBrowserAppUi::HandleKeyEventL(
    const TKeyEvent& /*aKeyEvent*/,TEventCode /*aType*/)
    {
    return EKeyWasNotConsumed;
    }

// ----------------------------------------------------
// COgreSamplesBrowserAppUi::HandleCommandL(TInt aCommand)
// ----------------------------------------------------
//
void COgreSamplesBrowserAppUi::HandleCommandL(TInt aCommand)
    {
    switch ( aCommand )
        {
        case EAknSoftkeyBack:
        case EEikCmdExit:
            {
            Exit();
            break;
            }
        default:
            break;
        }
    }

// End of File


text:
package org.sparky.model.builders;

import org.sparky.model.Bit;
import org.sparky.model.KeyRule;
import org.sparky.model.Rule;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by lloyd on 17/10/2015.
 */
public class VariableBuilder implements EvaluatableBuilder {

    private final List<Bit> bits = new ArrayList<>();

    @Override
    public VariableBuilder withBit(Bit bit) {
        bits.add(bit);
        return this;
    }

    @Override
    public Rule build() {
        return new KeyRule(bits);
    }

    public String buildAsColumnName(){
        if(bits.size() != 1){
            throw new IllegalStateException("A TableColumn Variable should only have a single bit");
        }
        if(!(bits.get(0) instanceof Rule.KeyBit)){
            throw new IllegalStateException("A TableColumn Variable should only have a single KeyBit");
        }
        return ((Rule.KeyBit)bits.get(0)).getKey();
    }
}


text:
<?php
namespace Aspose\Tasks\WorkingWithCurrencies;

use com\aspose\tasks\Project as Project;
use com\aspose\tasks\Prj as Prj;
use com\aspose\tasks\SaveFileFormat as SaveFileFormat;

class CurrencySymbols{

    public static function run($dataDir=null){

        # Getting Currency Symbol
        CurrencySymbols::get_currency_symbol($dataDir);

    	# Getting Currency Symbol
    	CurrencySymbols::set_currency_symbol($dataDir);
    }

    public static function get_currency_symbol($dataDir=null){

        # Instantiate project object
        $project = new Project($dataDir . 'test_tasks.mpp');

        $prj=new Prj();
        print "Currency Symbol: " . (string)$project->get($prj->CURRENCY_SYMBOL).PHP_EOL;//.to_string
    }

    public static function set_currency_symbol($dataDir=null){

        # Instantiate project object
        $project = new Project($dataDir . 'test_tasks.mpp');

        $prj=new Prj();
        $project->set($prj->CURRENCY_SYMBOL, "$$");

        $saveFileFormat=new SaveFileFormat();
        $project->save($dataDir . "ProjectCurrSymbols.mpp", $saveFileFormat->MPP);

        exit;
        print "Set currency symbol.".PHP_EOL;
    }

}
?>


text:
<?php

namespace StealThisShow\StealThisTracker\File;

use StealThisShow\StealThisTracker\Error as BaseError;

/**
 * Exception thrown when error happens in the File subpackage.
 *
 * @package    StealThisTracker
 * @subpackage File
 * @author     StealThisShow <info@stealthisshow.com>
 * @license    https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause
 */
class Error extends BaseError
{
}


text:
using UnityEngine;
using System.Collections;

public class GameController : MonoBehaviour
{
	public GameObject hazard;
	public Vector3 spawnValues;
	public int hazardCount;
	public float startWait;
	public float spawnWait;
	public float waveWait;
    public GUIText scoreText;
    public GUIText restartText;
    public GUIText gameOverText;

    private bool _gameOver;
    private bool _restart;
	private int _score;
	private float _sceneRadius;

	void Start()
    {
        _gameOver = false;
        _restart = false;
        restartText.text = string.Empty;
        gameOverText.text = string.Empty;

        _score = 0;
	    UpdateScore();

		SceneController sceneController = null;
		GameObject sceneControllerObject = GameObject.FindWithTag("SceneController");
		if (sceneControllerObject != null)
		{
			sceneController = sceneControllerObject.GetComponent<SceneController>();
		}
		if (sceneController == null)
		{
			Debug.Log("Cannot find 'SceneController' script");
		}
		_sceneRadius = sceneController.sceneRadius;

		StartCoroutine (SpawnWaves());
	}

    void Update()
    {
        if (_restart && Input.GetKeyDown(KeyCode.Return))
        {
            Application.LoadLevel(Application.loadedLevel);
        }
    }

	IEnumerator SpawnWaves()
	{
		yield return new WaitForSeconds(startWait);
		while (true)
		{
			for(int i = 0; i < hazardCount; i++)
			{
				Vector3 spawnPosition = new Vector3(Random.Range(-_sceneRadius+1, _sceneRadius-1),
				                                    Random.Range(-_sceneRadius+1, _sceneRadius-1),
				                                    Random.Range(-_sceneRadius+1, _sceneRadius-1));
				Quaternion spawnRotation = Quaternion.identity;

				Instantiate(hazard, spawnPosition, spawnRotation);

				yield return new WaitForSeconds(spawnWait);
			}

			yield return new WaitForSeconds(waveWait);

		    if (_gameOver)
		    {
		        restartText.text = "Press 'Enter' to restart";
		        _restart = true;
		        break;
		    }
		}
	}

    public void AddScore(int value)
    {
        _score += value;
        UpdateScore();
    }

    void UpdateScore()
    {
        scoreText.text = "Score: " + _score;
    }

    public void GameOver()
    {
        gameOverText.text = "Game Over";
        _gameOver = true;
    }
}


text:
package ru.stqa.pft.addressbook.appmanager;

import org.openqa.selenium.By;
import org.openqa.selenium.NoAlertPresentException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

import java.io.File;
import java.util.NoSuchElementException;

/**
 * Created by Ada on 2016-12-17.
 */
public class HelperBase {
  protected WebDriver wd;

  public HelperBase(WebDriver wd) {
    this.wd = wd;
  }

  protected void click(By locator) {
    wd.findElement(locator).click();
  }

  protected void type(By locator, String text) {
    click(locator);
    WebElement e = wd.findElement(locator);
    if (text != null){
      String existingText = e.getAttribute("value");
      if (! text.equals(existingText)) {
        e.clear();
        e.sendKeys(text);
      }
    }
  }

  protected void attach(By locator, File file) {
        if (file != null){
          wd.findElement(locator).sendKeys(file.getAbsolutePath());
    }
  }

  public boolean isAlertPresent() {
    try {
      wd.switchTo().alert();
      return true;
    } catch (NoAlertPresentException e) {
      return false;
    }
  }

  protected boolean isElementPresent(By locator) {
      try {
        wd.findElement(locator);
        return true;
      } catch (org.openqa.selenium.NoSuchElementException ex) {
        return false;
      }
  }
}


text:
from functools import wraps

import numpy as np

from ..base import normalize_token
from ..utils import derived_from
from .core import asanyarray, blockwise, map_blocks
from .routines import _average

@normalize_token.register(np.ma.masked_array)
def normalize_masked_array(x):
    data = normalize_token(x.data)
    mask = normalize_token(x.mask)
    fill_value = normalize_token(x.fill_value)
    return (data, mask, fill_value)

@derived_from(np.ma)
def filled(a, fill_value=None):
    a = asanyarray(a)
    return a.map_blocks(np.ma.filled, fill_value=fill_value)

def _wrap_masked(f):
    @wraps(f)
    def _(a, value):
        a = asanyarray(a)
        value = asanyarray(value)
        ainds = tuple(range(a.ndim))[::-1]
        vinds = tuple(range(value.ndim))[::-1]
        oinds = max(ainds, vinds, key=len)
        return blockwise(f, oinds, a, ainds, value, vinds, dtype=a.dtype)

    return _

masked_greater = _wrap_masked(np.ma.masked_greater)
masked_greater_equal = _wrap_masked(np.ma.masked_greater_equal)
masked_less = _wrap_masked(np.ma.masked_less)
masked_less_equal = _wrap_masked(np.ma.masked_less_equal)
masked_not_equal = _wrap_masked(np.ma.masked_not_equal)

@derived_from(np.ma)
def masked_equal(a, value):
    a = asanyarray(a)
    if getattr(value, "shape", ()):
        raise ValueError("da.ma.masked_equal doesn't support array `value`s")
    inds = tuple(range(a.ndim))
    return blockwise(np.ma.masked_equal, inds, a, inds, value, (), dtype=a.dtype)

@derived_from(np.ma)
def masked_invalid(a):
    return asanyarray(a).map_blocks(np.ma.masked_invalid)

@derived_from(np.ma)
def masked_inside(x, v1, v2):
    x = asanyarray(x)
    return x.map_blocks(np.ma.masked_inside, v1, v2)

@derived_from(np.ma)
def masked_outside(x, v1, v2):
    x = asanyarray(x)
    return x.map_blocks(np.ma.masked_outside, v1, v2)

@derived_from(np.ma)
def masked_where(condition, a):
    cshape = getattr(condition, "shape", ())
    if cshape and cshape != a.shape:
        raise IndexError(
            "Inconsistant shape between the condition and the "
            "input (got %s and %s)" % (cshape, a.shape)
        )
    condition = asanyarray(condition)
    a = asanyarray(a)
    ainds = tuple(range(a.ndim))
    cinds = tuple(range(condition.ndim))
    return blockwise(
        np.ma.masked_where, ainds, condition, cinds, a, ainds, dtype=a.dtype
    )

@derived_from(np.ma)
def masked_values(x, value, rtol=1e-05, atol=1e-08, shrink=True):
    x = asanyarray(x)
    if getattr(value, "shape", ()):
        raise ValueError("da.ma.masked_values doesn't support array `value`s")
    return map_blocks(
        np.ma.masked_values, x, value, rtol=rtol, atol=atol, shrink=shrink
    )

@derived_from(np.ma)
def fix_invalid(a, fill_value=None):
    a = asanyarray(a)
    return a.map_blocks(np.ma.fix_invalid, fill_value=fill_value)

@derived_from(np.ma)
def getdata(a):
    a = asanyarray(a)
    return a.map_blocks(np.ma.getdata)

@derived_from(np.ma)
def getmaskarray(a):
    a = asanyarray(a)
    return a.map_blocks(np.ma.getmaskarray)

def _masked_array(data, mask=np.ma.nomask, masked_dtype=None, **kwargs):
    if "chunks" in kwargs:
        del kwargs["chunks"]  # A Dask kwarg, not NumPy.
    return np.ma.masked_array(data, mask=mask, dtype=masked_dtype, **kwargs)

@derived_from(np.ma)
def masked_array(data, mask=np.ma.nomask, fill_value=None, **kwargs):
    data = asanyarray(data)
    inds = tuple(range(data.ndim))
    arginds = [inds, data, inds]

    if getattr(fill_value, "shape", ()):
        raise ValueError("non-scalar fill_value not supported")
    kwargs["fill_value"] = fill_value

    if mask is not np.ma.nomask:
        mask = asanyarray(mask)
        if mask.size == 1:
            mask = mask.reshape((1,) * data.ndim)
        elif data.shape != mask.shape:
            raise np.ma.MaskError(
                "Mask and data not compatible: data shape "
                "is %s, and mask shape is "
                "%s." % (repr(data.shape), repr(mask.shape))
            )
        arginds.extend([mask, inds])

    if "dtype" in kwargs:
        kwargs["masked_dtype"] = kwargs["dtype"]
    else:
        kwargs["dtype"] = data.dtype

    return blockwise(_masked_array, *arginds, **kwargs)

def _set_fill_value(x, fill_value):
    if isinstance(x, np.ma.masked_array):
        x = x.copy()
        np.ma.set_fill_value(x, fill_value=fill_value)
    return x

@derived_from(np.ma)
def set_fill_value(a, fill_value):
    a = asanyarray(a)
    if getattr(fill_value, "shape", ()):
        raise ValueError("da.ma.set_fill_value doesn't support array `value`s")
    fill_value = np.ma.core._check_fill_value(fill_value, a.dtype)
    res = a.map_blocks(_set_fill_value, fill_value)
    a.dask = res.dask
    a._name = res.name

@derived_from(np.ma)
def average(a, axis=None, weights=None, returned=False):
    return _average(a, axis, weights, returned, is_masked=True)


text:
<?php

namespace Zelenin\Ddd\Core\Domain\Model;

use Zelenin\Ddd\Core\Domain\Contract\HasEqualsTo;
use Zelenin\Ddd\Core\Domain\Contract\HasId;
use Zelenin\Ddd\Core\Domain\Object\Object;

interface Entity extends Object, HasId, HasEqualsTo
{
}


text:
package com.alibaba.dubbo.common.beanutil;

import java.io.Serializable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author kimi
 */
public final class JavaBeanDescriptor implements Serializable, Iterable<Map.Entry<Object, Object>> {

    private static final long serialVersionUID = -8505586483570518029L;

    public static final int TYPE_CLASS = 1;

    public static final int TYPE_ENUM = 2;

    public static final int TYPE_COLLECTION = 3;

    public static final int TYPE_MAP = 4;

    public static final int TYPE_ARRAY = 5;

    /** @see com.alibaba.dubbo.common.utils.ReflectUtils#isPrimitive(Class)  */
    public static final int TYPE_PRIMITIVE = 6;

    public static final int TYPE_BEAN = 7;

    private static final String ENUM_PROPERTY_NAME = "name";

    private static final String CLASS_PROPERTY_NAME = "name";

    private static final String PRIMITIVE_PROPERTY_VALUE = "value";

    /**
     * Used to define a type is valid.
     * @see #isValidType(int)
     */
    private static final int TYPE_MAX = TYPE_BEAN;

    /**
     * Used to define a type is valid.
     * @see #isValidType(int)
     */
    private static final int TYPE_MIN = TYPE_CLASS;

    private String className;

    private int type;

    private Map<Object, Object> properties = new LinkedHashMap<Object, Object>();

    public JavaBeanDescriptor() {}

    public JavaBeanDescriptor(String className, int type) {
        notEmpty(className, "class name is empty");
        if (!isValidType(type)) {
            throw new IllegalArgumentException(
                new StringBuilder(16).append("type [ ")
                    .append(type).append(" ] is unsupported").toString());
        }

        this.className = className;
        this.type = type;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public void setType(int type) {
        this.type = type;
    }

    public boolean isClassType() {
        return TYPE_CLASS == type;
    }

    public boolean isEnumType() {
        return TYPE_ENUM == type;
    }

    public boolean isCollectionType() {
        return TYPE_COLLECTION == type;
    }

    public boolean isMapType() {
        return TYPE_MAP == type;
    }

    public boolean isArrayType() {
        return TYPE_ARRAY == type;
    }

    public boolean isPrimitiveType() {
        return TYPE_PRIMITIVE == type;
    }

    public boolean isBeanType() {
        return TYPE_BEAN == type;
    }

    public int getType() {
        return type;
    }

    public String getClassName() {
        return className;
    }

    public Object setProperty(Object propertyName, Object propertyValue) {
        notNull(propertyName, "Property name is null");

        Object oldValue = properties.put(propertyName, propertyValue);
        return oldValue;
    }

    public String setEnumNameProperty(String name) {
        if (isEnumType()) {
            Object result = setProperty(ENUM_PROPERTY_NAME, name);
            return result == null ? null : result.toString();
        }
        throw new IllegalStateException("The instance is not a enum wrapper");
    }

    public String getEnumPropertyName() {
        if (isEnumType()) {
            Object result = getProperty(ENUM_PROPERTY_NAME).toString();
            return result == null ? null : result.toString();
        }
        throw new IllegalStateException("The instance is not a enum wrapper");
    }

    public String setClassNameProperty(String name) {
        if (isClassType()) {
            Object result = setProperty(CLASS_PROPERTY_NAME, name);
            return result == null ? null : result.toString();
        }
        throw new IllegalStateException("The instance is not a class wrapper");
    }

    public String getClassNameProperty() {
        if (isClassType()) {
            Object result = getProperty(CLASS_PROPERTY_NAME);
            return result == null ? null : result.toString();
        }
        throw new IllegalStateException("The instance is not a class wrapper");
    }

    public Object setPrimitiveProperty(Object primitiveValue) {
        if (isPrimitiveType()) {
            return setProperty(PRIMITIVE_PROPERTY_VALUE, primitiveValue);
        }
        throw new IllegalStateException("The instance is not a primitive type wrapper");
    }

    public Object getPrimitiveProperty() {
        if (isPrimitiveType()) {
            return getProperty(PRIMITIVE_PROPERTY_VALUE);
        }
        throw new IllegalStateException("The instance is not a primitive type wrapper");
    }

    public Object getProperty(Object propertyName) {
        notNull(propertyName, "Property name is null");
        Object propertyValue = properties.get(propertyName);
        return propertyValue;
    }

    public boolean containsProperty(Object propertyName) {
        notNull(propertyName, "Property name is null");
        return properties.containsKey(propertyName);
    }

    public Iterator<Map.Entry<Object, Object>> iterator() {
        return properties.entrySet().iterator();
    }

    public int propertySize() {
        return properties.size();
    }

    private boolean isValidType(int type) {
        return TYPE_MIN <= type && type <= TYPE_MAX;
    }

    private void notNull(Object obj, String message) {
        if (obj == null) {
            throw new IllegalArgumentException(message);
        }
    }

    private void notEmpty(String string, String message) {
        if (isEmpty(string)) {
            throw new IllegalArgumentException(message);
        }
    }

    private boolean isEmpty(String string) {
        return string == null || "".equals(string.trim());
    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Circular Progress Bar Sizes -->
    <item name="circular_progress_bar_inner_radius_ratio" format="float" type="dimen">3</item>
    <item name="circular_progress_bar_thickness_ratio" format="float" type="dimen">10</item>
</resources>


text:
"""
调试器,用于测试时调试执行爬虫
"""
import os
import time
import shutil
from multiprocessing import Process
from ..worker import launcher as worker
from ..scheduler import launcher as scheduler
from ..scheduler.client import HTTPError, Client
from ..common import Logger, FatalError, PickleContainer
from ..worker.common import find_free_port, parse_project_configs

logger = Logger.instance('pyloom')

def main(options):
    """
    :param options: 命令行参数
    """
    sub_processes = {}
    debugger_path = os.path.join(options.path, '__debugger__')
    # 子进程的stdin是关闭的,因此在主进程中读取参数
    project_configs = parse_project_configs(options)
    # 清理调试环境
    if options.clear:
        if os.path.exists(debugger_path):
            shutil.rmtree(debugger_path)
        logger.info("调试缓存已清空")
        return
    if options.nocache:
        if os.path.exists(debugger_path):
            shutil.rmtree(debugger_path)
        logger.info("调试缓存已清空")
    # 启动调度节点
    logger.info("启动Scheduler节点")
    if options.scheduler_port:
        scheduler_port = options.scheduler_port
    else:
        scheduler_port = find_free_port()
    scheduler_bind = "127.0.0.1"
    scheduler_configs = {
        "server": {
            "bind": scheduler_bind,
            "port": scheduler_port,
        },
        "pickle": os.path.join(debugger_path, 'scheduler')
    }
    process = Process(target=scheduler.main, args=(options, scheduler_configs))
    process.start()
    sub_processes['Scheduler'] = process
    # 注册项目
    client = Client(f"http://{scheduler_bind}:{scheduler_port}")
    project_id = PickleContainer.load(debugger_path, 'project_id', None)
    if project_id is None:
        logger.info("正在注册项目")
        project_id = client.projects.create("debugger")
        PickleContainer.dump(debugger_path, 'project_id', project_id)
    try:
        client.queues.create(project_id, exist_ok=True, **project_configs["scheduler"])
        client.buckets.create(project_id, exist_ok=True)
    except HTTPError as e:
        raise FatalError(str(e))
    # 启动工作节点
    for i in range(options.workers):
        logger.info(f"启动Worker-{i}节点")
        worker_configs = {
            "scheduler": f"http://{scheduler_bind}:{scheduler_port}",
            "pickle": os.path.join(debugger_path, f'worker-{i}'),
        }
        project_configs['project_id'] = project_id
        process = Process(target=worker.main, args=(options, worker_configs, project_configs))
        process.start()
        sub_processes[f'Worker-{i}'] = process
    # 等待子进程结束
    # 任何一个子进程意外退出,则终止所有进程
    try:
        while True:
            for name, process in sub_processes.items():
                if not process.is_alive():
                    raise FatalError(f"{name}意外退出")
            time.sleep(1)
    except FatalError as e:
        logger.error("严重错误", e)
        for name, process in sub_processes.items():
            if process.is_alive():
                logger.warning(f"正在结束{name}")
                process.terminate()
    except KeyboardInterrupt:
        logger.info("Debugger收到KeyboardInterrupt信号")
    finally:
        logger.info("Debugger已退出")


text:
<?php

namespace Omnipay\WorldPayXML\Message;

use Guzzle\Plugin\Cookie\Cookie;
use Guzzle\Plugin\Cookie\CookiePlugin;
use Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar;
use Omnipay\Common\CreditCard;
use Omnipay\Common\Message\AbstractRequest;

/**
 * Omnipay WorldPay XML Purchase Request
 */
class PurchaseRequest extends AbstractRequest
{
    const EP_HOST_LIVE = 'https://secure.worldpay.com';
    const EP_HOST_TEST = 'https://secure-test.worldpay.com';

    const EP_PATH = '/jsp/merchant/xml/paymentService.jsp';

    const VERSION = '1.4';

    /**
     * @var \Guzzle\Plugin\Cookie\CookiePlugin
     *
     * @access protected
     */
    protected $cookiePlugin;

    /**
     * Get accept header
     *
     * @access public
     * @return string
     */
    public function getAcceptHeader()
    {
        return $this->getParameter('acceptHeader');
    }

    /**
     * Set accept header
     *
     * @param string $value Accept header
     *
     * @access public
     * @return void
     */
    public function setAcceptHeader($value)
    {
        return $this->setParameter('acceptHeader', $value);
    }

    /**
     * Get cookie plugin
     *
     * @access public
     * @return \Guzzle\Plugin\Cookie\CookiePlugin
     */
    public function getCookiePlugin()
    {
        return $this->cookiePlugin;
    }

    /**
     * Get installation
     *
     * @access public
     * @return string
     */
    public function getInstallation()
    {
        return $this->getParameter('installation');
    }

    /**
     * Set installation
     *
     * @param string $value Installation
     *
     * @access public
     * @return void
     */
    public function setInstallation($value)
    {
        return $this->setParameter('installation', $value);
    }

    /**
     * Get merchant
     *
     * @access public
     * @return string
     */
    public function getMerchant()
    {
        return $this->getParameter('merchant');
    }

    /**
     * Set merchant
     *
     * @param string $value Merchant
     *
     * @access public
     * @return void
     */
    public function setMerchant($value)
    {
        return $this->setParameter('merchant', $value);
    }

    /**
     * Get pa response
     *
     * @access public
     * @return string
     */
    public function getPaResponse()
    {
        return $this->getParameter('pa_response');
    }

    /**
     * Set pa response
     *
     * @param string $value Pa response
     *
     * @access public
     * @return void
     */
    public function setPaResponse($value)
    {
        return $this->setParameter('pa_response', $value);
    }

    /**
     * Get password
     *
     * @access public
     * @return string
     */
    public function getPassword()
    {
        return $this->getParameter('password');
    }

    /**
     * Set password
     *
     * @param string $value Password
     *
     * @access public
     * @return void
     */
    public function setPassword($value)
    {
        return $this->setParameter('password', $value);
    }

    /**
     * Get redirect cookie
     *
     * @access public
     * @return string
     */
    public function getRedirectCookie()
    {
        return $this->getParameter('redirect_cookie');
    }

    /**
     * Set redirect cookie
     *
     * @param string $value Password
     *
     * @access public
     * @return void
     */
    public function setRedirectCookie($value)
    {
        return $this->setParameter('redirect_cookie', $value);
    }

    /**
     * Get redirect echo
     *
     * @access public
     * @return string
     */
    public function getRedirectEcho()
    {
        return $this->getParameter('redirect_echo');
    }

    /**
     * Set redirect echo
     *
     * @param string $value Password
     *
     * @access public
     * @return void
     */
    public function setRedirectEcho($value)
    {
        return $this->setParameter('redirect_echo', $value);
    }

    /**
     * Get session
     *
     * @access public
     * @return string
     */
    public function getSession()
    {
        return $this->getParameter('session');
    }

    /**
     * Set session
     *
     * @param string $value Session
     *
     * @access public
     * @return void
     */
    public function setSession($value)
    {
        return $this->setParameter('session', $value);
    }

    /**
     * Get term url
     *
     * @access public
     * @return string
     */
    public function getTermUrl()
    {
        return $this->getParameter('termUrl');
    }

    /**
     * Set term url
     *
     * @param string $value Term url
     *
     * @access public
     * @return void
     */
    public function setTermUrl($value)
    {
        return $this->setParameter('termUrl', $value);
    }

    /**
     * Get user agent header
     *
     * @access public
     * @return string
     */
    public function getUserAgentHeader()
    {
        return $this->getParameter('userAgentHeader');
    }

    /**
     * Set user agent header
     *
     * @param string $value User agent header
     *
     * @access public
     * @return void
     */
    public function setUserAgentHeader($value)
    {
        return $this->setParameter('userAgentHeader', $value);
    }

    /**
     * Get data
     *
     * @access public
     * @return \SimpleXMLElement
     */
    public function getData()
    {
        if ($this->getCard()->getNumber() == '') {
            $this->validate('amount');
            $useCreditCard = false;
        } else {
            $this->validate('amount', 'card');
            $this->getCard()->validate();
            $useCreditCard = true;
        }

        $data = new \SimpleXMLElement('<paymentService />');
        $data->addAttribute('version', self::VERSION);
        $data->addAttribute('merchantCode', $this->getMerchant());

        $order = $data->addChild('submit')->addChild('order');
        $order->addAttribute('orderCode', $this->getTransactionId());
        $order->addAttribute('installationId', $this->getInstallation());

        $order->addChild('description', $this->getDescription());

        $amount = $order->addChild('amount');
        $amount->addAttribute('value', $this->getAmountInteger());
        $amount->addAttribute('currencyCode', $this->getCurrency());
        $amount->addAttribute('exponent', $this->getCurrencyDecimalPlaces());

        $codes = array(
            CreditCard::BRAND_AMEX        => 'AMEX-SSL',
            CreditCard::BRAND_DANKORT     => 'DANKORT-SSL',
            CreditCard::BRAND_DINERS_CLUB => 'DINERS-SSL',
            CreditCard::BRAND_DISCOVER    => 'DISCOVER-SSL',
            CreditCard::BRAND_JCB         => 'JCB-SSL',
            CreditCard::BRAND_LASER       => 'LASER-SSL',
            CreditCard::BRAND_MAESTRO     => 'MAESTRO-SSL',
            CreditCard::BRAND_MASTERCARD  => 'ECMC-SSL',
            CreditCard::BRAND_SWITCH      => 'MAESTRO-SSL',
            CreditCard::BRAND_VISA        => 'VISA-SSL'
        );

        $payment = $order->addChild('paymentMethodMask');

        foreach ($codes as $code) {
            $include = $payment->addChild('include');
            $include->addAttribute('code', $code);
        }

        $shopper = $order->addChild('shopper');

        $email = $this->getCard()->getEmail();

        if (!empty($email)) {
            $shopper->addChild(
                'shopperEmailAddress',
                $this->getCard()->getEmail()
            );
        }

        $browser = $shopper->addChild('browser');
        $browser->addChild('acceptHeader', $this->getAcceptHeader());
        $browser->addChild('userAgentHeader', $this->getUserAgentHeader());

        $echoData = $this->getRedirectEcho();

        if (!empty($echoData)) {
            $order->addChild('echoData', $echoData);
        }

        return $data;
    }

    /**
     * Send data
     *
     * @param \SimpleXMLElement $data Data
     *
     * @access public
     * @return \Omnipay\WorldPayXML\Message\RedirectResponse
     */
    public function sendData($data)
    {
        $implementation = new \DOMImplementation();

        $dtd = $implementation->createDocumentType(
            'paymentService',
            '-//WorldPay//DTD WorldPay PaymentService v1//EN',
            'http://dtd.worldpay.com/paymentService_v1.dtd'
        );

        $document = $implementation->createDocument(null, '', $dtd);
        $document->encoding = 'utf-8';

        $node = $document->importNode(dom_import_simplexml($data), true);
        $document->appendChild($node);

        $authorisation = base64_encode(
            $this->getMerchant() . ':' . $this->getPassword()
        );

        $headers = array(
            'Authorization' => 'Basic ' . $authorisation,
            'Content-Type'  => 'text/xml; charset=utf-8'
        );

        $cookieJar = new ArrayCookieJar();

        $redirectCookie = $this->getRedirectCookie();

        if (!empty($redirectCookie)) {
            $url = parse_url($this->getEndpoint());

            $cookieJar->add(
                new Cookie(
                    array(
                        'domain' => $url['host'],
                        'name'   => 'machine',
                        'path'   => '/',
                        'value'  => $redirectCookie
                    )
                )
            );
        }

        $this->cookiePlugin = new CookiePlugin($cookieJar);

        $this->httpClient->addSubscriber($this->cookiePlugin);

        $xml = $document->saveXML();

        $httpResponse = $this->httpClient
            ->post($this->getEndpoint(), $headers, $xml)
            ->send();

        return $this->response = new RedirectResponse(
            $this,
            $httpResponse->getBody()
        );
    }

    /**
     * Get endpoint
     *
     * Returns endpoint depending on test mode
     *
     * @access protected
     * @return string
     */
    protected function getEndpoint()
    {
        if ($this->getTestMode()) {
            return self::EP_HOST_TEST . self::EP_PATH;
        }

        return self::EP_HOST_LIVE . self::EP_PATH;
    }
}


text:
package com.linecorp.armeria.common.auth;

import static com.google.common.base.Strings.isNullOrEmpty;
import static com.linecorp.armeria.common.auth.AuthUtil.secureEquals;
import static com.linecorp.armeria.internal.common.PercentEncoder.encodeComponent;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.annotation.Nullable;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Ascii;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

import com.linecorp.armeria.common.HttpHeaderNames;
import com.linecorp.armeria.internal.common.util.TemporaryThreadLocals;

/**
 * The bearer token of OAuth 1.0a authentication.
 */
public final class OAuth1aToken {

    /**
     * realm parameter. (optional)
     */
    private static final String REALM = "realm";

    /**
     * oauth_consumer_key parameter.
     */
    @VisibleForTesting
    static final String OAUTH_CONSUMER_KEY = "oauth_consumer_key";

    /**
     * oauth_token parameter.
     */
    @VisibleForTesting
    static final String OAUTH_TOKEN = "oauth_token";

    /**
     * oauth_signature_method parameter.
     */
    @VisibleForTesting
    static final String OAUTH_SIGNATURE_METHOD = "oauth_signature_method";

    /**
     * oauth_signature parameter.
     */
    @VisibleForTesting
    static final String OAUTH_SIGNATURE = "oauth_signature";

    /**
     * oauth_timestamp parameter.
     */
    @VisibleForTesting
    static final String OAUTH_TIMESTAMP = "oauth_timestamp";

    /**
     * oauth_nonce parameter.
     */
    @VisibleForTesting
    static final String OAUTH_NONCE = "oauth_nonce";

    /**
     * version parameter. (optional)
     * If not set, the default value is 1.0.
     */
    private static final String OAUTH_VERSION = "version";

    /**
     * Set of required parameters.
     */
    private static final Set<String> REQUIRED_PARAM_KEYS = ImmutableSet.of(OAUTH_CONSUMER_KEY, OAUTH_TOKEN,
                                                                           OAUTH_SIGNATURE_METHOD,
                                                                           OAUTH_SIGNATURE, OAUTH_TIMESTAMP,
                                                                           OAUTH_NONCE);

    /**
     * Set of optional parameters.
     */
    private static final Set<String> OPTIONAL_PARAM_KEYS = ImmutableSet.of(REALM, OAUTH_VERSION);

    /**
     * Set of defined parameters, regardless of it is required or not.
     */
    private static final Set<String> DEFINED_PARAM_KEYS = Sets.union(REQUIRED_PARAM_KEYS, OPTIONAL_PARAM_KEYS);

    /**
     * Creates a new {@link OAuth1aToken} from the given arguments.
     */
    public static OAuth1aToken of(Map<String, String> params) {
        return new OAuth1aToken(params);
    }

    private final Map<String, String> params;

    @Nullable
    private String headerValue;

    private OAuth1aToken(Map<String, String> params) {
        // Map builder with default version value.
        final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();

        for (Entry<String, String> param : params.entrySet()) {
            final String key = param.getKey();
            final String value = param.getValue();

            // Empty values are ignored.
            if (!isNullOrEmpty(value)) {
                final String lowerCased = Ascii.toLowerCase(key);
                if (DEFINED_PARAM_KEYS.contains(lowerCased)) {
                    // If given parameter is defined by Oauth1a protocol, add with lower-cased key.
                    builder.put(lowerCased, value);
                } else {
                    // Otherwise, just add.
                    builder.put(key, value);
                }
            }
        }

        this.params = builder.build();

        if (!this.params.keySet().containsAll(REQUIRED_PARAM_KEYS)) {
            final Set<String> missing = Sets.difference(REQUIRED_PARAM_KEYS, this.params.keySet());
            throw new IllegalArgumentException("Missing OAuth1a parameters: " + missing);
        }

        try {
            Long.parseLong(this.params.get(OAUTH_TIMESTAMP));
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(
                    "Illegal " + OAUTH_TIMESTAMP + " value: " + this.params.get(OAUTH_TIMESTAMP));
        }
    }

    /**
     * Returns the value of the {@value #REALM} property.
     */
    public String realm() {
        return params.get(REALM);
    }

    /**
     * Returns the value of the {@value #OAUTH_CONSUMER_KEY} property.
     */
    public String consumerKey() {
        return params.get(OAUTH_CONSUMER_KEY);
    }

    /**
     * Returns the value of the {@value #OAUTH_TOKEN} property.
     */
    public String token() {
        return params.get(OAUTH_TOKEN);
    }

    /**
     * Returns the value of {@value #OAUTH_SIGNATURE_METHOD} property.
     */
    public String signatureMethod() {
        return params.get(OAUTH_SIGNATURE_METHOD);
    }

    /**
     * Returns the value of {@value #OAUTH_SIGNATURE} property.
     */
    public String signature() {
        return params.get(OAUTH_SIGNATURE);
    }

    /**
     * Returns the value of {@value #OAUTH_TIMESTAMP} property.
     */
    public String timestamp() {
        return params.get(OAUTH_TIMESTAMP);
    }

    /**
     * Returns the value of {@value #OAUTH_NONCE} property.
     */
    public String nonce() {
        return params.get(OAUTH_NONCE);
    }

    /**
     * Returns the value of {@value #OAUTH_VERSION} property.
     * If not set, returns the default value of {@code "1.0"}.
     */
    public String version() {
        return params.getOrDefault(OAUTH_VERSION, "1.0");
    }

    /**
     * Returns additional (or user-defined) parameters.
     */
    public Map<String, String> additionals() {
        final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
        for (Entry<String, String> e : params.entrySet()) {
            if (!DEFINED_PARAM_KEYS.contains(e.getKey())) {
                builder.put(e.getKey(), e.getValue());
            }
        }
        return builder.build();
    }

    /**
     * Returns the string that is sent as the value of the {@link HttpHeaderNames#AUTHORIZATION} header.
     */
    public String toHeaderValue() {
        if (headerValue != null) {
            return headerValue;
        }
        final StringBuilder builder = TemporaryThreadLocals.get().stringBuilder();
        builder.append("OAuth ");
        final String realm = realm();
        if (!isNullOrEmpty(realm())) {
            builder.append("realm=\"");
            encodeComponent(builder, realm);
            builder.append("\",");
        }
        builder.append("oauth_consumer_key=\"");
        encodeComponent(builder, consumerKey());
        builder.append("\",oauth_token=\"");
        encodeComponent(builder, token());
        builder.append("\",oauth_signature_method=\"");
        encodeComponent(builder, signatureMethod());
        builder.append("\",oauth_signature=\"");
        encodeComponent(builder, signature());
        builder.append("\",oauth_timestamp=\"");
        encodeComponent(builder, timestamp());
        builder.append("\",oauth_nonce=\"");
        encodeComponent(builder, nonce());
        builder.append("\",version=\"");
        // Do not have to encode the version.
        builder.append(version());
        builder.append('"');
        for (Entry<String, String> entry : additionals().entrySet()) {
            builder.append("\",");
            encodeComponent(builder, entry.getKey());
            builder.append("=\"");
            encodeComponent(builder, entry.getValue());
            builder.append('"');
        }
        return headerValue = builder.toString();
    }

    @Override
    public boolean equals(@Nullable Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof OAuth1aToken)) {
            return false;
        }
        final OAuth1aToken that = (OAuth1aToken) o;

        // Do not short-circuit to make it hard to guess anything from timing.
        boolean equals = true;
        for (Entry<String, String> e : params.entrySet()) {
            equals &= secureEquals(that.params.get(e.getKey()), e.getValue());
        }

        return equals && params.size() == that.params.size();
    }

    @Override
    public int hashCode() {
        return params.hashCode();
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                          .add("realm", realm())
                          .add("consumerKey", consumerKey())
                          .add("token", "****")
                          .add("signatureMethod", signatureMethod())
                          .add("signature", signature())
                          .add("timestamp", timestamp())
                          .add("nonce", nonce())
                          .add("version", version())
                          .add("additionals", additionals())
                          .toString();
    }
}


text:
{-# LANGUAGE ForeignFunctionInterface, MagicHash, UnboxedTuples #-}

-- From trac #1947
-- Should fail with heap exhaustion
-- See notes below with "Infinite loop here".

module Main(main) where

import System.IO.Unsafe
import System.IO
import System.Environment
import System.Exit
import Foreign.C.Types
import Data.Char(ord,chr)

-- low level imports
import GHC.Base                 (realWorld#)
import GHC.IO                   (IO(IO), unIO, unsafePerformIO)
import GHC.Prim                 (State#,RealWorld)

-- FFI replacements for Haskell stuff
foreign import ccall unsafe "stdio.h getchar" getchar :: IO CInt
foreign import ccall unsafe "ctype.h iswspace" isspace :: CInt -> CInt

skipCAF :: State# RealWorld -> a -> a
skipCAF _ x = x

-- IO Subsystem
-- Unboxed IO is more efficient, but requires a certain level of
-- optimisation, so provide a BOXED_IO fallback

data RW_Box = RW_Box (State# RealWorld)
type RW_Pair a = (RW_Box, a)

fromIO :: IO a -> (RW_Box -> RW_Pair a)
fromIO a (RW_Box r) = case unIO a r of (# r, x #) -> (RW_Box r, x)

toIO :: (RW_Box -> RW_Pair a) -> IO a
toIO f = IO $ \r -> case f (RW_Box r) of (RW_Box r, x) -> (# r, x #)

-- IO functions not dependent on the IO primitives
main :: IO ()
main = toIO main_generated

typeRealWorld :: RW_Box -> RW_Box
typeRealWorld x = x

overlay_get_char :: RW_Box -> RW_Pair Int
overlay_get_char = fromIO $ do
    c <- getchar
    return $ fromIntegral c

system_IO_hPutChar :: Handle -> Int -> RW_Box -> RW_Pair ()
system_IO_hPutChar h c = fromIO $ hPutChar h (chr c)

overlay_errorIO :: [Int] -> RW_Box -> RW_Pair a
overlay_errorIO x r = case fromIO (putStrLn ("ERROR: " ++ map chr x)) r of
                           (r, _) -> fromIO exitFailure r

system_Environment_getArgs :: RW_Box -> RW_Pair [[Int]]
system_Environment_getArgs r = case (fromIO getArgs) r of
                                    (r, s) -> (r, map str_ s)

overlay_supero_wrap x = x

-- Primitives
prelude_seq = seq

prelude_error x = error (map chr x)

aDD_W = (+) :: Int -> Int -> Int
mUL_W = (*) :: Int -> Int -> Int
sUB_W = (-) :: Int -> Int -> Int
eQ_W = (==) :: Int -> Int -> Bool
nE_W = (/=) :: Int -> Int -> Bool
gT_W = (>) :: Int -> Int -> Bool
gE_W = (>=) :: Int -> Int -> Bool
lT_W = (<) :: Int -> Int -> Bool
lE_W = (<=) :: Int -> Int -> Bool
qUOT = quot :: Int -> Int -> Int
rEM = rem :: Int -> Int -> Int
nEG_W = negate :: Int -> Int
yHC_Primitive_primIntAbs = abs :: Int -> Int
yHC_Primitive_primIntSignum = signum :: Int -> Int
yHC_Primitive_primIntegerAdd = (+) :: Integer -> Integer -> Integer
yHC_Primitive_primIntegerEq = (==) :: Integer -> Integer -> Bool
yHC_Primitive_primIntegerFromInt = toInteger :: Int -> Integer
yHC_Primitive_primIntegerGe = (>=) :: Integer -> Integer -> Bool
yHC_Primitive_primIntegerGt = (>) :: Integer -> Integer -> Bool
yHC_Primitive_primIntegerLe = (<=) :: Integer -> Integer -> Bool
yHC_Primitive_primIntegerMul = (*) :: Integer -> Integer -> Integer
yHC_Primitive_primIntegerNe = (/=) :: Integer -> Integer -> Bool
yHC_Primitive_primIntegerNeg = negate :: Integer -> Integer
yHC_Primitive_primIntegerQuot = quot :: Integer -> Integer -> Integer
yHC_Primitive_primIntegerQuotRem = quotRem :: Integer -> Integer -> (Integer, Integer)
yHC_Primitive_primIntegerRem = rem :: Integer -> Integer -> Integer
yHC_Primitive_primIntFromInteger = fromInteger :: Integer -> Int
yHC_Primitive_primIntegerLt = (<) :: Integer -> Integer -> Bool
yHC_Primitive_primIntegerSub = (-) :: Integer -> Integer -> Integer

aDD_D = (+) :: Double -> Double -> Double
sUB_D = (-) :: Double -> Double -> Double
lT_D = (<) :: Double -> Double -> Bool
lE_D = (<=) :: Double -> Double -> Bool
gT_D = (>) :: Double -> Double -> Bool
gE_D = (>=) :: Double -> Double -> Bool
eQ_D = (==) :: Double -> Double -> Bool
mUL_D = (*) :: Double -> Double -> Double
nEG_D = (negate) :: Double -> Double
nE_D = (/=) :: Double -> Double -> Bool
sLASH_D = (/) :: Double -> Double -> Double
yHC_Primitive_primDecodeDouble = decodeFloat :: Double -> (Integer,Int)
yHC_Primitive_primDoubleACos = acos :: Double -> Double
yHC_Primitive_primDoubleASin = asin :: Double -> Double
yHC_Primitive_primDoubleATan = atan :: Double -> Double
yHC_Primitive_primDoubleAbs = abs :: Double -> Double
yHC_Primitive_primDoubleCos = cos :: Double -> Double
yHC_Primitive_primDoubleExp = exp :: Double -> Double
yHC_Primitive_primDoubleFromInteger = fromInteger :: Integer -> Double
yHC_Primitive_primDoubleLog = log :: Double -> Double
yHC_Primitive_primDoublePow = (**) :: Double -> Double -> Double
yHC_Primitive_primDoubleSignum = signum :: Double -> Double
yHC_Primitive_primDoubleSin = sin :: Double -> Double
yHC_Primitive_primDoubleSqrt = sqrt :: Double -> Double
yHC_Primitive_primDoubleTan = tan :: Double -> Double
yHC_Primitive_primEncodeDouble = encodeFloat :: Integer -> Int -> Double

-- things which Yhc decides should be hopelessly slow
prelude_Int_Integral_mod = mod :: Int -> Int -> Int
prelude_Integer_Integral_div = div :: Integer -> Integer -> Integer
prelude_Integer_Integral_mod = mod :: Integer -> Integer -> Integer
prelude_Integer_Num_signum = signum :: Integer -> Integer
prelude_Integer_Num_abs = abs :: Integer -> Integer

int_ x = x :: Int
chr_ x = ord x
str_ x = map chr_ x

system_IO_stdin = stdin
system_IO_stdout = stdout

data_Char_isSpace :: Int -> Bool
data_Char_isSpace c = isspace (toEnum c) /= 0

type ReadsPrec a = Int -> [Int] -> [(a,[Int])]

prelude_Int_Read_readsPrec :: ReadsPrec Int
prelude_Int_Read_readsPrec p s = [(a, str_ b) | (a,b) <- readsPrec p (map chr s)]
prelude_Int_Read_readList = undefined

prelude_Integer_Read_readsPrec :: ReadsPrec Integer
prelude_Integer_Read_readsPrec p s = [(a, str_ b) | (a,b) <- readsPrec p (map chr s)]
prelude_Integer_Read_readList = undefined

prelude_Double_Read_readsPrec :: ReadsPrec Double
prelude_Double_Read_readsPrec p s = [(a, str_ b) | (a,b) <- readsPrec p (map chr s)]
prelude_Double_Read_readList = undefined

prelude_Char_Read_readsPrec :: ReadsPrec Int
prelude_Char_Read_readsPrec p s = [(chr_ (a :: Char), str_ b) | (a,b) <- readsPrec p (map chr s)]

prelude_Char_Show_showList :: [Int] -> [Int] -> [Int]
prelude_Char_Show_showList value rest = str_ (show (map chr value)) ++ rest

prelude_Char_Show_showsPrec :: Int -> Int -> [Int] -> [Int]
prelude_Char_Show_showsPrec prec i rest = str_ (showsPrec prec (chr i) []) ++ rest

prelude_Int_Show_showsPrec :: Int -> Int -> [Int] -> [Int]
prelude_Int_Show_showsPrec prec i rest = str_ (showsPrec prec i []) ++ rest

prelude_Integer_Show_showsPrec :: Int -> Integer -> [Int] -> [Int]
prelude_Integer_Show_showsPrec prec i rest = str_ (showsPrec prec i []) ++ rest

prelude_Double_Show_showsPrec :: Int -> Double -> [Int] -> [Int]
prelude_Double_Show_showsPrec prec i rest = str_ (showsPrec prec i []) ++ rest

prelude_'amp'amp27 v1 v2 =
    case (data_Char_isSpace v1) of
        True ->
            case v2 of
                [] -> True
                (:) v4 v5 -> prelude_'amp'amp27 v4 v5
        False -> False

prelude_LAMBDA22 v1 v2 =
    case v1 of
        (,) v267 v268 ->
            case v268 of
                [] -> prelude_LAMBDA24 v267 v2
                (:) v7 v8 ->
                    let v11 = prelude_'amp'amp27 v7 v8
                    in case v11 of
                           True -> prelude_LAMBDA24 v267 v2
                           False -> prelude__foldr25 v2

prelude_LAMBDA24 v1 v2 = (:) v1 (prelude__foldr25 v2)

prelude_IO_Monad_fail41 v1 =
    overlay_errorIO
      (skipCAF realWorld# (str_ "pattern-match failure in do expression"))
      v1

prelude__foldr25 v1 =
    case v1 of
        [] -> []
        (:) v296 v297 -> prelude_LAMBDA22 v296 v297

f17 uncaf = skipCAF uncaf (str_ "Prelude.read: no parse")

f18 v1 v2 =
    case v1 of
        (,) v176 v177 ->
            case v177 of
                [] -> f20 v176 v2
                (:) v7 v8 ->
                    let v11 = prelude_'amp'amp27 v7 v8
                    in case v11 of
                           True -> f20 v176 v2
                           False ->
                               case v2 of
                                   [] -> prelude_error (f17 realWorld#)
                                   (:) v4 v5 -> f18 v4 v5

f20 v1 v2 =
    case v2 of
        [] -> v1
        (:) v257 v258 ->
            let v9 = prelude_LAMBDA22 v257 v258
            in case v9 of
                   [] -> v1
                   (:) v10 v11 ->
                       prelude_error
                         (skipCAF realWorld# (str_ "Prelude.read: ambiguous parse"))

-- Infinite loop here.  It was originally:
-- f34 v1 v2 v3 =
--    let v336 = f34 v1 v2 v3
--    in v336
--
-- But that now (correctly) just makes a non-allocating infinite loop
-- instead of (incorrectly) eta-reducing to f34 = f34.
-- So I've changed to an infinite, allocating loop, which makes
-- the heap get exhausted.
f34 v1 v2 v3 =
  if abs v2 < 1000 then
    let v336 = f34 (v1+1) (-v2) v3
    in v336
  else if v2 == 2000 then 0 else v1

f38 v1 v2 =
    case v1 of
        [] -> system_IO_hPutChar system_IO_stdout (chr_ '\n') v2
        (:) v350 v351 ->
            case (system_IO_hPutChar
                    system_IO_stdout
                    v350
                    (typeRealWorld v2)) of
                ( v7  , v8  ) -> f38 v351 v7

main_generated v1 =
    case (system_Environment_getArgs (typeRealWorld v1)) of
        ( v3  , v4  ) ->
            case v4 of
                (:) v7 v8 ->
                    case v8 of
                        (:) v9 v12 ->
                            case v12 of
                                (:) v13 v14 ->
                                    case v14 of
                                        [] ->
                                            case (prelude_Int_Show_showsPrec
                                                    (int_ 0)
                                                    (let v8 =
                                                             case (prelude_Int_Read_readsPrec
                                                                     (int_ 0)
                                                                     v7) of
                                                                 [] -> prelude_error (f17 realWorld#)
                                                                 (:) v12 v14 -> f18 v12 v14
                                                         v10 =
                                                             case (prelude_Int_Read_readsPrec
                                                                     (int_ 0)
                                                                     v9) of
                                                                 [] -> prelude_error (f17 realWorld#)
                                                                 (:) v15 v16 -> f18 v15 v16
                                                         v11 =
                                                             case (prelude_Int_Read_readsPrec
                                                                     (int_ 0)
                                                                     v13) of
                                                                 [] -> prelude_error (f17 realWorld#)
                                                                 (:) v17 v18 -> f18 v17 v18
                                                     in case (lT_W v10 v8) of
                                                            True ->
                                                                let v7 = f34 v8 v10 v11
                                                                in v7
                                                            False -> v11)
                                                    (skipCAF realWorld# (str_ ""))) of
                                                [] ->
                                                    system_IO_hPutChar
                                                      system_IO_stdout
                                                      (chr_ '\n')
                                                      (typeRealWorld v3)
                                                (:) v11 v12 ->
                                                    case (system_IO_hPutChar
                                                            system_IO_stdout
                                                            v11
                                                            (typeRealWorld (typeRealWorld v3))) of
                                                        ( v7  , v8  ) -> f38 v12 v7
                                        (:) v15 v16 -> prelude_IO_Monad_fail41 v3
                                [] -> prelude_IO_Monad_fail41 v3
                        [] -> prelude_IO_Monad_fail41 v3
                [] -> prelude_IO_Monad_fail41 v3


text:
/* Basic reset */
html, body, p, ul, li, h1, h2, h3, div {
  margin: 0;
  padding: 0; }

* {
  box-sizing: border-box; }

/* Global */
html, body {
  width: 100%;
  height: 100%; }

body {
  perspective: 700px;
  font-family: Verdana, sans-serif;
  font-size: 12px;
  padding: 5px;
  background: ORANGERED; }

#app {
  width: 100%;
  height: 100%;
  background: IVORY; }

/* Canvas */
canvas {
  max-width: 100%;
  min-height: 150px; }

.charts {
  min-height: 150px; }

/* Minimal flex grid */
.container {
  display: flex; }

.container.vertical {
  flex-direction: column; }

.container > * {
  flex: 1 1 auto; }

.container .shrink {
  flex: 0 1 auto; }

/* Area Description */
p.description {
  min-height: 30px; }

/* List */
ul {
  overflow-x: hidden;
  overflow-y: scroll;
  -webkit-overflow-scrolling: touch;
  list-style: none;
  padding: 5px; }

/* Styling Radio and Checkbox */
input[type='radio'], input[type='checkbox'] {
  display: none; }

input[type='radio'] + .name, input[type='checkbox'] + .name {
  display: block;
  font-size: 1rem;
  padding: 1rem 0.5rem;
  padding-left: 2rem;
  border: 1px solid transparent;
  border-left: 0;
  border-right: 0;
  transition: all 0.3s ease-out; }

input[type='radio']:checked + .name, input[type='checkbox']:checked + .name {
  border-color: DARKORANGE; }

/* Radio specific */
input[type='radio'] + .name {
  background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/15649/radio.svg) 10px 50% no-repeat;
  background-size: 16px; }

input[type='radio']:checked + .name {
  background: SNOW url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/15649/radio-checked.svg) 10px 50% no-repeat;
  background-size: 16px; }

/* Checkbox specific */
input[type='checkbox']:checked + .name {
  background: SNOW url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/15649/checked.svg) 10px 50% no-repeat;
  background-size: 16px; }

/* Info Button */
#info-btn {
  position: absolute;
  top: 0;
  right: 0; }

#info-btn a {
  width: 44px;
  height: 44px;
  display: block;
  background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/15649/info.svg); }

#info-btn a span {
  display: none; }

/* Info panel */
.hidden {
  transform: rotateY(-90deg); }

.show {
  transform: rotateY(0); }

#info-panel {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: ORANGERED;
  color: white;
  transform-origin: 0 0;
  transition: all 0.3s ease-out;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center; }

#info-panel a {
  color: white; }

#info-panel p {
  margin: 0.5em; }

p.more-space {
  margin: 2em; }


text:
var customer_domains = [
    "bistri.com",
    "bistri.me",
    "*.bistri.com",
    "*.bistri.me",
    "fiddle.jshell.net/*",
    "run.jsbin.io/*"
];

/*
 ****************************************
 *     DO NOT EDIT UNDER THIS LINE      *
 ****************************************
*/

 Components.utils.import("resource://gre/modules/Services.jsm");

var addon_domains             = [];
var allowed_domains_pref      = 'media.getusermedia.screensharing.allowed_domains';
var enable_screensharing_pref = 'media.getusermedia.screensharing.enabled';
var WindowListener            = {
    onOpenWindow: function( xulWindow )
    {
        var window = xulWindow.QueryInterface( Components.interfaces.nsIInterfaceRequestor ).getInterface( Components.interfaces.nsIDOMWindow );
        function onWindowLoad(){
            window.removeEventListener( 'load', onWindowLoad );
            if( window.document.documentElement.getAttribute( 'windowtype' ) == 'navigator:browser' ){
                loadIntoWindow( window );
            }
        }
        window.addEventListener( 'load', onWindowLoad );
    },
    onCloseWindow: function( xulWindow )
    {
    },
    onWindowTitleChange: function( xulWindow, newTitle )
    {
    }
};

function forEachOpenWindow( fn )
{
    var windows = Services.wm.getEnumerator( 'navigator:browser' );
    while( windows.hasMoreElements() )
    {
        fn( windows.getNext().QueryInterface( Components.interfaces.nsIDOMWindow ) );
    }
}

function loadIntoWindow( window )
{
    window.gBrowser.addEventListener( 'load', function( event )
    {
        insertTag( event.target );
    }, true);
    for( var i=0; i<window.length; i++ )
    {
        insertTag( window[ i ].document );
    }
}

function insertTag( doc ){
    var insert = false;
    customer_domains.forEach( function( domain )
    {
        if( doc.URL.indexOf( domain ) != -1 )
        {
            insert = true;
        }
    } );
    if( insert )
    {
        var node = doc.createElement( 'div' );
        node.id = 'bistri-screen-sharing-installed';
        doc.body.appendChild( node );
    }
}

function startup(data, reason)
{
    if(reason !== APP_STARTUP)
    {
        var prefs = Components.classes[ '@mozilla.org/preferences-service;1' ].getService( Components.interfaces.nsIPrefBranch );
        var values = prefs.getCharPref( allowed_domains_pref ).split( ',' );
        customer_domains.forEach( function( domain )
        {
            if( values.indexOf( domain ) === -1 )
            {
                values.push( domain );
                addon_domains.push( domain );
            }
        } );
        if( prefs.getBoolPref( enable_screensharing_pref ) == false )
        {
            prefs.setBoolPref( enable_screensharing_pref, 1 );
        }
        prefs.setCharPref( allowed_domains_pref, values.join( ',' ) );
    }
    forEachOpenWindow( loadIntoWindow );
    Services.wm.addListener( WindowListener );
}

function shutdown( data, reason )
{
    if( reason !== APP_SHUTDOWN )
    {
        var prefs = Components.classes[ '@mozilla.org/preferences-service;1' ].getService( Components.interfaces.nsIPrefBranch );
        var values = prefs.getCharPref( allowed_domains_pref ).split( ',' );

        values = values.filter( function( value )
        {
            return addon_domains.indexOf( value ) === -1;
        } );
        prefs.setCharPref( allowed_domains_pref, values.join( ',' ) );
    }
    Services.wm.removeListener( WindowListener );
}

function install(data, reason){}
function uninstall(data, reason){}