text:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.

using Microsoft.MixedReality.Toolkit.SpatialAwareness;
using Microsoft.MixedReality.Toolkit.Utilities;
using System.Collections.Generic;
using UnityEngine;

#if UNITY_WSA
using UnityEngine.XR.WSA;
#endif // UNITY_WSA

namespace Microsoft.MixedReality.Toolkit.WindowsMixedReality.SpatialAwareness
{
    [MixedRealityDataProvider(
        typeof(IMixedRealitySpatialAwarenessSystem),
        SupportedPlatforms.WindowsUniversal,
        "Windows Mixed Reality Spatial Mesh Observer",
        "Profiles/DefaultMixedRealitySpatialAwarenessMeshObserverProfile.asset",
        "MixedRealityToolkit.SDK")]
    public class WindowsMixedRealitySpatialMeshObserver : BaseSpatialObserver, IMixedRealitySpatialAwarenessMeshObserver
    {
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="registrar">The <see cref="IMixedRealityServiceRegistrar"/> instance that loaded the service.</param>
        /// <param name="name">Friendly name of the service.</param>
        /// <param name="priority">Service priority. Used to determine order of instantiation.</param>
        /// <param name="profile">The service's configuration profile.</param>
        public WindowsMixedRealitySpatialMeshObserver(
            IMixedRealityServiceRegistrar registrar,
            IMixedRealitySpatialAwarenessSystem spatialAwarenessSystem,
            string name = null,
            uint priority = DefaultPriority,
            BaseMixedRealityProfile profile = null) : base(registrar, spatialAwarenessSystem, name, priority, profile)
        {
            ReadProfile();
        }

        private void ReadProfile()
        {
            if (ConfigurationProfile == null)
            {
                Debug.LogError("Windows Mixed Reality Spatial Mesh Observer requires a configuration profile to run properly.");
                return;
            }

            MixedRealitySpatialAwarenessMeshObserverProfile profile = ConfigurationProfile as MixedRealitySpatialAwarenessMeshObserverProfile;
            if (profile == null)
            {
                Debug.LogError("Windows Mixed Reality Spatial Mesh Observer's configuration profile must be a MixedRealitySpatialAwarenessMeshObserverProfile.");
                return;
            }

            // IMixedRealitySpatialAwarenessObserver settings
            StartupBehavior = profile.StartupBehavior;
            IsStationaryObserver = profile.IsStationaryObserver;
            ObservationExtents = profile.ObservationExtents;
            ObserverVolumeType = profile.ObserverVolumeType;
            UpdateInterval = profile.UpdateInterval;

            // IMixedRealitySpatialAwarenessMeshObserver settings
            DisplayOption = profile.DisplayOption;
            LevelOfDetail = profile.LevelOfDetail;
            MeshPhysicsLayer = profile.MeshPhysicsLayer;
            OcclusionMaterial = profile.OcclusionMaterial;
            RecalculateNormals = profile.RecalculateNormals;
            TrianglesPerCubicMeter = profile.TrianglesPerCubicMeter;
            VisibleMaterial = profile.VisibleMaterial;
        }

        #region IMixedRealityToolkit implementation

#if UNITY_WSA

        /// <inheritdoc />
        public override void Initialize()
        {
            // Only initialize if the Spatial Awareness system has been enabled in the configuration profile.
            if (!MixedRealityToolkit.Instance.ActiveProfile.IsSpatialAwarenessSystemEnabled) { return; }

            CreateObserver();

            // Apply the initial observer volume settings.
            ConfigureObserverVolume();
        }

        /// <inheritdoc />
        public override void Reset()
        {
            CleanupObserver();
            Initialize();
        }

        /// <inheritdoc />
        public override void Enable()
        {
            // todo
        }

        /// <inheritdoc />
        public override void Update()
        {
            UpdateObserver();
        }

        /// <inheritdoc />
        public override void Disable()
        {
            // todo
        }

        /// <inheritdoc />
        public override void Destroy()
        {
            CleanupObserver();
        }

#endif // UNITY_WSA

        #endregion IMixedRealityToolkit implementation

        #region IMixedRealitySpatialAwarenessObserver implementation

        private GameObject observedObjectParent = null;

        /// <summary>
        /// The <see href="https://docs.unity3d.com/ScriptReference/GameObject.html">GameObject</see> to which observed objects are parented.
        /// </summary>
        private GameObject ObservedObjectParent => observedObjectParent != null ? observedObjectParent : (observedObjectParent = SpatialAwarenessSystem?.CreateSpatialAwarenessObjectParent("WindowsMixedRealitySpatialMeshObserver"));

        private IMixedRealitySpatialAwarenessSystem spatialAwarenessSystem = null;

        /// <summary>
        /// The currently active instance of <see cref="Microsoft.MixedReality.Toolkit.WindowsMixedReality.SpatialAwareness.IMixedRealitySpatialAwarenessSystem"/>.
        /// </summary>
        private IMixedRealitySpatialAwarenessSystem SpatialAwarenessSystem => spatialAwarenessSystem ?? (spatialAwarenessSystem = MixedRealityToolkit.SpatialAwarenessSystem);

#if UNITY_WSA
        /// <inheritdoc />
        protected override void Dispose(bool disposing)
        {
            if (disposed) { return; }

            base.Dispose(disposing);

            if (IsRunning)
            {
                Suspend();
            }

            if (disposing)
            {
                CleanupObservedObjects();
            }

            DisposeObserver();

            disposed = true;
        }

        /// <summary>
        /// The surface observer providing the spatial data.
        /// </summary>
        private SurfaceObserver observer = null;

        /// <summary>
        /// A queue of <see cref="SurfaceId"/> that need their meshes created (or updated).
        /// </summary>
        private readonly Queue<SurfaceId> meshWorkQueue = new Queue<SurfaceId>();

        /// <summary>
        /// To prevent too many meshes from being generated at the same time, we will
        /// only request one mesh to be created at a time.  This variable will track
        /// if a mesh creation request is in flight.
        /// </summary>
        private SpatialAwarenessMeshObject outstandingMeshObject = null;

        /// <summary>
        /// When surfaces are replaced or removed, rather than destroying them, we'll keep
        /// one as a spare for use in outstanding mesh requests. That way, we'll have fewer
        /// game object create/destroy cycles, which should help performance.
        /// </summary>
        protected SpatialAwarenessMeshObject spareMeshObject = null;

        /// <summary>
        /// The time at which the surface observer was last asked for updated data.
        /// </summary>
        private float lastUpdated = 0;
#endif // UNITY_WSA

        public SpatialAwarenessMeshDisplayOptions displayOption = SpatialAwarenessMeshDisplayOptions.Visible;
        /// <inheritdoc />
        public SpatialAwarenessMeshDisplayOptions DisplayOption
        {
            get
            {
                return displayOption;
            }

            set
            {
                if (value != displayOption)
                {
                    displayOption = value;
                    ApplyUpdatedMeshDisplayOption(displayOption);
                }
            }
        }

        public SpatialAwarenessMeshLevelOfDetail levelOfDetail = SpatialAwarenessMeshLevelOfDetail.Coarse;

        /// <inheritdoc />
        public SpatialAwarenessMeshLevelOfDetail LevelOfDetail
        {
            get { return levelOfDetail; }

            set
            {
                if (value != SpatialAwarenessMeshLevelOfDetail.Custom)
                {
                    // For non-custom levels, the enum value is the appropriate triangles per cubic meter.
                    TrianglesPerCubicMeter = (int)value;
                }

                levelOfDetail = value;
            }
        }

        private Dictionary<int, SpatialAwarenessMeshObject> meshes = new Dictionary<int, SpatialAwarenessMeshObject>();

        /// <inheritdoc />
        public IReadOnlyDictionary<int, SpatialAwarenessMeshObject> Meshes => new Dictionary<int, SpatialAwarenessMeshObject>(meshes) as IReadOnlyDictionary<int, SpatialAwarenessMeshObject>;

        /// <inheritdoc />
        public int MeshPhysicsLayer { get; set; }

        /// <inheritdoc />
        public int MeshPhysicsLayerMask => (1 << MeshPhysicsLayer);

        /// <inheritdoc />
        public Material OcclusionMaterial { get; set; } = null;

        /// <inheritdoc />
        public bool RecalculateNormals { get; set; } = true;

        public int TrianglesPerCubicMeter { get; set; } = 0;

        /// <inheritdoc />
        public Material VisibleMaterial { get; set; } = null;

        /// <inheritdoc/>
        public override void Resume()
        {
#if UNITY_WSA
            if (IsRunning)
            {
                Debug.LogWarning("The Windows Mixed Reality spatial observer is currently running.");
                return;
            }

            // We want the first update immediately.
            lastUpdated = 0;

            // UpdateObserver keys off of this value to start observing.
            IsRunning = true;

#endif // UNITY_WSA
        }

        /// <inheritdoc/>
        public override void Suspend()
        {
#if UNITY_WSA
            if (!IsRunning)
            {
                Debug.LogWarning("The Windows Mixed Reality spatial observer is currently stopped.");
                return;
            }

            // UpdateObserver keys off of this value to stop observing.
            IsRunning = false;

            // Clear any pending work.
            meshWorkQueue.Clear();
#endif // UNITY_WSA
        }

#if UNITY_WSA
        /// <summary>
        /// Creates the surface observer and handles the desired startup behavior.
        /// </summary>
        private void CreateObserver()
        {
            if (SpatialAwarenessSystem == null) { return; }

            if (observer == null)
            {
                observer = new SurfaceObserver();
                ConfigureObserverVolume();

                if (StartupBehavior == AutoStartBehavior.AutoStart)
                {
                    Resume();
                }
            }
        }

        /// <summary>
        /// Ensures that the surface observer has been stopped and destroyed.
        /// </summary>
        private void CleanupObserver()
        {
            // Destroys all observed objects and the observer.
            Dispose(true);
        }

        /// <summary>
        /// Cleans up the objects created during observation.
        /// </summary>
        private void CleanupObservedObjects()
        {
            if (Application.isPlaying)
            {
                // Cleanup the scene objects are managing
                if (observedObjectParent != null)
                {
                    observedObjectParent.transform.DetachChildren();
                }

                foreach (SpatialAwarenessMeshObject meshObject in meshes.Values)
                {
                    if (meshObject != null)
                    {
                        // Destroy the game object, destroy the meshes.
                        SpatialAwarenessMeshObject.Cleanup(meshObject);
                    }
                }
                meshes.Clear();

                // Cleanup the outstanding mesh object.
                if (outstandingMeshObject != null)
                {
                    // Destroy the game object, destroy the meshes.
                    SpatialAwarenessMeshObject.Cleanup(outstandingMeshObject);
                    outstandingMeshObject = null;
                }

                // Cleanup the spare mesh object
                if (spareMeshObject != null)
                {
                    // Destroy the game object, destroy the meshes.
                    SpatialAwarenessMeshObject.Cleanup(spareMeshObject);
                    spareMeshObject = null;
                }
            }
        }

        /// <summary>
        /// Implements proper cleanup of the SurfaceObserver.
        /// </summary>
        private void DisposeObserver()
        {
            if (observer != null)
            {
                observer.Dispose();
                observer = null;
            }
        }

        /// <summary>
        /// Requests updates from the surface observer.
        /// </summary>
        private void UpdateObserver()
        {
            if (!MixedRealityToolkit.Instance.ActiveProfile.IsSpatialAwarenessSystemEnabled ||
                (SpatialAwarenessSystem == null))
            {
                return;
            }

            // Only update the observer if it is running.
            if (IsRunning && (outstandingMeshObject == null))
            {
                // If we have a mesh to work on...
                if (meshWorkQueue.Count > 0)
                {
                    // We're using a simple first-in-first-out rule for requesting meshes, but a more sophisticated algorithm could prioritize
                    // the queue based on distance to the user or some other metric.
                    RequestMesh(meshWorkQueue.Dequeue());
                }
                // If enough time has passed since the previous observer update...
                else if (Time.time - lastUpdated >= UpdateInterval)
                {
                    // Update the observer orientation if user aligned
                    if (ObserverVolumeType == VolumeType.UserAlignedCube)
                    {
                        ObserverRotation = CameraCache.Main.transform.rotation;
                    }

                    // Update the observer location if it is not stationary
                    if (!IsStationaryObserver)
                    {
                        ObserverOrigin = CameraCache.Main.transform.position;
                    }

                    // The application can update the observer volume at any time, make sure we are using the latest.
                    ConfigureObserverVolume();

                    observer.Update(SurfaceObserver_OnSurfaceChanged);
                    lastUpdated = Time.time;
                }
            }
        }

        /// <summary>
        /// Issue a request to the Surface Observer to begin baking the mesh.
        /// </summary>
        /// <param name="surfaceId">ID of the mesh to bake.</param>
        private void RequestMesh(SurfaceId surfaceId)
        {
            string meshName = ("SpatialMesh - " + surfaceId.handle);

            SpatialAwarenessMeshObject newMesh;
            WorldAnchor worldAnchor;

            if (spareMeshObject == null)
            {
                newMesh = SpatialAwarenessMeshObject.Create(null, MeshPhysicsLayer, meshName, surfaceId.handle);

                worldAnchor = newMesh.GameObject.AddComponent<WorldAnchor>();
            }
            else
            {
                newMesh = spareMeshObject;
                spareMeshObject = null;

                newMesh.GameObject.name = meshName;
                newMesh.Id = surfaceId.handle;
                newMesh.GameObject.SetActive(true);

                worldAnchor = newMesh.GameObject.GetComponent<WorldAnchor>();
            }

            Debug.Assert(worldAnchor != null);

            SurfaceData surfaceData = new SurfaceData(
                surfaceId,
                newMesh.Filter,
                worldAnchor,
                newMesh.Collider,
                TrianglesPerCubicMeter,
                true);

            if (observer.RequestMeshAsync(surfaceData, SurfaceObserver_OnDataReady))
            {
                outstandingMeshObject = newMesh;
            }
            else
            {
                Debug.LogError($"Mesh request failed for Id == surfaceId.handle");
                outstandingMeshObject = null;
                ReclaimMeshObject(newMesh);
            }
        }

        /// <summary>
        /// Removes the <see cref="SpatialAwarenessMeshObject"/> associated with the specified id.
        /// </summary>
        /// <param name="id">The id of the mesh to be removed.</param>
        protected void RemoveMeshObject(int id)
        {
            SpatialAwarenessMeshObject mesh;

            if (meshes.TryGetValue(id, out mesh))
            {
                // Remove the mesh object from the collection.
                meshes.Remove(id);

                // Reclaim the mesh object for future use.
                ReclaimMeshObject(mesh);

                // Send the mesh removed event
                SpatialAwarenessSystem?.RaiseMeshRemoved(this, id);
            }
        }

        /// <summary>
        /// Reclaims the <see cref="SpatialAwarenessMeshObject"/> to allow for later reuse.
        /// </summary>
        /// <param name="availableMeshObject"></param>
        protected void ReclaimMeshObject(SpatialAwarenessMeshObject availableMeshObject)
        {
            if (spareMeshObject == null)
            {
                // Cleanup the mesh object.
                // Do not destroy the game object, destroy the meshes.
                SpatialAwarenessMeshObject.Cleanup(availableMeshObject, false);

                availableMeshObject.GameObject.name = "Unused Spatial Mesh";
                availableMeshObject.GameObject.SetActive(false);

                spareMeshObject = availableMeshObject;
            }
            else
            {
                // Cleanup the mesh object.
                // Destroy the game object, destroy the meshes.
                SpatialAwarenessMeshObject.Cleanup(availableMeshObject);
            }
        }

        /// <summary>
        /// Applies the configured observation extents.
        /// </summary>
        private void ConfigureObserverVolume()
        {
            // Update the observer
            switch(ObserverVolumeType)
            {
                case VolumeType.AxisAlignedCube:
                    observer.SetVolumeAsAxisAlignedBox(ObserverOrigin, ObservationExtents);
                    break;

                case VolumeType.Sphere:
                    // We use the x value of the extents as the sphere radius
                    observer.SetVolumeAsSphere(ObserverOrigin, ObservationExtents.x);
                    break;

                case VolumeType.UserAlignedCube:
                    observer.SetVolumeAsOrientedBox(ObserverOrigin, ObservationExtents, ObserverRotation);
                    break;

                default:
                    Debug.LogError($"Unsupported ObserverVolumeType value {ObserverVolumeType}");
                    break;
            }
        }

        /// <summary>
        /// Handles the SurfaceObserver's OnSurfaceChanged event.
        /// </summary>
        /// <param name="id">The identifier assigned to the surface which has changed.</param>
        /// <param name="changeType">The type of change that occurred on the surface.</param>
        /// <param name="bounds">The bounds of the surface.</param>
        /// <param name="updateTime">The date and time at which the change occurred.</param>
        private void SurfaceObserver_OnSurfaceChanged(SurfaceId id, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime)
        {
            if (!IsRunning) { return; }

            switch (changeType)
            {
                case SurfaceChange.Added:
                case SurfaceChange.Updated:
                    meshWorkQueue.Enqueue(id);
                    break;

                case SurfaceChange.Removed:
                    RemoveMeshObject(id.handle);
                    break;
            }
        }

        /// <summary>
        /// Handles the SurfaceObserver's OnDataReady event.
        /// </summary>
        /// <param name="cookedData">Struct containing output data.</param>
        /// <param name="outputWritten">Set to true if output has been written.</param>
        /// <param name="elapsedCookTimeSeconds">Seconds between mesh cook request and propagation of this event.</param>
        private void SurfaceObserver_OnDataReady(SurfaceData cookedData, bool outputWritten, float elapsedCookTimeSeconds)
        {
            if (!IsRunning) { return; }

            if (outstandingMeshObject == null)
            {
                Debug.LogWarning($"OnDataReady called for mesh id {cookedData.id.handle} while no request was outstanding.");
                return;
            }

            if (!outputWritten)
            {
                Debug.LogWarning($"OnDataReady reported no data written for mesh id {cookedData.id.handle}");
                ReclaimMeshObject(outstandingMeshObject);
                outstandingMeshObject = null;
                return;
            }

            // Since there is only one outstanding mesh object, update the id to match
            // the one received after baking.
            SpatialAwarenessMeshObject meshObject = outstandingMeshObject;
            meshObject.Id = cookedData.id.handle;
            outstandingMeshObject = null;

            // Apply the appropriate material to the mesh.
            SpatialAwarenessMeshDisplayOptions displayOption = DisplayOption;
            if (displayOption != SpatialAwarenessMeshDisplayOptions.None)
            {
                meshObject.Renderer.enabled = true;
                meshObject.Renderer.sharedMaterial = (displayOption == SpatialAwarenessMeshDisplayOptions.Visible) ?
                    VisibleMaterial :
                    OcclusionMaterial;
            }
            else
            {
                meshObject.Renderer.enabled = false;
            }

            // Recalculate the mesh normals if requested.
            if (RecalculateNormals)
            {
                meshObject.Filter.sharedMesh.RecalculateNormals();
            }

            // Add / update the mesh to our collection
            bool sendUpdatedEvent = false;
            if (meshes.ContainsKey(cookedData.id.handle))
            {
                // Reclaim the old mesh object for future use.
                ReclaimMeshObject(meshes[cookedData.id.handle]);
                meshes.Remove(cookedData.id.handle);

                sendUpdatedEvent = true;
            }
            meshes.Add(cookedData.id.handle, meshObject);

            meshObject.GameObject.transform.parent = (ObservedObjectParent.transform != null) ? ObservedObjectParent.transform : null;

            if (sendUpdatedEvent)
            {
                SpatialAwarenessSystem?.RaiseMeshUpdated(this, cookedData.id.handle, meshObject);
            }
            else
            {
                SpatialAwarenessSystem?.RaiseMeshAdded(this, cookedData.id.handle, meshObject);
            }
        }
#endif // UNITY_WSA

        /// <summary>
        /// Applies the mesh display option to existing meshes when modified at runtime.
        /// </summary>
        /// <param name="option">The <see cref="SpatialAwarenessMeshDisplayOptions"/> to apply to the meshes.</param>
        private void ApplyUpdatedMeshDisplayOption(SpatialAwarenessMeshDisplayOptions option)
        {
            bool enable = (option != SpatialAwarenessMeshDisplayOptions.None);

            foreach (SpatialAwarenessMeshObject meshObject in Meshes.Values)
            {
                if ((meshObject == null) || (meshObject.Renderer == null)) { continue; }

                if (enable)
                {
                    meshObject.Renderer.sharedMaterial = (option == SpatialAwarenessMeshDisplayOptions.Visible) ?
                        VisibleMaterial :
                        OcclusionMaterial;
                }

                meshObject.Renderer.enabled = enable;
            }
        }

        #endregion IMixedRealitySpatialAwarenessObserver implementation
    }
}


text:
/*jsl:import startup.js*/

DC.ValueTransformer = Class.create({

    transformedValue: function(value)
    {
        return value;
    },

    reverseTransformedValue: function(value)
    {
        return value;
    },

    __factory__: function()
    {
        var args= Array.from(arguments);
        var klass= this;

        function dummyConstructor(){}

        return function()
        {
            dummyConstructor.prototype= klass.prototype;
            var obj= new dummyConstructor();
            klass.prototype.constructor.apply(obj, args);
            return obj;
        };
    }

});

DC.ValueTransformer.__subclassCreated__= function(subclass)
{
    var rootproto= DC.ValueTransformer.prototype;
    var proto= subclass.prototype;

    /*  Mask the reverseTransformedValue if not overridden in a subclass.
        This enables the detection of whether the Transformer _really_ supports
        reverse transformation, while at the same time, clearly documenting the
        API for reverseTransformedValue.
        @JEFF: I think this may be a bit dangerous, because if someone were just
        inspecting the code, he might be confused about why reverseTransformedValue
        wasn't executing...
     */
    if (rootproto.reverseTransformedValue == proto.reverseTransformedValue)
        subclass.prototype.reverseTransformedValue = null;
}

/** @namespace
    This is where all the ValueTransformer classes are registered.
 **/
DC.transformer= {};

/** @namespace
    This is where all the registered instances of ValueTransformers live.
 **/
DC.transformerInstances= {};

/** Lookup a ValueTransformer instance by name.
 *
 *  @param transformerName  the name of the value transformer
 *  @returns a reference to the specifed value transformer
 *  @throws InvalidArgumentError if the transformerName does not specify
 *          a pre-registered value transformer
 **/
DC.findTransformerWithName= function(transformerName)
{
    var valueTransformer= DC.transformerInstances[transformerName.toLowerCase()];
    if (valueTransformer)
        return valueTransformer;

    //  Try to create an instance of the transformer assuming the transformerName
    //  value is a class name
    if (-1===transformerName.indexOf('.'))
        valueTransformer= DC.transformer[transformerName];

    //  If there were dots in the name or the undotted name wasn't found, try to
    //  evaluate the string to see if it resolves to an instance, constructor, or
    //  finally a factory function.
    if (!valueTransformer)
    {
        try
        {
            valueTransformer= eval(transformerName);
        }
        catch(e)
        {}
    }

    if (!valueTransformer)
        throw new InvalidArgumentError("The transformerName argument does not specify a valid ValueTransformer: " +
                                       transformerName);

    //  If the valueTransformer isn't a function, just return it
    if ('function'!==typeof(valueTransformer))
        return valueTransformer;

    //  valueTransformer is now either a factory function or a constructor.
    //  Create an instance of the transformer, if you need arguments, you should
    //  probably consider using the factory function version...
    if (valueTransformer.__factoryFn__)
        valueTransformer= valueTransformer();
    else
        valueTransformer= new valueTransformer();

    return valueTransformer;
}

/** Register an instance of a ValueTransformer with a specific name.

    @param valueTransformer the value transformer instance or constructor
                            to register
    @param name             the name by which this value transformer is known

    @throws InvalidArgumentError if the valueTransformer parameter
            doesn't specify either a constructor or an instance of a valid
            ValueTransformer subclass.
 **/
DC.registerTransformerWithName= function(valueTransformer, name)
{
    //  make certain it really is a value transformer
    if (!valueTransformer.transformedValue)
        throw new InvalidArgumentError( "The valueTransformer argument does not support the ValueTransformer method transformedValue" );

    name= name.toLowerCase();
    DC.transformerInstances[name]= valueTransformer;
}

/** Simple ValueTransformer that reverses the truth value of a key
 **/
DC.transformer.Not= Class.create(DC.ValueTransformer, {

    transformedValue: function(value)
    {
        return (value?false:true);
    },

    reverseTransformedValue: function(value)
    {
        return !!value;
    }

});

DC.registerTransformerWithName(new DC.transformer.Not(), "not");

/** ValueTransformer that returns true only for a particular value.
 **/
DC.transformer.Boolean= Class.create(DC.ValueTransformer, {

    constructor: function(trueValue, falseValue)
    {
        this.trueValue= trueValue;
        this.falseValue= falseValue;
    },

    transformedValue: function(value)
    {
        return (value==this.trueValue);
    },

    reverseTransformedValue: function(value)
    {
        return (value?this.trueValue:this.falseValue);
    }

});

/** ValueTransformer that returns true only for values matching a regex
 **/
DC.transformer.Matches= Class.create(DC.ValueTransformer, {

    constructor: function(trueRegex)
    {
        this.trueRegex= trueRegex;
    },

    transformedValue: function(value)
    {
        return this.trueRegex.test(value);
    }

});

/** A transformer that maps between two lists of values.
 **/
DC.transformer.Generic= Class.create(DC.ValueTransformer, {

    constructor: function(modelValues, displayValues)
    {
        this.modelValues= modelValues;
        this.displayValues= displayValues;
    },

    transformedValue: function(value)
    {
        var index= this.modelValues.indexOf(value);
        var novalue;

        if (-1==index)
            return novalue;
        else
            return this.displayValues[index];
    },

    reverseTransformedValue: function(value)
    {
        var index= this.displayValues.indexOf(value);
        var novalue;

        if (-1==index)
            return novalue;
        else
            return this.modelValues[index];
    }

});

DC.transformer.Truncated= Class.create(DC.ValueTransformer, {

    constructor: function(max)
    {
        this.max= max || 50;
    },

    ellipsis: String.fromCharCode(0x2026),

    transformedValue: function(value)
    {
        if (!value && 0!==value)
            return value;

        value= "" + value;
        var len= value.length;
        if (len<=this.max)
            return value;

        //  Perform the ellipsis trick
        var half= this.max/2-2;

        //  Have to use Unicode character rather than entity because otherwise this
        //  won't work as a text binding.
        return [value.substr(0, half), this.ellipsis, value.substr(len-half)].join(' ');
    }

});

DC.registerTransformerWithName(new DC.transformer.Truncated(50), "truncated");

DC.transformer.StringsToObjects= Class.create(DC.ValueTransformer, {

    constructor: function(key)
    {
        this.key= key||'string';
    },

    transformedValue: function(array)
    {
        //  not really an array
        if (!array || !array.map)
            return array;

        function makeObj(string)
        {
            var kvo= new DC.KVO();
            kvo[this.key]= string;
            return kvo;
        }
        return array.map(makeObj, this);
    },

    reverseTransformedValue: function(array)
    {
        if (!array || !array.map)
            return array;

        function makeString(obj)
        {
            return obj[this.key];
        }
        return array.map(makeString, this);
    }

});
DC.registerTransformerWithName(new DC.transformer.StringsToObjects('string'), 'StringsToObjects');

DC.transformer.FirstObject= Class.create(DC.ValueTransformer, {
    transformedValue: function(array) {
        if (DC.typeOf(array) == 'array') {
            return array[0];
        }

        return array;
    }
});

redpajama_set_name: RedPajamaGithub


text:
define(['marionette',
    'backbone',
    'modules/cell/collections/pdbcodes',
    'modules/cell/collections/analysed',

    'modules/cell/models/autoproc',
    'modules/cell/views/autoproc',
    'modules/cell/views/autoproc_years',

    'modules/cell/models/states',
    'modules/cell/views/states',

    'modules/cell/models/beamlines',
    'modules/cell/views/beamlines',

    'views/filter',
    'views/table',
    'utils/table',
    'utils',
    'templates/cell/pdbs.html',

    ], function(Marionette, Backbone, PDBCodes, Analysed, Autoproc, AutoprocPie, AutoprocBars, States, StatesPie, Beamlines, BeamlineBars, FilterView, TableView, table, utils, template) {

    return Marionette.LayoutView.extend({
        template: template,
        className: 'content',

        regions: {
            ana: '.analysed',
            ty: '.ty',
        },

        events: {
            'click @ui.proc': 'processPDBs',
            'click @ui.upd': 'updateAPP',
            'change @ui.dist': 'updateDiff',
            'click a.download': 'downloadData'
        },

        ui: {
            tol: 'input[name=tol]',
            proc: 'a.process',
            state: '.processing',
            app: '#aps',
            apb: '#apstats',
            dist: 'input[name=dist]',
            upd: 'a.update',

            sta: '#visit_pie',

            bl: '#pdbs',
            bl2: '#pdbs2',

            cd: '.celldiff',
        },

        updateDiff: function(e) {
            this.ui.cd.text(Math.sqrt(Math.pow(this.ui.dist.val(), 2)/3).toFixed(2))
            this.autoproc.fetch()
        },

        updateAPP: function(e) {
            e.preventDefault()
            this.autoproc.fetch()
        },

        downloadData: function(e) {
            e.preventDefault()
            var url = app.apiurl+this.autoproc.url()+'&download=1'
            utils.sign({
                url: url,
                callback: function(resp) {
                    window.location = url+'&token='+resp.token
                }
            })
        },

        initialize: function(options) {
            this.updateDiff = _.debounce(this.updateDiff, 100)

            this.analysed = new Analysed()
            this.analysed.fetch()

            this.types = new FilterView({
                url: false,
                collection: this.analysed,
                name: 't',
                filters: [
                    { id: 'match', name: 'Matched'},
                    { id: 'mismatch', name: 'Mismatch'},
                    { id: 'noresults', name: 'No Results'},
                    { id: 'nomatch', name: 'No Match'},
                ]
            })

            var columns = [
                { name: 'CODE', label: 'Code', cell: 'string', editable: false },
                { name: 'PDBDATE', label: 'Release Date', cell: 'string', editable: false },
                { name: 'PDBBEAMLINENAMESTRIPPED', label: 'PDB Bl', cell: 'string', editable: false },
                { name: 'BEAMLINEMATCHTEXT', label: 'Bl Match', cell: 'string', editable: false },
                { name: 'AUTHORMATCHTEXT', label: 'Author Match', cell: 'string', editable: false },
                { label: 'Nearest', cell: table.TemplateCell, editable: false, test: 'BEAMLINENAME', template: '<%-BEAMLINENAME%> (<%-DISTANCE%>)' },
                { name: 'BEAMLINES', label: 'Beamlines', cell: 'string', editable: false },
                { name: 'AUTOPROCCOUNT', label: 'Integrations', cell: 'string', editable: false },
                { name: 'STATUS', label: 'Status', cell: 'string', editable: false },
                { label: '', cell: table.TemplateCell, editable: false, template: '<a href="/cell/pdb/<%-CODE%>" class="button"> <a class="button" href="http://www.rcsb.org/pdb/explore/explore.do?structureId=<%-CODE%>">' },
            ]

            if (app.mobile()) {
                _.each([3,4,5,6,8], function(v) {
                    columns[v].renderable = false
                })
            }

            this.anatable = new TableView({ collection: this.analysed, columns: columns, tableClass: 'analysed', filter: 's', noPageUrl: true, noSearchUrl: true, loading: true, backgrid: { emptyText: 'No analysed PDBs found' } })

            var self = this
            this.autoproc = new Autoproc()
            this.autoproc.dist = function() {
                return self.ui.dist.val()
            }

            this.states = new States()
            this.states.fetch()

            this.beamlines = new Beamlines()
            this.beamlines.fetch()
        },

        onRender: function() {
            this.ana.show(this.anatable)
            this.ty.show(this.types)

            this.updateDiff()
            this.app = new AutoprocPie({ model: this.autoproc, el: this.ui.app })
            this.apb = new AutoprocBars({ model: this.autoproc, el: this.ui.apb })

            this.sta = new StatesPie({ model: this.states, el: this.ui.sta })

            this.bls = new BeamlineBars({ model: this.beamlines, el: this.ui.bl, second: true })
            this.bls2 = new BeamlineBars({ model: this.beamlines, el: this.ui.bl2 })
        },

        processPDBs: function(e) {
            e.preventDefault()

            this.ui.proc.hide()
            this.counts = { success: 0, fail: 0 }

            Backbone.ajax({
                url: app.apiurl+'/cell/rcsb',
                success: this.getProcessedPDBs.bind(this)
            })
        },

        getProcessedPDBs: function(pdbs) {
            this.pdbs = pdbs.split('\n')
            this.processed = new PDBCodes()
            this.processed.fetch({
                success: this.doProcessPDBs.bind(this)
            })
        },

        doProcessPDBs: function() {
            this.toprocess = _.difference(this.pdbs, this.processed.pluck('CODE')).reverse().slice(1)
            console.log(this.toprocess.length, this.pdbs.length, this.toprocess[0])
            this.processPDB(0)
        },

        processPDB: function(id) {
            if (id > this.toprocess.length) {
                this.ui.proc.show()
                return
            }

            this.ui.state.text(id+'/'+this.toprocess.length+' PDB files processed, '+this.counts.success+' successful, '+this.counts.fail+' failures')

            var p = this.toprocess[id]
            var self = this

            Backbone.ajax({
                url: app.apiurl+'/cell/pdb?pdb='+p,
                type: 'GET',
                dataType: 'xml',
                timeout: 5000,
                success: function(xml){
                    var data = { pdb: p }
                    $(xml).find('record').each(function(i,r) {
                        _.each({ a: 'lengthOfUnitCellLatticeA',
                                b: 'lengthOfUnitCellLatticeB',
                                c: 'lengthOfUnitCellLatticeC',
                                al: 'unitCellAngleAlpha',
                                be: 'unitCellAngleBeta',
                                ga: 'unitCellAngleGamma',
                               }, function(v, k) {
                            data[k] = $(r).find('dimStructure\\.'+v).text()
                        })

                        data['title'] = $(r).find('dimStructure\\.structureTitle').text()

                        // add 25% tolerance on resolution limit
                        data['res'] = $(r).find('dimStructure\\.resolution').text()*1.25

                        if ($(r).find('dimStructure\\.diffractionSource').text() != 'null') data['bl'] = $(r).find('dimStructure\\.diffractionSource').text()
                        if ($(r).find('dimStructure\\.structureAuthor').text() != 'null') data['author'] = $(r).find('dimStructure\\.structureAuthor').text()
                        data['year'] = $(r).find('dimStructure\\.releaseDate').text()
                    })

                    Backbone.ajax({
                        url: app.apiurl+'/cell/process',
                        type: 'POST',
                        data: data,
                        success: function(json){
                           self.counts.success++
                           self.processPDB(id+1)
                        },
                        error: function(xhr, status, error) {
                            console.log(xhr, status, error)
                            self.counts.fail++
                            self.processPDB(id+1)
                        }
                    })
                }
            })

        },

    })

})


text:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
?><!DOCTYPE html>

	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">

<?php $this->view('Login/header');?>

    <?php echo validation_errors(); ?>
    <?php echo form_open('/Login/register', array("id"=>"register")); ?>
    <?php
      if (isset($error) && $error != "") {
        echo "
$error.
";
      }
      if (isset($info) && $info != "") {
        echo "
$info";
      }
    ?>

        <input name="firstname" type="text" class="form-control" placeholder="First name">

        <input name="lastname" type="text" class="form-control" placeholder="Last name">

        <input name="email" type="email" class="form-control" placeholder="Email">

        <input name="password" type="password" class="form-control" placeholder="Password">

        <input name="confirmpassword" type="password" class="form-control" placeholder="Confirm password">

          <button type="submit" class="btn btn-primary btn-block btn-flat">Sign Up</button>

    </form>

I have already account.   Sign In.


text:
package com.jnape.palatable.lambda.functor.builtin;

import com.jnape.palatable.lambda.adt.Either;
import com.jnape.palatable.lambda.adt.Maybe;
import com.jnape.palatable.traitor.annotations.TestTraits;
import com.jnape.palatable.traitor.runners.Traits;
import org.junit.Test;
import org.junit.runner.RunWith;
import testsupport.traits.ApplicativeLaws;
import testsupport.traits.FunctorLaws;

import static com.jnape.palatable.lambda.adt.Either.left;
import static com.jnape.palatable.lambda.adt.Either.right;
import static com.jnape.palatable.lambda.adt.Maybe.just;
import static com.jnape.palatable.lambda.adt.Maybe.pureMaybe;
import static com.jnape.palatable.lambda.functor.builtin.Compose.pureCompose;
import static com.jnape.palatable.lambda.functor.builtin.Identity.pureIdentity;
import static com.jnape.palatable.lambda.functor.builtin.Lazy.lazy;
import static org.junit.Assert.assertEquals;

@RunWith(Traits.class)
public class ComposeTest {

    @TestTraits({FunctorLaws.class, ApplicativeLaws.class})
    public Compose<Identity<?>, Identity<?>, Integer> testSubject() {
        return new Compose<>(new Identity<>(new Identity<>(1)));
    }

    @Test
    public void inference() {
        Either<Object, Maybe<Integer>> a = new Compose<>(right(just(1))).fmap(x -> x + 1).getCompose();
        assertEquals(right(just(2)), a);
    }

    @Test
    public void lazyZip() {
        assertEquals(new Compose<>(right(just(2))),
                     new Compose<>(right(just(1))).lazyZip(lazy(new Compose<>(right(just(x -> x + 1))))).value());
        assertEquals(new Compose<>(left("foo")),
                     new Compose<>(left("foo")).lazyZip(lazy(() -> {
                         throw new AssertionError();
                     })).value());
    }

    @Test
    public void staticPure() {
        Compose<Identity<?>, Maybe<?>, Integer> compose = pureCompose(pureIdentity(), pureMaybe()).apply(1);
        assertEquals(new Compose<>(new Identity<>(just(1))), compose);
    }
}


text:
package net.snowflake.client.jdbc;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Types;
import java.util.Calendar;
import java.util.TimeZone;
import net.snowflake.client.AbstractDriverIT;
import net.snowflake.client.category.TestCategoryOthers;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;

/** Integration tests for binding variable */
@RunWith(Theories.class)
@Category(TestCategoryOthers.class)
public class BindingDataIT extends AbstractDriverIT {
  @DataPoints public static short[] shortValues = {0, 1, -1, Short.MIN_VALUE, Short.MAX_VALUE};

  @Theory
  public void testBindShort(short shortValue) throws SQLException {
    Connection connection = getConnection();
    Statement statement = connection.createStatement();
    statement.execute("create or replace table test_bind_short(c1 number)");

    PreparedStatement preparedStatement =
        connection.prepareStatement("insert into test_bind_short values (?)");
    preparedStatement.setShort(1, shortValue);
    assertEquals(1, preparedStatement.executeUpdate());

    preparedStatement = connection.prepareStatement("select * from test_bind_short where c1 = ?");
    preparedStatement.setShort(1, shortValue);

    ResultSet resultSet = preparedStatement.executeQuery();
    assertThat(resultSet.next(), is(true));
    assertThat(resultSet.getShort("C1"), is(shortValue));

    resultSet.close();
    preparedStatement.close();

    statement.execute("drop table if exists test_bind_short");
    connection.close();
  }

  @Theory
  public void testBindShortViaSetObject(short shortValue) throws SQLException {
    Connection connection = getConnection();
    Statement statement = connection.createStatement();
    statement.execute("create or replace table test_bind_short(c1 number)");

    PreparedStatement preparedStatement =
        connection.prepareStatement("insert into test_bind_short values (?)");
    preparedStatement.setObject(1, new Short(shortValue));
    preparedStatement.executeUpdate();

    preparedStatement = connection.prepareStatement("select * from test_bind_short where c1 = ?");
    preparedStatement.setObject(1, new Short(shortValue));

    ResultSet resultSet = preparedStatement.executeQuery();
    assertThat(resultSet.next(), is(true));
    assertThat(resultSet.getShort("C1"), is(shortValue));

    resultSet.close();
    preparedStatement.close();

    statement.execute("drop table if exists test_bind_short");
    connection.close();
  }

  @DataPoints public static int[] intValues = {0, 1, -1, Integer.MAX_VALUE, Integer.MIN_VALUE};

  @Theory
  public void testBindInt(int intValue) throws SQLException {
    Connection connection = getConnection();
    Statement statement = connection.createStatement();
    statement.execute("create or replace table test_bind_int(c1 number)");

    PreparedStatement preparedStatement =
        connection.prepareStatement("insert into test_bind_int values (?)");
    preparedStatement.setInt(1, intValue);
    preparedStatement.executeUpdate();

    preparedStatement = connection.prepareStatement("select * from test_bind_int where c1 = ?");
    preparedStatement.setInt(1, intValue);

    ResultSet resultSet = preparedStatement.executeQuery();
    assertThat(resultSet.next(), is(true));
    assertThat(resultSet.getInt("C1"), is(intValue));

    resultSet.close();
    preparedStatement.close();

    statement.execute("drop table if exists test_bind_int");
    connection.close();
  }

  @DataPoints public static byte[] byteValues = {0, 1, -1, Byte.MAX_VALUE, Byte.MIN_VALUE};

  @Theory
  public void testBindByte(byte byteValue) throws SQLException {
    Connection connection = getConnection();
    Statement statement = connection.createStatement();
    statement.execute("create or replace table test_bind_byte(c1 integer)");

    PreparedStatement preparedStatement =
        connection.prepareStatement("insert into test_bind_byte values (?)");
    preparedStatement.setByte(1, byteValue);
    preparedStatement.executeUpdate();

    preparedStatement = connection.prepareStatement("select * from test_bind_byte where c1 = ?");
    preparedStatement.setInt(1, byteValue);

    ResultSet resultSet = preparedStatement.executeQuery();
    assertThat(resultSet.next(), is(true));
    assertThat(resultSet.getByte("C1"), is(byteValue));

    resultSet.close();
    preparedStatement.close();

    statement.execute("drop table if exists test_bind_byte");
    connection.close();
  }

  @Test
  public void testBindNull() throws SQLException {
    Connection connection = getConnection();
    Statement statement = connection.createStatement();
    statement.execute("create or replace table test_bind_null(id number, val " + "number)");

    PreparedStatement preparedStatement =
        connection.prepareStatement("insert into test_bind_null values (?, ?)");
    preparedStatement.setInt(1, 0);
    preparedStatement.setBigDecimal(2, null);
    preparedStatement.addBatch();

    preparedStatement.setInt(1, 1);
    preparedStatement.setNull(1, Types.INTEGER);
    preparedStatement.addBatch();

    preparedStatement.setInt(1, 2);
    preparedStatement.setObject(1, null, Types.BIGINT);
    preparedStatement.addBatch();

    preparedStatement.setInt(1, 3);
    preparedStatement.setObject(1, null, Types.BIGINT, 0);
    preparedStatement.addBatch();

    preparedStatement.executeBatch();

    ResultSet rs = statement.executeQuery("select * from test_bind_null " + "order by id asc");
    int count = 0;
    while (rs.next()) {
      assertThat(rs.getBigDecimal("VAL"), is(nullValue()));
      count++;
    }

    assertThat(count, is(4));

    rs.close();
    preparedStatement.close();

    statement.execute("drop table if exists test_bind_null");
    connection.close();
  }

  @DataPoints
  public static Time[] timeValues = {
    Time.valueOf("00:00:00"),
    Time.valueOf("12:34:56"),
    Time.valueOf("12:00:00"),
    Time.valueOf("11:59:59"),
    Time.valueOf("15:30:00"),
    Time.valueOf("13:01:01"),
    Time.valueOf("12:00:00"),
  };

  @Theory
  public void testBindTime(Time timeVal) throws SQLException {
    Connection connection = getConnection();
    Statement statement = connection.createStatement();
    statement.execute("create or replace table test_bind_time(c1 time)");

    PreparedStatement preparedStatement =
        connection.prepareStatement("insert into test_bind_time values (?)");
    preparedStatement.setTime(1, timeVal);
    preparedStatement.executeUpdate();

    preparedStatement = connection.prepareStatement("select * from test_bind_time where c1 = ?");
    preparedStatement.setTime(1, timeVal);

    ResultSet resultSet = preparedStatement.executeQuery();
    assertThat(resultSet.next(), is(true));
    assertThat(resultSet.getTime("C1"), is(timeVal));

    resultSet.close();
    preparedStatement.close();

    statement.execute("drop table if exists test_bind_time");
    connection.close();
  }

  /**
   * Bind time with calendar is not supported now. Everything is in UTC, need to revisit in the
   * future
   */
  @Theory
  public void testBindTimeWithCalendar(Time timeVal) throws SQLException {
    Calendar utcCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
    Calendar laCal = Calendar.getInstance(TimeZone.getTimeZone("PST"));

    Connection connection = getConnection();
    Statement statement = connection.createStatement();
    statement.execute("create or replace table test_bind_time_calendar(c1 " + "time)");

    PreparedStatement preparedStatement =
        connection.prepareStatement("insert into test_bind_time_calendar values (?)");
    preparedStatement.setTime(1, timeVal, laCal);
    preparedStatement.executeUpdate();

    // bind time with UTC
    preparedStatement =
        connection.prepareStatement("select * from test_bind_time_calendar where c1 = ?");
    preparedStatement.setTime(1, timeVal, laCal);

    ResultSet resultSet = preparedStatement.executeQuery();
    assertThat(resultSet.next(), is(true));
    assertThat(resultSet.getTime("C1", utcCal), is(timeVal));

    resultSet.close();
    preparedStatement.close();

    statement.execute("drop table if exists test_bind_time_calendar");
    connection.close();
  }

  @Theory
  public void testBindTimeViaSetObject(Time timeVal) throws SQLException {
    Connection connection = getConnection();
    Statement statement = connection.createStatement();
    statement.execute("create or replace table test_bind_time(c1 time)");

    PreparedStatement preparedStatement =
        connection.prepareStatement("insert into test_bind_time values (?)");
    preparedStatement.setObject(1, timeVal, Types.TIME);
    preparedStatement.executeUpdate();

    preparedStatement = connection.prepareStatement("select * from test_bind_time where c1 = ?");
    preparedStatement.setObject(1, timeVal, Types.TIME);

    ResultSet resultSet = preparedStatement.executeQuery();
    assertThat(resultSet.next(), is(true));
    assertThat(resultSet.getTime("C1"), is(timeVal));

    resultSet.close();
    preparedStatement.close();

    statement.execute("drop table if exists test_bind_time");
    connection.close();
  }

  @Theory
  public void testBindTimeViaSetObjectCast(Time timeVal) throws SQLException {
    Connection connection = getConnection();
    Statement statement = connection.createStatement();
    statement.execute("create or replace table test_bind_time(c1 time)");

    PreparedStatement preparedStatement =
        connection.prepareStatement("insert into test_bind_time values (?)");
    preparedStatement.setObject(1, timeVal);
    preparedStatement.executeUpdate();

    preparedStatement = connection.prepareStatement("select * from test_bind_time where c1 = ?");
    preparedStatement.setObject(1, timeVal);

    ResultSet resultSet = preparedStatement.executeQuery();
    assertThat(resultSet.next(), is(true));
    assertThat(resultSet.getTime("C1"), is(timeVal));

    resultSet.close();
    preparedStatement.close();

    statement.execute("drop table if exists test_bind_time");
    connection.close();
  }

  @DataPoints
  public static Date[] dateValues = {
    Date.valueOf("2000-01-01"),
    Date.valueOf("3000-01-01"),
    Date.valueOf("1970-01-01"),
    Date.valueOf("1969-01-01"),
    Date.valueOf("1500-01-01"),
    Date.valueOf("1400-01-01"),
    Date.valueOf("1000-01-01")
  };

  @Theory
  public void testBindDate(Date dateValue) throws SQLException {
    Connection connection = getConnection();
    Statement statement = connection.createStatement();
    statement.execute("create or replace table test_bind_date(c1 date)");

    PreparedStatement preparedStatement =
        connection.prepareStatement("insert into test_bind_date values (?)");
    preparedStatement.setDate(1, dateValue);
    preparedStatement.executeUpdate();

    preparedStatement = connection.prepareStatement("select * from test_bind_date where c1 = ?");
    preparedStatement.setDate(1, dateValue);

    ResultSet resultSet = preparedStatement.executeQuery();
    assertThat(resultSet.next(), is(true));
    assertThat(resultSet.getDate("C1"), is(dateValue));

    resultSet.close();
    preparedStatement.close();

    statement.execute("drop table if exists test_bind_date");
    connection.close();
  }

  @Theory
  public void testBindDateWithCalendar(Date dateValue) throws SQLException {
    Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));

    Connection connection = getConnection();
    Statement statement = connection.createStatement();
    statement.execute("create or replace table test_bind_date(c1 date)");

    PreparedStatement preparedStatement =
        connection.prepareStatement("insert into test_bind_date values (?)");
    preparedStatement.setDate(1, dateValue, calendar);
    preparedStatement.executeUpdate();

    preparedStatement = connection.prepareStatement("select * from test_bind_date where c1 = ?");
    preparedStatement.setDate(1, dateValue, calendar);

    ResultSet resultSet = preparedStatement.executeQuery();
    assertThat(resultSet.next(), is(true));
    assertThat(resultSet.getDate("C1"), is(dateValue));

    resultSet.close();
    preparedStatement.close();

    statement.execute("drop table if exists test_bind_date");
    connection.close();
  }

  @Theory
  public void testBindObjectWithScaleZero(int intValue) throws SQLException {
    Connection connection = getConnection();
    Statement statement = connection.createStatement();
    statement.execute("create or replace table test_bind_object_0(c1 number)");

    PreparedStatement preparedStatement =
        connection.prepareStatement("insert into test_bind_object_0 values (?)");
    preparedStatement.setObject(1, intValue, Types.NUMERIC, 0);
    preparedStatement.executeUpdate();

    preparedStatement =
        connection.prepareStatement("select * from test_bind_object_0 where c1 = ?");
    preparedStatement.setObject(1, intValue, Types.NUMERIC, 0);

    ResultSet resultSet = preparedStatement.executeQuery();
    assertThat(resultSet.next(), is(true));
    assertThat(resultSet.getInt("C1"), is(intValue));

    resultSet.close();
    preparedStatement.close();

    statement.execute("drop table if exists test_bind_object_0");
    connection.close();
  }

  /** Binding null as all types. */
  @Test
  public void testBindNullForAllTypes() throws Throwable {
    try (Connection connection = getConnection()) {
      connection
          .createStatement()
          .execute(
              "create or replace table TEST_BIND_ALL_TYPES(C0 string,"
                  + "C1 number(20, 3), C2 INTEGER, C3 double, C4 varchar(1000),"
                  + "C5 string, C6 date, C7 time, C8 timestamp_ntz, "
                  + "C9 timestamp_ltz, C10 timestamp_tz,"
                  + "C11 BINARY, C12 BOOLEAN)");

      for (SnowflakeType.JavaSQLType t : SnowflakeType.JavaSQLType.ALL_TYPES) {
        PreparedStatement preparedStatement =
            connection.prepareStatement(
                "insert into TEST_BIND_ALL_TYPES values(?, ?,?,?, ?,?,?, ?,?,?, ?,?,?)");
        preparedStatement.setString(1, t.toString());
        for (int i = 2; i <= 13; ++i) {
          preparedStatement.setNull(i, t.getType());
        }
        preparedStatement.executeUpdate();
      }

      ResultSet result =
          connection.createStatement().executeQuery("select * from TEST_BIND_ALL_TYPES");
      while (result.next()) {
        String testType = result.getString(1);
        for (int i = 2; i <= 13; ++i) {
          assertNull(String.format("Java Type: %s is not null", testType), result.getString(i));
        }
      }
    }
  }
}


text:
package com.twu.biblioteca;

import com.twu.biblioteca.options.*;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
 * Created by gdias on 7/31/15.
 */
public class MenuTest {
    private Menu menu;

    @Before
    public void setUp() throws Exception {
        menu = new Menu();
    }

    @Test
    public void listOptions_ShouldReturnTheMenuOptions() throws Exception {
        assertEquals("1 - List resources\n2 - Checkout resource\n3 - Return resource\n4 - Log in\n5 - Verify book\n6 - My info\n7 - Quit", menu.listOptions());
    }

    @Test
    public void selectOption_ShouldReturnAListResourcesOption_WhenReceivesListBooksOptionNumber() throws Exception {
        assertTrue(menu.selectOption(MenuOptionsConsts.LIST_RESOURCES_OPTION_NUMBER) instanceof ListResourcesOption);
    }

    @Test
    public void selectOption_ShouldReturnAQuitOption_WhenReceivesQuitOptionNumber() throws Exception {
        assertTrue(menu.selectOption(MenuOptionsConsts.QUIT_OPTION_NUMBER) instanceof QuitOption);
    }

    @Test
    public void selectOption_ShouldReturnACheckoutOption_WhenReceivesCheckoutOptionNumber() throws Exception {
        assertTrue(menu.selectOption(MenuOptionsConsts.CHECKOUT_OPTION_NUMBER) instanceof CheckoutOption);
    }

    @Test
    public void selectOption_ShouldReturnAReturnBookOption_WhenReceivesReturnBookOptionNumber() throws Exception {
        assertTrue(menu.selectOption(MenuOptionsConsts.RETURN_BOOK_OPTION_NUMBER) instanceof ReturnResourceOption);
    }

    @Test
    public void selectOption_ShouldReturnAnInvalidOption_WhenReceivesAnInvalidOptionNumber() throws Exception {
        int invalidOptionNumber = 0;
        assertTrue(menu.selectOption(invalidOptionNumber) instanceof InvalidOption);
    }
}


text: log = loglevel.createPackageLogger('practicalmeteor:mocha-web-driver', 'info');


text:
**Note:** The original project name is "`HSpark`" which is requested to rename to the current name due to trade mark concerns by Apache foundation.

Apache HBase is a distributed Key-Value store of data on HDFS. It is modeled after Google's Big Table, and provides APIs to query the data. The data is organized, partitioned and distributed by its "row keys". Per partition, the data is further physically partitioned by "column families" that specify collections of "columns" of data. The data model is for wide and sparse tables where columns are dynamic and may well be sparse.

Although HBase is a very useful big data store, its access mechanism is very primitive and only through client-side APIs, Map/Reduce interfaces and interactive shells. SQL accesses to HBase data are available through Map/Reduce or interfaces mechanisms such as Apache Hive and Impala, or some "native" SQL technologies like Apache Phoenix. While the former is usually cheaper to implement and use, their latencies and efficiencies often cannot compare favorably with the latter and are often suitable only for offline analysis. The latter category, in contrast, often performs better and qualifies more as online engines; they are often on top of purpose-built execution engines.

Currently Spark supports queries against HBase data through HBase's Map/Reduce interface (i.e., TableInputFormat). Spark SQL supports use of Hive data, which theoretically should be able to support HBase data access, out-of-box, through HBase's Map/Reduce interface and therefore falls into the first category of the "SQL on HBase" technologies.

We believe, as a unified big data processing engine, Spark is in good position to provide better HBase support.

## Online Documentation

Online documentation is in the doc folder.

## Requirements

This version of 2.2.0 requires Spark 2.2.0.

## Building Spark HBase

Spark HBase is built using [Apache Maven](http://maven.apache.org/).

I. Clone the Heracles project from GitHub
```
$ git clone https://github.com/bomeng/Heracles.git
```
or
```
$ git clone git@github.com:bomeng/Heracles.git
```

II. Go to the root of the source tree
```
$ cd Heracles
```

III. Build the project
Build without testing
```
$ mvn -DskipTests clean install
```
Or, build with testing. It will run test suites against a HBase minicluster.
```
$ mvn clean install
```

## Coprocessor

Currently, HBase coprocessor is not supported in this release.

## Interactive Scala Shell

The shell will connect to a local HBase master. You need to configure the HBase's hbase-env.sh file under "conf" folder by adding hspark.jar to its classpath.

```
export HBASE_CLASSPATH=<path_to_hspark>/hspark-2.2.0.jar
```

You may need to set the JAVA_HOME in the hbase-env.sh as well. Follow the instruction of configuring HBase to its proper settings (e.g. hbase-site.xml etc), after that, you can start HBase by following command:

```
start-hbase.sh
```

Then, the easiest way to start using Spark HBase is through the Scala shell:
```
./bin/hbase-sql
```

## Python Shell

First, add the spark-hbase jar to the SPARK_CLASSPATH in the $SPARK_HOME/conf directory, as follows:
```
SPARK_CLASSPATH=$SPARK_CLASSPATH:/spark-hbase-root-dir/target/Heracles-2.2.0.jar
```
Then go to the spark-hbase installation directory and issue
```
./bin/pyspark-hbase
```
A successful message is as follows:
```
   You are using Heracles !!!
   HBaseSQLContext available as hsqlContext.
```
To run a python script, the PYTHONPATH environment should be set to the "python" directory of the Spark-HBase installation. For example,
```
export PYTHONPATH=/root-of-Heracles/python
```

Note that the shell commands are not included in the Zip file of the Spark release. They are for developers' use only for this version of 2.2.0. Instead, users can use "$SPARK_HOME/bin/spark-shell --packages Heracles/Heracles:2.2.0" for SQL shell or "$SPARK_HOME/bin/pyspark --packages Heracles/Heracles:2.2.0" for Pythin shell.

## Running Tests

Testing first requires [building Spark HBase](#building-spark-hbase). Once Spark HBase is built ...

Run all test suites from Maven:
```
mvn -Phbase,hadoop-2.4 test
```
Run a single test suite from Maven, for example:
```
mvn -Phbase,hadoop-2.4 test -DwildcardSuites=org.apache.spark.sql.hbase.BasicQueriesSuite
```
## IDE Setup

We use IntelliJ IDEA for Spark HBase development. You can get the community edition for free and install the JetBrains Scala plugin from Preferences > Plugins.

To import the current Spark HBase project for IntelliJ:

1. Download IntelliJ and install the Scala plug-in for IntelliJ. You may also need to install Maven plug-in for IntelliJ.
2. Go to "File -> Import Project", locate the Spark HBase source directory, and select "Maven Project".
3. In the Import Wizard, select "Import Maven projects automatically" and leave other settings at their default.
4. Make sure some specific profiles are enabled. Select corresponding Hadoop version, "maven3" and also "hbase" in order to get dependencies.
5. Leave other settings at their default and you should be able to start your development.
6. When you run the scala test, sometimes you will get out of memory exception. You can increase your VM memory usage by the following setting, for example:

```
-XX:MaxPermSize=512m -Xmx3072m
```

You can also make those setting to be the default by setting to the "Defaults -> ScalaTest".

## Configuration

Please refer to the [Configuration guide](http://spark.apache.org/docs/latest/configuration.html)
in the online documentation for an overview on how to configure Spark.

For HBase 1.2, it is recommended to use higher "open files" and "max user processes" ulimit values. A typical value is 65536(64K).


text:
package org.jboss.weld.tests.interceptors.exclusion;

import javax.enterprise.inject.spi.BeanManager;
import javax.inject.Inject;
import javax.interceptor.ExcludeClassInterceptors;
import javax.interceptor.Interceptors;

@Interceptors({ Interceptor1.class, Interceptor2.class })
public class InterceptedBean {

    @Inject
    @Interceptors(Interceptor2.class)
    @ExcludeClassInterceptors
    public InterceptedBean(BeanManager manager) {
    }

    @Interceptors(Interceptor2.class)
    @ExcludeClassInterceptors
    public void ping() {
    }

    public void pong() {
    }
}


text:
'use strict';
const visitIf = require('enhance-visitors').visitIf;
const createAvaRule = require('../create-ava-rule');

const create = context => {
	const ava = createAvaRule();

	return ava.merge({
		CallExpression: visitIf([
			ava.isInTestFile,
			ava.isTestNode
		])(node => {
			if (ava.hasTestModifier('todo')) {
				context.report({
					node,
					message: '`test.todo()` should be not be used.'
				});
			}
		})
	});
};

module.exports = {
	create,
	meta: {}
};


text:
ACCEPTED

#### According to
International Plant Names Index

#### Published in
null

#### Original name
Hiraea psilophylla A.Juss.

### Remarks
null


text:
project_path: /web/fundamentals/_project.yaml
book_path: /web/fundamentals/_book.yaml
description: Улучшение доступности для веб-страниц

{# wf_updated_on: 2019-06-08 #}
{# wf_published_on: 2016-06-26 #}

# Доступность {: .page-title }

{% include "web/_shared/contributors/megginkearney.html" %}
{% include "web/_shared/contributors/dgash.html" %}
{% include "web/_shared/contributors/aliceboxhall.html" %}
{% include "web/_shared/contributors/robdodson.html" %}

Этот набор документов – текстовая версия части материала, представленного в
[Курсе Udacity по
доступности](https://www.udacity.com/course/web-accessibility--ud891){: .external }.
Это не расшифровка видеокурса, а, скорее, более лаконичное изложение
принципов и приемов обеспечения доступности на основе  оригинальных
материалов курса.

### TL;DR {: .hide-from-toc }

Из этой статьи вы узнаете:
- что такое доступность и как она применяется к веб-разработке;
- как сделать веб-сайты доступными и полезными для всех;
- как обеспечить базовую доступность с минимальным влиянием на разработку;
- какие возможности HTML вам доступны, и как использовать их для улучшения доступности;
- продвинутые техники для обеспечения максимальной дотсупности.

Понимание доступности, её охвата и влияния может повысить вашу квалификацию
веб-разработчика. Это руководство предназначено помочь вам понять, как сделать
свой сайт доступней и полезней для всех.

Слово "доступность" бывает сложно написать без ошибок, но реализовать ее не
так сложно. В этом руководстве вам будут представлены некоторые простые
решения, которые помогут улучшить доступность с минимальными усилиями, будет
показано, как использовать встроенный функционал HTML для создания более
доступных и надежных интерфейсов, а также, как использовать некоторые
продвинутые техники для обеспечения максимальной доступности.

Вы также узнаете, что многие из этих техник помогут вам создавать интерфейсы,
более приятные и простые в использовании для *всех* пользователей, а не только
для людей с ограниченными возможностями.

Разумеется, множество разработчиков имеют лишь туманное представление о том,
что значит доступность (что-то связанное с государственными контрактами,
контрольными списками, и устройствами чтения с экрана, так?), и вокруг этого
понятия витает множество заблуждений. Например, многие разработчики считают,
что решение проблемы доступности заставит их выбирать между созданием
восхитительного и привлекательного интерфейса и чем-то неудобным и уродливым,
но доступным.

Это, конечно, не совсем так, так что давайте проясним это, прежде чем займёмся
чем-то еще. Что мы подразумеваем под доступностью, и чему мы здесь будем учиться?

## Что такое доступность?

В широком смысле, когда мы говорим, что сайт доступен, мы имеем ввиду, что
контент сайта доступен и его функционалом может воспользоваться буквально *кто
угодно*. Как разработчикам вам легко принять, что все пользователи могут видеть
и могут использовать клавиатуру, или мышь, или сенсорный экран, и могут
взаимодействовать с вашей страницей так же, как и вы. Это может привести к тому,
что все работает хорошо для одних людей, но создает проблемы, которые
варьируются от простых раздражений до блокирующих работу, для других.

Доступность относится к пользователям, которые могут выходить за рамки узкого
понятия "типичный" пользователь, к пользователяим, которые могут иметь доступ или
взаимодействовать с вещами не так, как вы ожидаете. В частности, это касается
пользователей, у которых имеются некоторые нарушения или инвалидность — и имейте
в виду, что это всё может быть нефизическим или временным.

Например, хотя мы и склонны сосредотачивать наше обсуждение доступности на
пользователях с физическими нарушениями, всем нам знаком опыт
использования интерфейса недоступного для нас по другим причинам. У вас
когда-нибудь были проблемы с использованием сайта на мобильном телефоне, или вы
видели сообщение "Этот контент недоступен в вашем регионе", или вы не могли
найти знакомое меню на планшете? Все это проблемы доступности.

Как станет ясно в дальнейшем, когда вы решаете проблемы доступности в этом, более
широком, более глобальном смысле, это почти всегда улучшает пользовательский
опыт для всех. Давайте взглянем на пример:

![a form with poor accessibility](imgs/pooraccess.jpg)

У этой формы несколько проблем с доступностью.

- Текст должен быть более контрастным, его сложно читать пользователям с плохим
  зрением.
- Расположение названий полей слева, а самих полей справа затрудняет ассоциацию
  их друг с другом, для многих людей, и делает практически невозможной для тех,
  кому требуется увеличение масштаба для использования страницы; представьте, что
  глядя на это на телефоне вам приходится панорамно передвигаться по странице,
  чтобы связать поля с названиеми.
- Надпись "Запомнить данные?" не связана с переключателем, так что вы должны
  коснуться или кликнуть только на маленький квадратик, вместо того, чтобы просто
  кликнуть на надпись; кроме того, у пользователей, использующих устройства чтения с
  экрана, могут быть проблемы с ассоциацией надписи и переключателя.

Теперь давайте взмахнем нашей волшебной палочкой доступности и посмотрим на эту
форму с уже исправленными проблемами.
Мы сделаем текст темнее, изменим дизайн так, чтобы названия полей
стали ближе к самим полям, и исправим надпись, связанную с переключателем так,
чтобы переключать его можно было нажатием на саму надпись.

![a form with improved accessibility](imgs/betteraccess.jpg)

Какой формой вы бы предпочли пользоваться? Если вы сказали "доступной версией",
значит вы на пути понимания основных предпосылок этого руководства. Часто,
что-то, что полностью блокирует несколько пользователей, так же представляет неудобство
для многих других, так что решая проблемы доступности вы улучшаете интерфейс для
всех.

## Рекомендации по доступности контента

В этом руководстве мы будем ссылаться на [Рекомендации по доступности контента
(РПДК) 2.0](https://www.w3.org/TR/WCAG20/){: .external }, набор инструкций и
практик собранных экспертами по доступности, чтобы решить что значит
"доступность" методическим путем.

РПДК организована вокруг четырёх принципов, часто обозначаемых акронимом *ВУПН*:

- **Воспринимаемый**: Могут ли пользователи воспринимать контент? Необходимо
помнить, что только потому, что что-то воспринимается только одним чувством,
таким как зрение, не значит что все пользователи могут воспринимать это.

- **Управляемый**: Могут ли пользователи использовать компоненты
пользовательского интерфейса и перемещаться по содержимому? Например, что-то что
требует взаимодействия при наведения не может управляться кем-то, кто не может
использовать мышь или сенсорный экран.

- **Понятный**: Могут ли пользователи понять содержимое? Могут ли пользователи
понять интерфейс  и достаточно ли он последователен, чтобы избежать путаницы?

- **Надежный**: Может ли контент использоваться различными агентами
пользователей (браузерами)? Он работает с ассистивной технологией?

Хотя РПДК обеспечивает всесторонний обзор того, что значит доступный контент,
это так же может быть немного подавляюще. Чтобы помочь смягчить это,
[WebAIM](https://webaim.org/){: .external } (Web Accessibility in Mind) группа
переработала руководства РПДК в простой перечень, специально предназначенный для
веб-контента.

[WebAIM перечень](https://webaim.org/standards/wcag/checklist){: .external }
может дать вам короткое, высокоуровневое резюме того, что вам нужно реализовать,
а также ссылаться на базовую спецификацию РПДК, если вам требуется расширенное
определение.

С этим инструментом в руках, вы можете наметить направление вашей работы по
доступности и быть уверенным, что если ваш проект соответствует описанным
критериям, ваши пользователи будут иметь положительный опыт доступа к вашему
контенту.

## Понимание разнообразия пользователей

При изучении доступности может помочь понимание разнообразия пользователей в
мире и видов специальных возможностей, которые их затрагивают. Для объяснения
дальнейшего, ниже представлено интервью с Victor Tsaran -
полностью слепым Technical Program Manager в Google.

Victor Tsaran

> *Над чем вы работаете в Google?*

В Google моя работа состоит в том, чтобы помочь гарантировать, что наши
продукты работают для всех наших разнообразных пользователей, независимо от
нарушений или способностей.

> *Какие нарушения бывают у пользователей?*

Когда мы говорим о видах нарушений, которые могут привести кого-нибудь к
сложностям в доступе к нашему контенту, большинство людей сразу же представят
слепого пользователя, типа меня. И это правда, такое нарушение действительно
может сделать разочаровывающим или даже невозможным использование множества
веб-сайтов.

Много современных веб-технологий имеют печальный побочный эффект создания
сайтов, которые не работают хорошо с инструментами, используемыми слепыми
пользователя для доступа к вебу. Тем не менее, доступность на самом деле больше,
чем это. Мы считаем полезным думать о нарушениях, попадающих в четыре больших
корзины: зрительные, двигательные, слуховые и когнитивные.

> *Давайте пройдемся по ним по очереди. Можете привести пару примеров зрительных
нарушений?*

Зрительные нарушения могут быть разделены на две категории: Пользователи без
зрения, как я, могут использовать устройства чтения с экрана, шрифт Брайля, или
их комбинацию.

Устройство чтения Брайля

На самом деле, полное отстутсвие зрения встречается довольно редко, но все же, есть
хороший шанс, что вы знакомы или встречали хотя бы одного человека, который не
может видеть вообще. При этом существует огромное количество тех, кого мы называем
слабовидящие пользователи.

Это широкий диапазон, от кого-то, вроде моей жены, у кого нет роговиц, так что,
хотя она в принципе различает очертания вещей, читает она с трудом, и юридически
считатется слепой, до тех, у кого просто может быть плохое зрение и им нужно
носить очень сильные очки.

Это действительно огромный диапазон, так что, естесственно, существует большой
выбор приспособлений, которые люди в этой категории используют: кто-то
использует устройства чтения с экрана или дисплей Брайля (Я даже слышал об одной
женщине, которая читает шрифт Брайля с экрана, потому что его легче увидеть, чем
обычный текст), или они могут использовать технологию "текст-в-речь" без
полноценного использования устройств чтения с экрана, или они могут использовать
экранную лупу, для увеличения части экрана, или они могут просто использовать
браузерное увеличение, чтобы сделать шрифт больше. Они так же могут использовать
режим высокой контрастности, как режим операционной системы, как расширение для
браузера, или как высоконтрастную тему для веб-сайта.

Режим высокой контрастности

Множество пользователей пользуются комбинацией этих решений, как моя подруга
Laura, которая использует комбинацию высоконтрастного режима, браузерного
масштабирования и "текст-в-речь".

Ощущение слабого зрения знакомо множеству людей. Во-первых, у всех нас
ухудшается зрение по мере старения, так что даже если у вас самих нет проблем
со зрением, вы могли слышать о подобных проблемах от своих
родителей. Но многим знакомо неприятное ощущуние, когда достаешь ноутбук у залитого
солнцем окна и неожиданно понимаешь, что ничего не можешь прочитать! Или
кто-то, кто перенес лазерную операцию или, может быть просто хочет прочитать
что-то на другом конце комнаты, возможно, воспользуется одним из
приспособлений, о которых я упоминал. Поэтому я думаю, что разработчикам
довольно легко сопереживать пользователям со слабым зрением.

О, и нельзя не упомянуть людей с нарушениями восприятия цвета – около
9% мужчин имеют некую форму нарушения цветового восприятия! Плюс около 1%
женщин. Они могут испытывать проблемы с различением красного от зеленого
или желтого от синего. Подумайте об этом в следующий раз, при проектировании
валидации формы.

> *А как насчет нарушений моторики?*

Да, нарушения моторики или нарушения ловкости. Эта группа варьируется от тех,
кто предпочел бы не использовать мышь, так как у них, возможно, какой-то вид RSI
или что-то вроде и такое использование болезненно, до кого-то, кто может быть
физически парализован и ограничен в движении определённых частей тела.

Устройство отслеживания глаз

Ограниченные в движении пользователи могут пользоваться
клавиатурой, переключателем, голосовым управление, или даже устройством,
отслеживающим глаза, для взаимодействия с их компьютером.

Подобно нарушениям зрения, подвижность также может быть временной или
ситуативной: может быть вы сломали запястье, на той руке, которой держите мышь.
Может быть трекпад сломан на вашем ноутбуке или вы просто едете на шатающемся
поезде.
Существует множество ситуаций где подвижность пользователя затруднена и,
убедившись, что мы обслуживаем их, мы улучшаем опыт в целом: как для людей с
постоянными нарушениями, так и для тех, кто временно не может пользоваться
интерфейсами на основе указателя.

> *Отлично, давайте поговорим о нарушениях слуха.*

Эта группа может варьироваться от глухих до слабослышащих. И так же, как и
зрение, наш слух ухудшается с возрастом. Многие из нас используют общие средства
для помощи, такие как слуховые аппараты.

Субтитры

Для слабослышащих пользователей, мы должны быть уверены, что мы не полагаемся на
звук, поэтому обязательно используйте такие вещи как субтитры и транскрипции, и
предоставляйте какую-то альтернативу, если звук является частью интерфейса.

И также, как было со зрительными и двигательными нарушениями, очень просто
представить что кто-то, чьи уши работают нормально также выиграет от этих
улучшений. Много моих друзей говорят, что им нравится, когда у видео есть
субтитры и транскрипции, потому что это значит, что если они находятся в
открытом офисе и не принесли свои наушники, они все равно смогут смотреть видео!

> *Хорошо, можете рассказать немного о когнитивных нарушениях?*

Существует целый ряд когнитивных состояний, таких как СДВГ, дислексия и аутизм,
которые могут значить, что люди хотят или нуждаются в других способах доступа к информации-другому. Приспособления для этих групп, естественно, чрезвычайно
разнообразны, но мы определенно нашли некоторое пересечение с другими областями,
такими как использование функции масштабирования, чтобы сделать чтение и
концентрацию легче. Также, эти пользователи могут обнаружить, что действительно
минималистичный дизайн воспринимается лучше всего, потому что это сводит к
минимуму отвлечение и когнитивную нагрузку.

Я думаю стресс умственной перегрузки может коснуться каждого, так что это
очевидно что, если мы создаём что-то, что работает хорошо для кого-то с
когнитивным расстройством, мы создаем что-то, что будет приятным для всех.

> *Итак, как бы вы резюмировали, как вы думаете о доступности?*

Если вы посмотрите на широкий спектр возможностей и инвалидностей, которые могут
быть у людей, вы увидите, что проектирование и создание продуктов только
для людей с превосходным зрением, слухом, подвижностью и восприятием окажется
невероятно узким. Это почти самоуничтожение, так как мы создаем более стрессовые
и менее удобные интерфейсы для всех, а для некоторых пользователей создаем опыт,
который на самом деле полностью исключает их.

В этом интервью Виктор определил ряд нарушений и разместил их в четыре широких
категории: *зрительные*, *двигательные*, *слуховые*, и *когнитивные*. Он также
указал, что каждый тип нарушений может быть *ситуационным*, *временным*, или
*постоянным*.

Давайте взглянем на несколько примеров нарушений доступа из реальной жизни и
посмотрим как они попадают в эти категории и типы. Обратите внимание что
некоторые нарушения могут попадать больше чем в одну категорию или тип.

    Ситуативные
    Временные
    Постоянные

    Зрительные

    сотрясение мозга
    слепота

    Двигательные
    ребенок на руках
    сломанная рука, RSI*
    RSI*

    Слуховые
    шумный офис

    Когнитивные

    сотрясение мозга

*Repetitive Strain Injury*: напрмер, кистевой туннельный синдром, теннисный
локоть, курковый палец

## Следующие шаги

Мы изучили уже довольно много! Вы прочитали

- о том, что такое доступность и почему она важна для всех
- о РПДК и WebAIM перечне доступности
- о различных типах нарушений, которые вы должны учитывать

В оставшейся части руководства мы окунемся в практические аспекты создания
доступных веб-сайтов. Мы организуем эту работу вокруг трех основных предметных
областей:

- [**Фокус**](/web/fundamentals/accessibility/focus): Мы посмотрим как создавать
вещи, которыми можно управлять с клавиатуры вместо мыши. Это конечно важно для
пользователей с нарушениями моторики, но это также гарантирует, что ваш
интерфейс хорошо работает для всех пользователей.

- [**Семантика**](/web/fundamentals/accessibility/semantics-builtin): Мы
позаботимся о том, чтобы наш интерфейс надежно работал с различными
вспомогательными технологиями.

- [**Стилизация**](/web/fundamentals/accessibility/accessible-styles): Мы
рассмотрим дизайн и некоторые приемы, позволяющие сделать визуальные элементы
интерфейса максимально гибкими и удобными.

Каждая из этих тем может занять целый курс, так что мы не будем рассматривать
каждый аспект создания доступных веб-сайтов. Однако, мы дадим вам достаточно
информации, чтобы начать, и укажем вам на несколько хороших мест, где вы сможете
узнать больше о каждой теме.

Translated by
{% include "web/_shared/contributors/dmitryskripunov.html" %}


text:
package com.evolveum.midpoint.common.refinery;

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

import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismPropertyDefinition;
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.delta.PropertyDelta;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.schema.processor.ObjectClassComplexTypeDefinition;
import com.evolveum.midpoint.schema.processor.ResourceAttribute;
import com.evolveum.midpoint.schema.processor.ResourceAttributeContainerDefinition;
import com.evolveum.midpoint.schema.processor.ResourceAttributeDefinition;
import com.evolveum.midpoint.util.DebugUtil;
import com.evolveum.midpoint.util.DisplayableValue;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AttributeFetchStrategyType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.LayerType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType;

/**
 * @author semancik
 *
 */
public class LayerRefinedAttributeDefinition<T> extends RefinedAttributeDefinition<T> {

	private RefinedAttributeDefinition<T> refinedAttributeDefinition;
	private LayerType layer;
	private Boolean overrideCanRead = null;
	private Boolean overrideCanAdd = null;
	private Boolean overrideCanModify = null;

	private LayerRefinedAttributeDefinition(RefinedAttributeDefinition<T> refinedAttributeDefinition, LayerType layer) {
		super(refinedAttributeDefinition, refinedAttributeDefinition.getPrismContext());
		this.refinedAttributeDefinition = refinedAttributeDefinition;
		this.layer = layer;
	}

	static <T> LayerRefinedAttributeDefinition<T> wrap(RefinedAttributeDefinition<T> rAttrDef, LayerType layer) {
		if (rAttrDef == null) {
			return null;
		}
		return new LayerRefinedAttributeDefinition<T>(rAttrDef, layer);
	}

	static List<LayerRefinedAttributeDefinition<?>> wrapCollection(
			Collection<? extends ItemDefinition> defs, LayerType layer) {
		List outs = new ArrayList<LayerRefinedAttributeDefinition<?>>(defs.size());
		for (ItemDefinition itemDef: defs) {
            if (itemDef instanceof LayerRefinedAttributeDefinition) {
                outs.add(itemDef);
            } else if (itemDef instanceof RefinedAttributeDefinition) {
                outs.add(wrap((RefinedAttributeDefinition)itemDef, layer));
            } else {
                throw new IllegalStateException("Unexpected type of attribute definition: " + itemDef);
            }
		}
		return outs;
	}

	public LayerType getLayer() {
		return layer;
	}

	@Override
	public ResourceAttribute<T> instantiate() {
		return refinedAttributeDefinition.instantiate();
	}

	@Override
	public ResourceAttribute<T> instantiate(QName name) {
		return refinedAttributeDefinition.instantiate(name);
	}

	@Override
	public boolean isIdentifier(ResourceAttributeContainerDefinition objectDefinition) {
		return refinedAttributeDefinition.isIdentifier(objectDefinition);
	}

	@Override
	public boolean isIdentifier(ObjectClassComplexTypeDefinition objectDefinition) {
		return refinedAttributeDefinition.isIdentifier(objectDefinition);
	}

	@Override
	public void setNativeAttributeName(String nativeAttributeName) {
		refinedAttributeDefinition.setNativeAttributeName(nativeAttributeName);
	}

	@Override
	public boolean isSecondaryIdentifier(ObjectClassComplexTypeDefinition objectDefinition) {
		return refinedAttributeDefinition.isSecondaryIdentifier(objectDefinition);
	}

	@Override
	public boolean isTolerant() {
		return refinedAttributeDefinition.isTolerant();
	}

	@Override
	public void setTolerant(boolean tolerant) {
		refinedAttributeDefinition.setTolerant(tolerant);
	}

	public Boolean getOverrideCanRead() {
		return overrideCanRead;
	}

	public void setOverrideCanRead(Boolean overrideCanRead) {
		this.overrideCanRead = overrideCanRead;
	}

	public Boolean getOverrideCanAdd() {
		return overrideCanAdd;
	}

	public void setOverrideCanAdd(Boolean overrideCanAdd) {
		this.overrideCanAdd = overrideCanAdd;
	}

	public Boolean getOverrideCanModify() {
		return overrideCanModify;
	}

	public void setOverrideCanModify(Boolean overrideCanModify) {
		this.overrideCanModify = overrideCanModify;
	}

	@Override
	public boolean canAdd() {
		if (overrideCanAdd != null) {
			return overrideCanAdd;
		}
		return refinedAttributeDefinition.canAdd(layer);
	}

	@Override
	public boolean canAdd(LayerType layer) {
		return refinedAttributeDefinition.canAdd(layer);
	}

	@Override
	public boolean canRead() {
		if (overrideCanRead != null) {
			return overrideCanRead;
		}
		return refinedAttributeDefinition.canRead(layer);
	}

	@Override
	public boolean canRead(LayerType layer) {
		return refinedAttributeDefinition.canRead(layer);
	}

	@Override
	public boolean canModify() {
		if (overrideCanModify != null) {
			return overrideCanModify;
		}
		return refinedAttributeDefinition.canModify(layer);
	}

	@Override
	public void setName(QName name) {
		refinedAttributeDefinition.setName(name);
	}

	@Override
	public boolean canModify(LayerType layer) {
		return refinedAttributeDefinition.canModify(layer);
	}

	@Override
	public void setReadOnly() {
		refinedAttributeDefinition.setReadOnly();
	}

	@Override
	public void setTypeName(QName typeName) {
		refinedAttributeDefinition.setTypeName(typeName);
	}

	@Override
	public QName getValueType() {
		return refinedAttributeDefinition.getValueType();
	}

	@Override
	public String getNamespace() {
		return refinedAttributeDefinition.getNamespace();
	}

	@Override
	public Boolean isIndexed() {
		return refinedAttributeDefinition.isIndexed();
	}

	@Override
	public void setMinOccurs(int minOccurs) {
		refinedAttributeDefinition.setMinOccurs(minOccurs);
	}

	@Override
	public void setMaxOccurs(int maxOccurs) {
		refinedAttributeDefinition.setMaxOccurs(maxOccurs);
	}

	@Override
	public void setCanRead(boolean read) {
		refinedAttributeDefinition.setCanRead(read);
	}

	@Override
	public void setCanModify(boolean update) {
		refinedAttributeDefinition.setCanModify(update);
	}

	@Override
	public void setIndexed(Boolean indexed) {
		refinedAttributeDefinition.setIndexed(indexed);
	}

	@Override
	public Integer getDisplayOrder() {
		return refinedAttributeDefinition.getDisplayOrder();
	}

	@Override
	public boolean isSingleValue() {
		return refinedAttributeDefinition.isSingleValue(layer);
	}

	@Override
	public void setCanAdd(boolean create) {
		refinedAttributeDefinition.setCanAdd(create);
	}

	@Override
	public PropertyDelta<T> createEmptyDelta(ItemPath path) {
		return refinedAttributeDefinition.createEmptyDelta(path);
	}

	@Override
	public boolean isMultiValue() {
		return refinedAttributeDefinition.isMultiValue(layer);
	}

	@Override
	public boolean isIgnored() {
		return refinedAttributeDefinition.isIgnored(layer);
	}

	@Override
	public boolean isIgnored(LayerType layer) {
		return refinedAttributeDefinition.isIgnored(layer);
	}

	@Override
	public void setDisplayOrder(Integer displayOrder) {
		refinedAttributeDefinition.setDisplayOrder(displayOrder);
	}

	@Override
	public boolean isMandatory() {
		return refinedAttributeDefinition.isMandatory(layer);
	}

	@Override
	public void setIgnored(boolean ignored) {
		refinedAttributeDefinition.setIgnored(ignored);
	}

	@Override
	public boolean isOptional() {
		return refinedAttributeDefinition.isOptional(layer);
	}

	@Override
	public void setHelp(String help) {
		refinedAttributeDefinition.setHelp(help);
	}

	@Override
	public String getDisplayName() {
		return refinedAttributeDefinition.getDisplayName();
	}

	@Override
	public boolean isDynamic() {
		return refinedAttributeDefinition.isDynamic();
	}

	@Override
	public void setDisplayName(String displayName) {
		refinedAttributeDefinition.setDisplayName(displayName);
	}

	@Override
	public String getDescription() {
		return refinedAttributeDefinition.getDescription();
	}

	@Override
	public PrismContext getPrismContext() {
		return refinedAttributeDefinition.getPrismContext();
	}

	@Override
	public void setDescription(String description) {
		refinedAttributeDefinition.setDescription(description);
	}

	@Override
	public Class<T> getTypeClass() {
		return refinedAttributeDefinition.getTypeClass();
	}

	@Override
	public ResourceAttributeDefinition<T> getAttributeDefinition() {
		return refinedAttributeDefinition.getAttributeDefinition();
	}

	@Override
	public void setAttributeDefinition(ResourceAttributeDefinition<T> attributeDefinition) {
		refinedAttributeDefinition.setAttributeDefinition(attributeDefinition);
	}

	@Override
	public void setDynamic(boolean dynamic) {
		refinedAttributeDefinition.setDynamic(dynamic);
	}

	@Override
	public boolean isValidFor(QName elementQName, Class clazz) {
		return isValidFor(elementQName, clazz, false);
	}

	@Override
	public boolean isValidFor(QName elementQName, Class clazz, boolean caseInsensitive) {
		return refinedAttributeDefinition.isValidFor(elementQName, clazz, caseInsensitive);
	}

	public Boolean getReturnedByDefault() {
		return refinedAttributeDefinition.getReturnedByDefault();
	}

	public boolean isAbstract() {
		return refinedAttributeDefinition.isAbstract();
	}

	public boolean isDeprecated() {
		return refinedAttributeDefinition.isDeprecated();
	}

	public boolean isOperational() {
		return refinedAttributeDefinition.isOperational();
	}

	public String getDocumentation() {
		return refinedAttributeDefinition.getDocumentation();
	}

	public String getDocumentationPreview() {
		return refinedAttributeDefinition.getDocumentationPreview();
	}

	public boolean isRuntimeSchema() {
		return refinedAttributeDefinition.isRuntimeSchema();
	}

	public boolean isReturnedByDefault() {
		return refinedAttributeDefinition.isReturnedByDefault();
	}

	public String getDocClassName() {
		return refinedAttributeDefinition.getDocClassName();
	}

	public boolean isExlusiveStrong() {
		return refinedAttributeDefinition.isExlusiveStrong();
	}

	public boolean isSecondaryIdentifier() {
		return refinedAttributeDefinition.isSecondaryIdentifier();
	}

	public boolean isInherited() {
		return refinedAttributeDefinition.isInherited();
	}

	public boolean isVolatilityTrigger() {
		return refinedAttributeDefinition.isVolatilityTrigger();
	}

	public boolean isDisplayNameAttribute() {
		return refinedAttributeDefinition.isDisplayNameAttribute();
	}

	public AttributeFetchStrategyType getFetchStrategy() {
		return refinedAttributeDefinition.getFetchStrategy();
	}

	public List<String> getTolerantValuePattern() {
		return refinedAttributeDefinition.getTolerantValuePattern();
	}

	public List<String> getIntolerantValuePattern() {
		return refinedAttributeDefinition.getIntolerantValuePattern();
	}

	@Override
	public MappingType getOutboundMappingType() {
		return refinedAttributeDefinition.getOutboundMappingType();
	}

	@Override
	public void setOutboundMappingType(MappingType outboundMappingType) {
		refinedAttributeDefinition.setOutboundMappingType(outboundMappingType);
	}

	@Override
	public boolean hasOutboundMapping() {
		return refinedAttributeDefinition.hasOutboundMapping();
	}

	@Override
	public List<MappingType> getInboundMappingTypes() {
		return refinedAttributeDefinition.getInboundMappingTypes();
	}

	@Override
	public void setInboundMappingTypes(List<MappingType> inboundAssignmentTypes) {
		refinedAttributeDefinition.setInboundMappingTypes(inboundAssignmentTypes);
	}

	@Override
	public QName getName() {
		return refinedAttributeDefinition.getName();
	}

	@Override
	public QName getTypeName() {
		return refinedAttributeDefinition.getTypeName();
	}

	@Override
	public String getNativeAttributeName() {
		return refinedAttributeDefinition.getNativeAttributeName();
	}

	@Override
	public Collection<? extends DisplayableValue<T>> getAllowedValues() {
		return refinedAttributeDefinition.getAllowedValues();
	}

	@Override
	public int getMaxOccurs() {
		return refinedAttributeDefinition.getMaxOccurs(layer);
	}

	@Override
	public int getMaxOccurs(LayerType layer) {
		return refinedAttributeDefinition.getMaxOccurs(layer);
	}

	@Override
	public int getMinOccurs() {
		return refinedAttributeDefinition.getMinOccurs(layer);
	}

	@Override
	public int getMinOccurs(LayerType layer) {
		return refinedAttributeDefinition.getMinOccurs(layer);
	}

	@Override
	public PropertyLimitations getLimitations(LayerType layer) {
		return refinedAttributeDefinition.getLimitations(layer);
	}

	public PropertyLimitations getLimitations() {
		return refinedAttributeDefinition.getLimitations(layer);
	}

	@Override
	public String getHelp() {
		return refinedAttributeDefinition.getHelp();
	}

	public QName getMatchingRuleQName() {
		return refinedAttributeDefinition.getMatchingRuleQName();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + ((layer == null) ? 0 : layer.hashCode());
		result = prime * result + ((refinedAttributeDefinition == null) ? 0 : refinedAttributeDefinition.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		LayerRefinedAttributeDefinition other = (LayerRefinedAttributeDefinition) obj;
		if (layer != other.layer)
			return false;
		if (refinedAttributeDefinition == null) {
			if (other.refinedAttributeDefinition != null)
				return false;
		} else if (!refinedAttributeDefinition.equals(other.refinedAttributeDefinition))
			return false;
		return true;
	}

	@Override
	public String debugDump() {
		return debugDump(0);
	}

	@Override
	public String debugDump(int indent) {
		StringBuilder sb = new StringBuilder();
		DebugUtil.indentDebugDump(sb, indent);
		sb.append(getDebugDumpClassName()).append("(layer=").append(layer).append(",\n");
		sb.append(refinedAttributeDefinition.debugDump(indent+1, layer));
		return sb.toString();
	}

	/**
     * Return a human readable name of this class suitable for logs.
     */
    @Override
    protected String getDebugDumpClassName() {
        return "LRRAD";
    }

}