text:
// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.firebase.firestore;

import static com.google.common.truth.Truth.assertThat;
import static com.google.firebase.firestore.testutil.IntegrationTestUtil.testDocument;
import static com.google.firebase.firestore.testutil.IntegrationTestUtil.waitFor;
import static com.google.firebase.firestore.testutil.IntegrationTestUtil.waitForException;
import static com.google.firebase.firestore.testutil.TestUtil.map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.gms.tasks.Task;
import com.google.firebase.Timestamp;
import com.google.firebase.firestore.DocumentSnapshot.ServerTimestampBehavior;
import com.google.firebase.firestore.FirebaseFirestoreException.Code;
import com.google.firebase.firestore.testutil.EventAccumulator;
import com.google.firebase.firestore.testutil.IntegrationTestUtil;
import java.util.Map;
import javax.annotation.Nullable;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AndroidJUnit4.class)
public class ServerTimestampTest {

  // Data written in tests via set.
  private static final Map<String, Object> setData =
      map(
          "a",
          42L,
          "when",
          FieldValue.serverTimestamp(),
          "deep",
          map("when", FieldValue.serverTimestamp()));

  // Base and update data used for update tests.
  private static final Map<String, Object> initialData = map("a", 42L);
  private static final Map<String, Object> updateData =
      map("when", FieldValue.serverTimestamp(), "deep", map("when", FieldValue.serverTimestamp()));

  // A document reference to read and write to.
  private DocumentReference docRef;

  // Accumulator used to capture events during the test.
  private EventAccumulator<DocumentSnapshot> accumulator;

  // Listener registration for a listener maintained during the course of the test.
  private ListenerRegistration listenerRegistration;

  @Before
  public void setUp() {
    docRef = testDocument();
    accumulator = new EventAccumulator<>();
    listenerRegistration =
        docRef.addSnapshotListener(MetadataChanges.INCLUDE, accumulator.listener());

    // Wait for initial null snapshot to avoid potential races.
    DocumentSnapshot initialSnapshot = accumulator.await();
    assertFalse(initialSnapshot.exists());
  }

  @After
  public void tearDown() {
    listenerRegistration.remove();
    IntegrationTestUtil.tearDown();
  }

  // Returns the expected data, with an arbitrary timestamp substituted in.
  private Map<String, Object> expectedDataWithTimestamp(Object timestamp) {
    return map("a", 42L, "when", timestamp, "deep", map("when", timestamp));
  }

  /** Writes initialData and waits for the corresponding snapshot. */
  private void writeInitialData() {
    waitFor(docRef.set(initialData));
    DocumentSnapshot initialDataSnap = accumulator.await();
    assertEquals(initialData, initialDataSnap.getData());
    initialDataSnap = accumulator.await();
    assertEquals(initialData, initialDataSnap.getData());
  }

  /** Verifies a snapshot containing setData but with null for the timestamps. */
  private void verifyTimestampsAreNull(DocumentSnapshot snapshot) {
    assertEquals(expectedDataWithTimestamp(null), snapshot.getData());
  }

  /** Verifies a snapshot containing setData but with resolved server timestamps. */
  private void verifyTimestampsAreResolved(DocumentSnapshot snapshot) {
    assertTrue(snapshot.exists());
    Timestamp when = snapshot.getTimestamp("when");
    assertNotNull(when);
    // Tolerate up to 48*60*60 seconds of clock skew between client and server. This should be more
    // than enough to compensate for timezone issues (even after taking daylight saving into
    // account) and should allow local clocks to deviate from true time slightly and still pass the
    // test.
    int deltaSec = 48 * 60 * 60;
    Timestamp now = Timestamp.now();
    assertTrue(
        "resolved timestamp (" + when + ") should be within " + deltaSec + "s of now (" + now + ")",
        Math.abs(when.getSeconds() - now.getSeconds()) < deltaSec);

    // Validate the rest of the document.
    assertEquals(expectedDataWithTimestamp(when), snapshot.getData());
  }

  /** Verifies a snapshot containing setData but with local estimates for server timestamps. */
  private void verifyTimestampsAreEstimates(DocumentSnapshot snapshot) {
    assertTrue(snapshot.exists());
    Timestamp when = snapshot.getTimestamp("when", ServerTimestampBehavior.ESTIMATE);
    assertNotNull(when);
    assertEquals(
        expectedDataWithTimestamp(when), snapshot.getData(ServerTimestampBehavior.ESTIMATE));
  }

  /**
   * Verifies a snapshot containing setData but using the previous field value for the timestamps.
   */
  private void verifyTimestampsUsePreviousValue(
      DocumentSnapshot current, @Nullable DocumentSnapshot previous) {
    assertTrue(current.exists());
    if (previous != null) {
      Timestamp when = previous.getTimestamp("when");
      assertNotNull(when);
      assertEquals(
          expectedDataWithTimestamp(when), current.getData(ServerTimestampBehavior.PREVIOUS));
    } else {
      assertEquals(
          expectedDataWithTimestamp(null), current.getData(ServerTimestampBehavior.PREVIOUS));
    }
  }

  @Test
  public void testServerTimestampsWorkViaSet() {
    waitFor(docRef.set(setData));
    verifyTimestampsAreNull(accumulator.awaitLocalEvent());
    verifyTimestampsAreResolved(accumulator.awaitRemoteEvent());
  }

  @Test
  public void testServerTimestampsWorkViaUpdate() {
    writeInitialData();
    waitFor(docRef.update(updateData));
    verifyTimestampsAreNull(accumulator.awaitLocalEvent());
    verifyTimestampsAreResolved(accumulator.awaitRemoteEvent());
  }

  @Test
  public void testServerTimestampsCanReturnEstimatedValue() {
    writeInitialData();
    waitFor(docRef.update(updateData));
    verifyTimestampsAreEstimates(accumulator.awaitLocalEvent());
    verifyTimestampsAreResolved(accumulator.awaitRemoteEvent());
  }

  @Test
  public void testServerTimestampsCanReturnPreviousValue() {
    writeInitialData();
    waitFor(docRef.update(updateData));
    verifyTimestampsUsePreviousValue(accumulator.awaitLocalEvent(), null);

    DocumentSnapshot previousSnapshot = accumulator.awaitRemoteEvent();
    verifyTimestampsAreResolved(previousSnapshot);

    // The following update includes an update of the nested map "deep", which updates it to contain
    // a single ServerTimestamp. As such, the update is split into two mutations: One that sets
    // "deep" to an empty map and overwrites the previous ServerTimestamp value and a second
    // transform that writes the new ServerTimestamp. This step in the test verifies that we can
    // still access the old ServerTimestamp value (from `previousSnapshot`) even though it was
    // removed in an intermediate step.
    waitFor(docRef.update(updateData));
    verifyTimestampsUsePreviousValue(accumulator.awaitLocalEvent(), previousSnapshot);
    verifyTimestampsAreResolved(accumulator.awaitRemoteEvent());
  }

  @Test
  public void testServerTimestampsCanReturnPreviousValueOfDifferentType() {
    writeInitialData();
    waitFor(docRef.update("a", FieldValue.serverTimestamp()));

    DocumentSnapshot localSnapshot = accumulator.awaitLocalEvent();
    assertNull(localSnapshot.get("a"));
    assertThat(localSnapshot.get("a", ServerTimestampBehavior.ESTIMATE))
        .isInstanceOf(Timestamp.class);
    assertEquals(42L, localSnapshot.get("a", ServerTimestampBehavior.PREVIOUS));

    DocumentSnapshot remoteSnapshot = accumulator.awaitRemoteEvent();
    assertThat(remoteSnapshot.get("a")).isInstanceOf(Timestamp.class);
    assertThat(remoteSnapshot.get("a", ServerTimestampBehavior.ESTIMATE))
        .isInstanceOf(Timestamp.class);
    assertThat(remoteSnapshot.get("a", ServerTimestampBehavior.PREVIOUS))
        .isInstanceOf(Timestamp.class);
  }

  @Test
  public void testServerTimestampsCanRetainPreviousValueThroughConsecutiveUpdates() {
    writeInitialData();
    waitFor(docRef.getFirestore().getClient().disableNetwork());
    accumulator.awaitRemoteEvent();

    docRef.update("a", FieldValue.serverTimestamp());
    DocumentSnapshot localSnapshot = accumulator.awaitLocalEvent();
    assertEquals(42L, localSnapshot.get("a", ServerTimestampBehavior.PREVIOUS));

    // include b=1 to ensure there's a change resulting in a new snapshot.
    docRef.update("a", FieldValue.serverTimestamp(), "b", 1);
    localSnapshot = accumulator.awaitLocalEvent();
    assertEquals(42L, localSnapshot.get("a", ServerTimestampBehavior.PREVIOUS));

    waitFor(docRef.getFirestore().getClient().enableNetwork());

    DocumentSnapshot remoteSnapshot = accumulator.awaitRemoteEvent();
    assertThat(remoteSnapshot.get("a")).isInstanceOf(Timestamp.class);
  }

  @Test
  public void testServerTimestampsUsesPreviousValueFromLocalMutation() {
    writeInitialData();
    waitFor(docRef.getFirestore().getClient().disableNetwork());
    accumulator.awaitRemoteEvent();

    docRef.update("a", FieldValue.serverTimestamp());
    DocumentSnapshot localSnapshot = accumulator.awaitLocalEvent();
    assertEquals(42L, localSnapshot.get("a", ServerTimestampBehavior.PREVIOUS));

    docRef.update("a", 1337);
    accumulator.awaitLocalEvent();

    docRef.update("a", FieldValue.serverTimestamp());
    localSnapshot = accumulator.awaitLocalEvent();
    assertEquals(1337L, localSnapshot.get("a", ServerTimestampBehavior.PREVIOUS));

    waitFor(docRef.getFirestore().getClient().enableNetwork());

    DocumentSnapshot remoteSnapshot = accumulator.awaitRemoteEvent();
    assertThat(remoteSnapshot.get("a")).isInstanceOf(Timestamp.class);
  }

  @Test
  public void testServerTimestampBehaviorOverloadsOfDocumentSnapshotGet() {
    writeInitialData();
    waitFor(docRef.update(updateData));
    DocumentSnapshot snap = accumulator.awaitLocalEvent();

    // Default behavior should return null timestamp (via any overload).
    assertNull(snap.get("when"));
    assertNull(snap.get(FieldPath.of("when")));
    assertNull(snap.get("when", Timestamp.class));
    assertNull(snap.get(FieldPath.of("when"), Timestamp.class));

    // Estimate should return a Timestamp object (via any overload).
    assertThat(snap.get("when", ServerTimestampBehavior.ESTIMATE)).isInstanceOf(Timestamp.class);
    assertThat(snap.get(FieldPath.of("when"), ServerTimestampBehavior.ESTIMATE))
        .isInstanceOf(Timestamp.class);
    assertThat(snap.get("when", Timestamp.class, ServerTimestampBehavior.ESTIMATE))
        .isInstanceOf(Timestamp.class);
    assertThat(snap.get(FieldPath.of("when"), Timestamp.class, ServerTimestampBehavior.ESTIMATE))
        .isInstanceOf(Timestamp.class);
  }

  @Test
  public void testServerTimestampsWorkViaTransactionSet() {
    waitFor(
        docRef
            .getFirestore()
            .runTransaction(
                transaction -> {
                  transaction.set(docRef, setData);
                  return null;
                }));
    verifyTimestampsAreResolved(accumulator.awaitRemoteEvent());
  }

  @Test
  public void testServerTimestampsWorkViaTransactionUpdate() {
    writeInitialData();
    waitFor(
        docRef
            .getFirestore()
            .runTransaction(
                transaction -> {
                  transaction.update(docRef, updateData);
                  return null;
                }));
    verifyTimestampsAreResolved(accumulator.awaitRemoteEvent());
  }

  @Test
  public void testServerTimestampsFailViaUpdateOnNonexistentDocument() {
    Exception e = waitForException(docRef.update(updateData));
    assertNotNull(e);
    assertTrue(e instanceof FirebaseFirestoreException);
    assertEquals(Code.NOT_FOUND, ((FirebaseFirestoreException) e).getCode());
  }

  @Test
  public void testServerTimestampsFailViaTransactionUpdateOnNonexistentDocument() {
    Task<?> completion =
        docRef
            .getFirestore()
            .runTransaction(
                transaction -> {
                  transaction.update(docRef, updateData);
                  return null;
                });
    Exception e = waitForException(completion);
    assertNotNull(e);
    assertTrue(e instanceof FirebaseFirestoreException);
    assertEquals(Code.NOT_FOUND, ((FirebaseFirestoreException) e).getCode());
  }

  @Test
  public void testPOJOSupport() {
    DocumentReference ref = testDocument();

    // Write empty pojo (nulls should turn into timestamps)
    TimestampPOJO pojo = new TimestampPOJO();
    waitFor(ref.set(pojo));

    // Read it back (timestamps should have been populated).
    pojo = waitFor(ref.get()).toObject(TimestampPOJO.class);
    assertNull(pojo.a);
    Timestamp resolvedTimestamp = pojo.timestamp1;
    assertNotNull(resolvedTimestamp);
    assertEquals(resolvedTimestamp, pojo.timestamp2);

    // Write it back; timestamps shouldn't change since they're non-null.
    pojo.a = 42L;
    waitFor(ref.set(pojo));

    // And read it back again; make sure the timestamps stayed the same.
    pojo = waitFor(ref.get()).toObject(TimestampPOJO.class);
    assertEquals((Long) 42L, pojo.a);
    assertEquals(resolvedTimestamp, pojo.timestamp1);
    assertEquals(resolvedTimestamp, pojo.timestamp2);
  }

  @Test
  public void testPOJOWithWrongType() {
    DocumentReference ref = testDocument();
    try {
      ref.set(new TimestampPOJOWithWrongType());
      fail("Expected exception.");
    } catch (IllegalArgumentException e) {
      assertEquals(
          "Field timestamp is annotated with @ServerTimestamp but is class "
              + "java.lang.String instead of Date or Timestamp.",
          e.getMessage());
    }
  }

  @Test
  public void testPOJOWithAnnotatedSetter() {
    DocumentReference ref = testDocument();
    try {
      ref.set(new TimestampPOJOWithAnnotatedSetter());
      fail("Expected exception.");
    } catch (IllegalArgumentException e) {
      assertEquals(
          "Method setTimestamp is annotated with @ServerTimestamp but should not be. "
              + "@ServerTimestamp can only be applied to fields and getters, not setters.",
          e.getMessage());
    }
  }

  private static class TimestampPOJO {

    public Long a;

    // On a field
    @ServerTimestamp public Timestamp timestamp1;

    // On a getter
    private Timestamp timestamp2;

    @ServerTimestamp
    public Timestamp getTimestamp2() {
      return timestamp2;
    }
  }

  // ServerTimestamp fields must be of type Timestamp.
  private static class TimestampPOJOWithWrongType {
    @ServerTimestamp public String timestamp;
  }

  // ServerTimestamp can't be applied to setters.
  private static class TimestampPOJOWithAnnotatedSetter {
    private Timestamp timestamp;

    public Timestamp getTimestamp() {
      return timestamp;
    }

    @ServerTimestamp
    public void setTimestamp(Timestamp timestamp) {
      this.timestamp = timestamp;
    }
  }
}


text:
import styled from 'styled-components'
import { css } from '../util'
import { cssTypes } from '../types'

/**
 * @namespace TableHead
 * @desc Primitive styled-component 💅
 * @return {Function} React component
 */
const TableHead = styled.thead`
  ${css};
`

/**
 * @name defaultProps
 * @memberof TableHead
 * @desc Primitive's default properties
 */
TableHead.defaultProps = {}

/**
 * @name propTypes
 * @memberof TableHead
 * @desc Primitive's prop type definitions
 */
TableHead.propTypes = {
  ...cssTypes,
}

/** @component */
export default TableHead

redpajama_set_name: RedPajamaGithub


text:
class TreeBuilderAction < TreeBuilder
  private

  def tree_init_options
    {:full_ids => true}
  end

  # level 0 - root
  def root_options
    {
      :text    => t = _("All Actions"),
      :tooltip => t
    }
  end

  # level 1 - actions
  def x_get_tree_roots
    count_only_or_objects(false, MiqAction.all, :description)
  end
end


text:
/*Disclaimer: This module (Apple Notification Center Service) can and will be changed at any time by either Apple or Nordic Semiconductor ASA.*/
#include "ble_ancs_c.h"
#include <string.h>
#include <stdbool.h>
#include "ble_err.h"
#include "ble_srv_common.h"
#include "nordic_common.h"
#include "nrf_assert.h"
#include "ble_bondmngr.h"
#include "ble_bondmngr_cfg.h"
#include "ble_flash.h"
#include "pstorage.h"
#include "nRF6350.h"
#include "nrf_gpio.h"

#define START_HANDLE_DISCOVER            0x0001                                            /**< Value of start handle during discovery. */

#define NOTIFICATION_DATA_LENGTH         2                                                 /**< The mandatory length of notification data. After the mandatory data, the optional message is located. */

#define TX_BUFFER_MASK                   0x07                                              /**< TX Buffer mask, must be a mask of contiguous zeroes, followed by contiguous sequence of ones: 000...111. */
#define TX_BUFFER_SIZE                   (TX_BUFFER_MASK + 1)                              /**< Size of send buffer, which is 1 higher than the mask. */
#define WRITE_MESSAGE_LENGTH             20                                                /**< Length of the write message for CCCD/control point. */
#define BLE_CCCD_NOTIFY_BIT_MASK         0x0001                                            /**< Enable Notification bit. */

#define BLE_ANCS_MAX_DISCOVERED_CENTRALS BLE_BONDMNGR_MAX_BONDED_CENTRALS                  /**< Maximum number of discovered services that can be stored in the flash. This number should be identical to maximum number of bonded masters. */

#define DISCOVERED_SERVICE_DB_SIZE \
    CEIL_DIV(sizeof(apple_service_t) * BLE_ANCS_MAX_DISCOVERED_CENTRALS, sizeof(uint32_t))  /**< Size of bonded masters database in word size (4 byte). */

typedef enum
{
    READ_REQ = 1,                                                                          /**< Type identifying that this tx_message is a read request. */
    WRITE_REQ                                                                              /**< Type identifying that this tx_message is a write request. */
} ancs_tx_request_t;

typedef enum
{
    STATE_UNINITIALIZED,                                                                   /**< Uninitialized state of the internal state machine. */
    STATE_IDLE,                                                                            /**< Idle state, this is the state when no master has connected to this device. */
    STATE_DISC_SERV,                                                                       /**< A BLE master is connected and a service discovery is in progress. */
    STATE_DISC_CHAR,                                                                       /**< A BLE master is connected and characteristic discovery is in progress. */
    STATE_DISC_DESC,                                                                       /**< A BLE master is connected and descriptor discovery is in progress. */
    STATE_RUNNING,                                                                         /**< A BLE master is connected and complete service discovery has been performed. */
    STATE_WAITING_ENC,                                                                     /**< A previously bonded BLE master has re-connected and the service awaits the setup of an encrypted link. */
    STATE_RUNNING_NOT_DISCOVERED,                                                          /**< A BLE master is connected and a service discovery is in progress. */
} ancs_state_t;

/* brief Structure used for holding the characteristic found during discovery process.
 */
typedef struct
{
    ble_uuid_t               uuid;                                                         /**< UUID identifying this characteristic. */
    ble_gatt_char_props_t    properties;                                                   /**< Properties for this characteristic. */
    uint16_t                 handle_decl;                                                  /**< Characteristic Declaration Handle for this characteristic. */
    uint16_t                 handle_value;                                                 /**< Value Handle for the value provided in this characteristic. */
    uint16_t                 handle_cccd;                                                  /**< CCCD Handle value for this characteristic. BLE_ANCS_INVALID_HANDLE if not present in the master. */
} apple_characteristic_t;

/**@brief Structure used for holding the Apple Notification Center Service found during discovery process.
 */
typedef struct
{
    uint8_t                  handle;                                                       /**< Handle of Apple Notification Center Service which identifies to which master this discovered service belongs. */
    ble_gattc_service_t      service;                                                      /**< The GATT service holding the discovered Apple Notification Center Service. */
    apple_characteristic_t   control_point;
    apple_characteristic_t   notification_source;
    apple_characteristic_t   data_source;
} apple_service_t;

/**@brief Structure for writing a message to the master, i.e. Control Point or CCCD.
 */
typedef struct
{
    uint8_t                  gattc_value[WRITE_MESSAGE_LENGTH];                            /**< The message to write. */
    ble_gattc_write_params_t gattc_params;                                                 /**< GATTC parameters for this message. */
} write_params_t;

/**@brief Structure for holding data to be transmitted to the connected master.
 */
typedef struct
{
    uint16_t                 conn_handle;                                                  /**< Connection handle to be used when transmitting this message. */
    ancs_tx_request_t        type;                                                         /**< Type of this message, i.e. read or write message. */
    union
    {
        uint16_t             read_handle;                                                  /**< Read request message. */
        write_params_t       write_req;                                                    /**< Write request message. */
    } req;
} tx_message_t;

/**@brief ANCS notification attribute parsing states.
 */
typedef enum
{
    COMMAND_ID,
    NOTIFICATION_UID1,
    NOTIFICATION_UID2,
    NOTIFICATION_UID3,
    NOTIFICATION_UID4,
    ATTRIBUTE_ID,
    ATTRIBUTE_LEN1,
    ATTRIBUTE_LEN2,
    ATTRIBUTE_READY
} parse_state_t;

static tx_message_t          m_tx_buffer[TX_BUFFER_SIZE];                                  /**< Transmit buffer for messages to be transmitted to the master. */
static uint32_t              m_tx_insert_index = 0;                                        /**< Current index in the transmit buffer where next message should be inserted. */
static uint32_t              m_tx_index = 0;                                               /**< Current index in the transmit buffer from where the next message to be transmitted resides. */
static pstorage_handle_t     m_flash_handle;                                               /**< Flash handle where discovered services for bonded masters should be stored. */

static ancs_state_t          m_client_state = STATE_UNINITIALIZED;                         /**< Current state of the Apple Notification Center State Machine. */

static uint32_t              m_service_db[DISCOVERED_SERVICE_DB_SIZE];                     /**< Service database for bonded masters (Word size aligned). */
static apple_service_t *     mp_service_db;                                                /**< Pointer to start of discovered services database. */
static apple_service_t       m_service;                                                    /**< Current service data. */

static parse_state_t         m_parse_state = COMMAND_ID;                                   /**< ANCS notification attribute parsing state. */
static ble_ancs_c_t *        m_ancs_c_obj;                                                 /**< Pointer to the instantiated object. */

const ble_uuid128_t ble_ancs_base_uuid128 =
{
   {
    // 7905F431-B5CE-4E99-A40F-4B1E122D00D0
    0xd0, 0x00, 0x2d, 0x12, 0x1e, 0x4b, 0x0f, 0xa4,
    0x99, 0x4e, 0xce, 0xb5, 0x31, 0xf4, 0x05, 0x79

   }
};

const ble_uuid128_t ble_ancs_cp_base_uuid128 =
{
   {
    // 69d1d8f3-45e1-49a8-9821-9bbdfdaad9d9
    0xd9, 0xd9, 0xaa, 0xfd, 0xbd, 0x9b, 0x21, 0x98,
    0xa8, 0x49, 0xe1, 0x45, 0xf3, 0xd8, 0xd1, 0x69

   }
};

const ble_uuid128_t ble_ancs_ns_base_uuid128 =
{
   {
    // 9FBF120D-6301-42D9-8C58-25E699A21DBD
    0xbd, 0x1d, 0xa2, 0x99, 0xe6, 0x25, 0x58, 0x8c,
    0xd9, 0x42, 0x01, 0x63, 0x0d, 0x12, 0xbf, 0x9f

   }
};

const ble_uuid128_t ble_ancs_ds_base_uuid128 =
{
   {
    // 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB
    0xfb, 0x7b, 0x7c, 0xce, 0x6a, 0xb3, 0x44, 0xbe,
    0xb5, 0x4b, 0xd6, 0x24, 0xe9, 0xc6, 0xea, 0x22

   }
};

/**@brief Function for passing any pending request from the buffer to the stack.
 */
static void tx_buffer_process(void)
{
    if (m_tx_index != m_tx_insert_index)
    {
        uint32_t err_code;

        if (m_tx_buffer[m_tx_index].type == READ_REQ)
        {
            err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle,
                                         m_tx_buffer[m_tx_index].req.read_handle,
                                         0);
        }
        else
        {
            err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle,
                                          &m_tx_buffer[m_tx_index].req.write_req.gattc_params);
        }
        if (err_code == NRF_SUCCESS)
        {
            ++m_tx_index;
            m_tx_index &= TX_BUFFER_MASK;
        }
    }
}

/**@brief Function for updating the current state and sending an event on discovery failure.
 */
static void handle_discovery_failure(const ble_ancs_c_t * p_ancs, uint32_t code)
{
    ble_ancs_c_evt_t event;

    m_client_state        = STATE_RUNNING_NOT_DISCOVERED;
    event.evt_type        = BLE_ANCS_C_EVT_DISCOVER_FAILED;
    event.data.error_code = code;

    p_ancs->evt_handler(&event);
}

/**@brief Function for executing the Service Discovery Procedure.
 */
static void service_disc_req_send(const ble_ancs_c_t * p_ancs)
{
    uint16_t   handle = START_HANDLE_DISCOVER;
    ble_uuid_t ancs_uuid;
    uint32_t   err_code;

    // Discover services on uuid for ANCS.
    BLE_UUID_BLE_ASSIGN(ancs_uuid, BLE_UUID_APPLE_NOTIFICATION_CENTER_SERVICE);
    ancs_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN;

    err_code = sd_ble_gattc_primary_services_discover(p_ancs->conn_handle, handle, &ancs_uuid);
    if (err_code != NRF_SUCCESS)
    {
        handle_discovery_failure(p_ancs, err_code);
    }
    else
    {
        m_client_state = STATE_DISC_SERV;
    }
}

/**@brief Function for executing the Characteristic Discovery Procedure.
 */
static void characteristic_disc_req_send(const ble_ancs_c_t * p_ancs,
                                         const ble_gattc_handle_range_t * p_handle)
{
    uint32_t err_code;

    // With valid service, we should discover characteristics.
    err_code = sd_ble_gattc_characteristics_discover(p_ancs->conn_handle, p_handle);

    if (err_code == NRF_SUCCESS)
    {
        m_client_state = STATE_DISC_CHAR;
    }
    else
    {
        handle_discovery_failure(p_ancs, err_code);
    }
}

/**@brief Function for executing the Characteristic Descriptor Discovery Procedure.
 */
static void descriptor_disc_req_send(const ble_ancs_c_t * p_ancs)
{
    ble_gattc_handle_range_t descriptor_handle;
    uint32_t                 err_code = NRF_SUCCESS;

    // If we have not discovered descriptors for all characteristics,
    // we will discover next descriptor.
    if (m_service.notification_source.handle_cccd == BLE_ANCS_INVALID_HANDLE)
    {
        descriptor_handle.start_handle = m_service.notification_source.handle_value + 1;
        descriptor_handle.end_handle = m_service.notification_source.handle_value + 1;

        err_code = sd_ble_gattc_descriptors_discover(p_ancs->conn_handle, &descriptor_handle);
    }
    else if (m_service.data_source.handle_cccd == BLE_ANCS_INVALID_HANDLE)
    {
        descriptor_handle.start_handle = m_service.data_source.handle_value + 1;
        descriptor_handle.end_handle = m_service.data_source.handle_value + 1;

        err_code = sd_ble_gattc_descriptors_discover(p_ancs->conn_handle, &descriptor_handle);
    }

    if (err_code == NRF_SUCCESS)
    {
        m_client_state = STATE_DISC_DESC;
    }
    else
    {
        handle_discovery_failure(p_ancs, err_code);
    }
}

/**@brief Function for indicating that a connection has successfully been established.
 *        Either when the Service Discovery Procedure completes or a re-connection has been
 *        established to a bonded master.
 *
 * @details This function is executed when a service discovery or a re-connect to a bonded master
 *          occurs. In the event of re-connection to a bonded master, this function will ensure
 *          writing of the control point according to the Apple Notification Center Service Client
 *          specification.
 *          Finally an event is passed to the application:
 *          BLE_ANCS_C_EVT_RECONNECT         - When we are connected to an existing master and the
 *                                            apple notification control point has been written.
 *          BLE_ANCS_C_EVT_DISCOVER_COMPLETE - When we are connected to a new master and the Service
 *                                            Discovery has been completed.
 */
static void connection_established(const ble_ancs_c_t * p_ancs)
{
    ble_ancs_c_evt_t event;

    m_client_state = STATE_RUNNING;

    event.evt_type = BLE_ANCS_C_EVT_DISCOVER_COMPLETE;
    p_ancs->evt_handler(&event);
}

/**@brief Function for waiting until an encrypted link has been established to a bonded master.
 */
static void encrypted_link_setup_wait(const ble_ancs_c_t * p_ancs)
{
    m_client_state = STATE_WAITING_ENC;
}

/**@brief Function for handling the connect event when a master connects.
 *
 * @details This function will check if bonded master connects, and do the following
 *          Bonded master  - enter wait for encryption state.
 *          Unknown master - Initiate service discovery procedure.
 */
static void event_connect(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt)
{
    p_ancs->conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;

    if (p_ancs->master_handle != INVALID_CENTRAL_HANDLE)
    {
        m_service = mp_service_db[p_ancs->master_handle];
        encrypted_link_setup_wait(p_ancs);
    }
    else
    {
        m_service.handle = INVALID_SERVICE_HANDLE;
        service_disc_req_send(p_ancs);
    }
}

/**@brief Function for handling the encrypted link event when a secure
 *        connection has been established with a master.
 *
 * @details This function will check if the service for the master is known.
 *          Service known   - Execute action running / switch to running state.
 *          Service unknown - Initiate Service Discovery Procedure.
 */
static void event_encrypted_link(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt)
{
    // If we are setting up a bonded connection and the UUID of the service
    // is unknown, a new discovery must be performed.
    if (m_service.service.uuid.uuid != BLE_UUID_APPLE_NOTIFICATION_CENTER_SERVICE)
    {
        m_service.handle = INVALID_SERVICE_HANDLE;
        service_disc_req_send(p_ancs);
    }
    else
    {
        connection_established(p_ancs);
    }
}

/**@brief Function for handling the response on service discovery.
 *
 * @details This function will validate the response.
 *          Invalid response - Handle discovery failure.
 *          Valid response   - Initiate Characteristic Discovery Procedure.
 */
static void event_discover_rsp(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt)
{
    if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS)
    {
        // We have received an  unexpected result.
        // As we are in a connected state, but can not continue
        // our service discovery, we will go to running state.
        handle_discovery_failure(p_ancs, p_ble_evt->evt.gattc_evt.gatt_status);
    }
    else
    {
        BLE_UUID_COPY_INST(m_service.service.uuid,
                           p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[0].uuid);

        if (p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count > 0)
        {
            const ble_gattc_service_t * p_service;

            p_service = &(p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[0]);

            m_service.service.handle_range.start_handle = p_service->handle_range.start_handle;
            m_service.service.handle_range.end_handle   = p_service->handle_range.end_handle;

            characteristic_disc_req_send(p_ancs, &(m_service.service.handle_range));
        }
        else
        {
            // If we receive an answer, but it contains no service, we just go to state: Running.
            handle_discovery_failure(p_ancs, p_ble_evt->evt.gattc_evt.gatt_status);
        }
    }
}

/**@brief Function for setting the discovered characteristics in the apple service.
 */
static void characteristics_set(apple_characteristic_t * p_characteristic,
                                const ble_gattc_char_t * p_char_resp)
{
    BLE_UUID_COPY_INST(p_characteristic->uuid, p_char_resp->uuid);

    p_characteristic->properties   = p_char_resp->char_props;
    p_characteristic->handle_decl  = p_char_resp->handle_decl;
    p_characteristic->handle_value = p_char_resp->handle_value;
    p_characteristic->handle_cccd  = BLE_ANCS_INVALID_HANDLE;
}

/**@brief Function for handling a characteristic discovery response event.
 *
 * @details This function will validate and store the characteristics received.
 *          If not all characteristics are discovered it will continue the characteristic discovery
 *          procedure, otherwise it will continue with the descriptor discovery procedure.
 *          If we receive a GATT Client error, we will go to handling of discovery failure.
 */
static void event_characteristic_rsp(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt)
{
    if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND ||
        p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INVALID_HANDLE)
    {
        if ((m_service.notification_source.handle_value == 0)    ||
            (m_service.control_point.handle_value == 0)    ||
            (m_service.data_source.handle_value == 0) )
        {
            // At least one required characteristic is missing on the server side.
            handle_discovery_failure(p_ancs, NRF_ERROR_NOT_FOUND);
        }
        else
        {
            descriptor_disc_req_send(p_ancs);
        }
    }
    else if (p_ble_evt->evt.gattc_evt.gatt_status)
    {
        // We have received an  unexpected result.
        // As we are in a connected state, but can not continue
        // our service discovery, we must go to running state.
        handle_discovery_failure(p_ancs, p_ble_evt->evt.gattc_evt.gatt_status);
    }
    else
    {
        uint32_t                 i;
        const ble_gattc_char_t * p_char_resp = NULL;

        // Iterate trough the characteristics and find the correct one.
        for (i = 0; i < p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count; i++)
        {
            p_char_resp = &(p_ble_evt->evt.gattc_evt.params.char_disc_rsp.chars[i]);
            switch (p_char_resp->uuid.uuid)
            {
                case BLE_UUID_ANCS_CONTROL_POINT_CHAR:
                    characteristics_set(&m_service.control_point, p_char_resp);
                    break;

                case BLE_UUID_ANCS_NOTIFICATION_SOURCE_CHAR:
                    characteristics_set(&m_service.notification_source, p_char_resp);
                    break;

                case BLE_UUID_ANCS_DATA_SOURCE_CHAR:
                    characteristics_set(&m_service.data_source, p_char_resp);
                    break;

                default:
                    break;
            }
        }

        if (p_char_resp != NULL)
        {
            // If not all characteristics are received, we do a 2nd/3rd/... round.
            ble_gattc_handle_range_t char_handle;

            char_handle.start_handle = p_char_resp->handle_value + 1;
            char_handle.end_handle   = m_service.service.handle_range.end_handle;

            characteristic_disc_req_send(p_ancs, &char_handle);
        }
        else
        {
            characteristic_disc_req_send(p_ancs, &(m_service.service.handle_range));
        }
    }
}

/**@brief Function for setting the discovered descriptor in the apple service.
 */
static void descriptor_set(apple_service_t * p_service, const ble_gattc_desc_t * p_desc_resp)
{
    if (p_service->control_point.handle_value == (p_desc_resp->handle - 1))
    {
        if (p_desc_resp->uuid.uuid == BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG)
        {
            p_service->control_point.handle_cccd = p_desc_resp->handle;
        }
    }

    else if (p_service->notification_source.handle_value == (p_desc_resp->handle - 1))
    {
        if (p_desc_resp->uuid.uuid == BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG)
        {
            p_service->notification_source.handle_cccd = p_desc_resp->handle;
        }
    }
    else if (p_service->data_source.handle_value == (p_desc_resp->handle - 1))
    {
        if (p_desc_resp->uuid.uuid == BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG)
        {
            p_service->data_source.handle_cccd = p_desc_resp->handle;
        }
    }
}

/**@brief Function for handling of descriptor discovery responses.
 *
 * @details This function will validate and store the descriptor received.
 *          If not all descriptors are discovered it will continue the descriptor discovery
 *          procedure, otherwise it will continue to running state.
 *          If we receive a GATT Client error, we will go to handling of discovery failure.
 */
static void event_descriptor_rsp(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt)
{
    if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND ||
        p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INVALID_HANDLE)
    {
        handle_discovery_failure(p_ancs, NRF_ERROR_NOT_FOUND);
    }
    else if (p_ble_evt->evt.gattc_evt.gatt_status)
    {
        // We have received an unexpected result.
        // As we are in a connected state, but can not continue
        // our descriptor discovery, we will go to running state.
        handle_discovery_failure(p_ancs, p_ble_evt->evt.gattc_evt.gatt_status);
    }
    else
    {
        if (p_ble_evt->evt.gattc_evt.params.desc_disc_rsp.count > 0)
        {
            descriptor_set(&m_service, &(p_ble_evt->evt.gattc_evt.params.desc_disc_rsp.descs[0]));
        }

        if (m_service.notification_source.handle_cccd == BLE_ANCS_INVALID_HANDLE ||
            m_service.data_source.handle_cccd == BLE_ANCS_INVALID_HANDLE)
        {
            descriptor_disc_req_send(p_ancs);
        }
        else
        {
            connection_established(p_ancs);
        }
    }
}

/**@brief Function for parsing received notification attribute response data.
 */
static void parse_get_notification_attributes_response(ble_ancs_c_t * p_ancs, const uint8_t *data, int len)
{
    static uint8_t *ptr;
    static uint16_t current_len;
    static ble_ancs_c_evt_t event;
    int i;

    for (i = 0; i < len; i++)
    {
        switch (m_parse_state)
        {
        case COMMAND_ID:
            event.data.attribute.command_id = data[i];
            m_parse_state = NOTIFICATION_UID1;
            break;

        case NOTIFICATION_UID1:
            event.data.attribute.notification_uid[0] = data[i];
            m_parse_state = NOTIFICATION_UID2;
            break;

        case NOTIFICATION_UID2:
            event.data.attribute.notification_uid[1] = data[i];
            m_parse_state = NOTIFICATION_UID3;
            break;

        case NOTIFICATION_UID3:
            event.data.attribute.notification_uid[2] = data[i];
            m_parse_state = NOTIFICATION_UID4;
            break;

        case NOTIFICATION_UID4:
            event.data.attribute.notification_uid[3] = data[i];
            m_parse_state = ATTRIBUTE_ID;
            break;

        case ATTRIBUTE_ID:
            event.data.attribute.attribute_id = data[i];
            m_parse_state = ATTRIBUTE_LEN1;
            break;

        case ATTRIBUTE_LEN1:
            event.data.attribute.attribute_len = data[i];
            m_parse_state = ATTRIBUTE_LEN2;
            break;

        case ATTRIBUTE_LEN2:
            event.data.attribute.attribute_len |= (data[i] << 8);
            m_parse_state = ATTRIBUTE_READY;
            ptr = event.data.attribute.data;
            current_len = 0;
            break;

        case ATTRIBUTE_READY:
            *ptr++ = data[i];
            current_len++;

            if (current_len == event.data.attribute.attribute_len)
            {
                *ptr++ = 0;
                event.evt_type = BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE;
                p_ancs->evt_handler(&event);
                m_parse_state = ATTRIBUTE_ID;
            }
            break;
        }
    }
}

/**@brief Function for receiving and validating notifications received from the master.
 */
static void event_notify(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt)
{
    ble_ancs_c_evt_t               event;
    const ble_gattc_evt_hvx_t *    p_notification = &p_ble_evt->evt.gattc_evt.params.hvx;

    // Message is not valid -> ignore.
    if (p_notification->len < NOTIFICATION_DATA_LENGTH)
    {
        return;
    }

    if (p_notification->handle == m_service.notification_source.handle_value)
    {
        BLE_UUID_COPY_INST(event.uuid, m_service.notification_source.uuid);
    }
    else if (p_notification->handle == m_service.data_source.handle_value)
    {
        BLE_UUID_COPY_INST(event.uuid, m_service.data_source.uuid);
    }
    else
    {
        // Nothing to process.
        return;
    }

    if (p_notification->handle == m_service.notification_source.handle_value)
    {
        event.data.notification.event_id       = p_notification->data[0];                 /*lint -e{*} suppress Warning 415: possible access out of bond */
        event.data.notification.event_flags    = p_notification->data[1];                 /*lint -e{*} suppress Warning 415: possible access out of bond */
        event.data.notification.category_id    = p_notification->data[2];                 /*lint -e{*} suppress Warning 415: possible access out of bond */
        event.data.notification.category_count = p_notification->data[3];                 /*lint -e{*} suppress Warning 415: possible access out of bond */
        memcpy(event.data.notification.notification_uid, &p_notification->data[4], 4);    /*lint -e{*} suppress Warning 415: possible access out of bond */
        event.evt_type = BLE_ANCS_C_EVT_IOS_NOTIFICATION;

        p_ancs->evt_handler(&event);

        if (event.data.notification.event_id == BLE_ANCS_EVENT_ID_NOTIFICATION_ADDED)
        {
            ble_ancs_attr_list_t attr_list[2];
            attr_list[0].attribute_id = BLE_ANCS_NOTIFICATION_ATTRIBUTE_ID_TITLE;
            attr_list[0].attribute_len = 32;
            attr_list[1].attribute_id = BLE_ANCS_NOTIFICATION_ATTRIBUTE_ID_MESSAGE;
            attr_list[1].attribute_len = 32;
            uint32_t err_code = ble_ancs_get_notification_attributes(p_ancs, event.data.notification.notification_uid, 2, attr_list);
            APP_ERROR_CHECK(err_code);
            m_parse_state = COMMAND_ID;
        }
    }
    else if (p_notification->handle == m_service.data_source.handle_value)
    {
        parse_get_notification_attributes_response(p_ancs, p_notification->data, p_notification->len);
    }
}

/**@brief Function for handling write response events.
 */
static void event_write_rsp(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt)
{
    tx_buffer_process();
}

/**@brief Function for disconnecting and cleaning the current service.
 */
static void event_disconnect(ble_ancs_c_t * p_ancs)
{
    m_client_state = STATE_IDLE;

    if (m_service.handle == INVALID_SERVICE_HANDLE_DISC &&
        p_ancs->master_handle != INVALID_CENTRAL_HANDLE)
    {
        m_service.handle = p_ancs->master_handle;
    }

    if (m_service.handle < BLE_ANCS_MAX_DISCOVERED_CENTRALS)
    {
        mp_service_db[m_service.handle] = m_service;
    }

    memset(&m_service, 0, sizeof(apple_service_t));

    m_service.handle       = INVALID_SERVICE_HANDLE;
    p_ancs->service_handle = INVALID_SERVICE_HANDLE;
    p_ancs->conn_handle    = BLE_CONN_HANDLE_INVALID;
    p_ancs->master_handle  = INVALID_CENTRAL_HANDLE;
}

/**@brief Function for handling of Bond Manager events.
 */
void ble_ancs_c_on_bondmgmr_evt(ble_ancs_c_t * p_ancs, const ble_bondmngr_evt_t * p_bond_mgmr_evt)
{
    switch (p_bond_mgmr_evt->evt_type)
    {
        case BLE_BONDMNGR_EVT_NEW_BOND:
            p_ancs->master_handle = p_bond_mgmr_evt->central_handle;
            break;

        case BLE_BONDMNGR_EVT_CONN_TO_BONDED_CENTRAL:
            p_ancs->master_handle = p_bond_mgmr_evt->central_handle;
            break;

        default:
            // Do nothing.
            break;
    }
}

/**@brief Function for handling of BLE stack events.
 */
void ble_ancs_c_on_ble_evt(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt)
{
    uint16_t event = p_ble_evt->header.evt_id;

    switch (m_client_state)
    {
        case STATE_UNINITIALIZED:
            // Initialization is handle in special case, thus if we enter here, it means that an
            // event is received even though we are not initialized --> ignore.
            break;

        case STATE_IDLE:
            if (event == BLE_GAP_EVT_CONNECTED)
            {
                event_connect(p_ancs, p_ble_evt);
            }
            break;

        case STATE_WAITING_ENC:
            if ((event == BLE_GAP_EVT_AUTH_STATUS)|| (event == BLE_GAP_EVT_SEC_INFO_REQUEST))
            {
                event_encrypted_link(p_ancs, p_ble_evt);
            }
            else if (event == BLE_GAP_EVT_DISCONNECTED)
            {
                event_disconnect(p_ancs);
            }
            break;

        case STATE_DISC_SERV:
            if (event == BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP)
            {
                event_discover_rsp(p_ancs, p_ble_evt);
            }
            else if (event == BLE_GAP_EVT_DISCONNECTED)
            {
                event_disconnect(p_ancs);
            }
            break;

        case STATE_DISC_CHAR:
            if (event == BLE_GATTC_EVT_CHAR_DISC_RSP)
            {
                event_characteristic_rsp(p_ancs, p_ble_evt);
            }
            else if (event == BLE_GAP_EVT_DISCONNECTED)
            {
                event_disconnect(p_ancs);
            }
            break;

        case STATE_DISC_DESC:
            if (event == BLE_GATTC_EVT_DESC_DISC_RSP)
            {
                event_descriptor_rsp(p_ancs, p_ble_evt);
            }
            else if (event == BLE_GAP_EVT_DISCONNECTED)
            {
                event_disconnect(p_ancs);
            }
            break;

        case STATE_RUNNING:
            if (event == BLE_GATTC_EVT_HVX)
            {
                event_notify(p_ancs, p_ble_evt);
            }
            else if (event == BLE_GATTC_EVT_WRITE_RSP)
            {
                event_write_rsp(p_ancs, p_ble_evt);
            }
            else if (event == BLE_GAP_EVT_DISCONNECTED)
            {
                event_disconnect(p_ancs);
            }
            else
            {
                // Do nothing, event not handled in this state.
            }
            break;

        case STATE_RUNNING_NOT_DISCOVERED:
        default:
            if (event == BLE_GAP_EVT_DISCONNECTED)
            {
                event_disconnect(p_ancs);
            }
            break;
    }
}

static void ancs_pstorage_callback(pstorage_handle_t * handle,
                                   uint8_t             op_code,
                                   uint32_t            reason,
                                   uint8_t           * p_data,
                                   uint32_t            param_len)
{
    if (reason != NRF_SUCCESS)
    {
        m_ancs_c_obj->error_handler(reason);
    }
}

uint32_t ble_ancs_c_init(ble_ancs_c_t * p_ancs, const ble_ancs_c_init_t * p_ancs_init)
{
    uint32_t                err_code;
    pstorage_module_param_t param;

    if (p_ancs_init->evt_handler == NULL)
    {
        return NRF_ERROR_INVALID_PARAM;
    }

    p_ancs->evt_handler         = p_ancs_init->evt_handler;
    p_ancs->error_handler       = p_ancs_init->error_handler;
    p_ancs->service_handle      = INVALID_SERVICE_HANDLE;
    p_ancs->master_handle       = INVALID_CENTRAL_HANDLE;
    p_ancs->service_handle      = 0;
    p_ancs->message_buffer_size = p_ancs_init->message_buffer_size;
    p_ancs->p_message_buffer    = p_ancs_init->p_message_buffer;
    p_ancs->conn_handle         = BLE_CONN_HANDLE_INVALID;

    memset(&m_service, 0, sizeof(apple_service_t));
    memset(m_tx_buffer, 0, TX_BUFFER_SIZE);

    m_service.handle = INVALID_SERVICE_HANDLE;
    m_client_state   = STATE_IDLE;

    param.block_count = 1;
    param.block_size  = DISCOVERED_SERVICE_DB_SIZE * sizeof(uint32_t); // uint32_t array.
    param.cb          = ancs_pstorage_callback;

    // Register with storage module.
    err_code = pstorage_register(&param, &m_flash_handle);

    mp_service_db    = (apple_service_t *) (m_service_db);

    return err_code;
}

/**@brief Function for creating a TX message for writing a CCCD.
 */
static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool enable)
{
    tx_message_t * p_msg;
    uint16_t       cccd_val = enable ? BLE_CCCD_NOTIFY_BIT_MASK : 0;

    if (m_client_state != STATE_RUNNING)
    {
        return NRF_ERROR_INVALID_STATE;
    }

    p_msg              = &m_tx_buffer[m_tx_insert_index++];
    m_tx_insert_index &= TX_BUFFER_MASK;

    p_msg->req.write_req.gattc_params.handle   = handle_cccd;
    p_msg->req.write_req.gattc_params.len      = 2;
    p_msg->req.write_req.gattc_params.p_value  = p_msg->req.write_req.gattc_value;
    p_msg->req.write_req.gattc_params.offset   = 0;
    p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
    p_msg->req.write_req.gattc_value[0]        = LSB(cccd_val);
    p_msg->req.write_req.gattc_value[1]        = MSB(cccd_val);
    p_msg->conn_handle                         = conn_handle;
    p_msg->type                                = WRITE_REQ;

    tx_buffer_process();
    return NRF_SUCCESS;
}

uint32_t ble_ancs_c_enable_notif_notification_source(const ble_ancs_c_t * p_ancs)
{
    return cccd_configure(p_ancs->conn_handle,
                          m_service.notification_source.handle_cccd,
                          true);
}

uint32_t ble_ancs_c_disable_notif_notification_source(const ble_ancs_c_t * p_ancs)
{
    return cccd_configure(p_ancs->conn_handle,
                          m_service.notification_source.handle_cccd,
                          false);
}

uint32_t ble_ancs_c_enable_notif_data_source(const ble_ancs_c_t * p_ancs)
{
    return cccd_configure(p_ancs->conn_handle,
                          m_service.data_source.handle_cccd,
                          true);
}

uint32_t ble_ancs_c_disable_notif_data_source(const ble_ancs_c_t * p_ancs)
{
    return cccd_configure(p_ancs->conn_handle,
                          m_service.data_source.handle_cccd,
                          false);
}

uint32_t ble_ancs_get_notification_attributes(const ble_ancs_c_t * p_ancs, uint8_t * p_uid,
                                              uint8_t num_attr, ble_ancs_attr_list_t *p_attr)
{
    tx_message_t * p_msg;
    uint32_t i = 0;

    if (m_client_state != STATE_RUNNING)
    {
        return NRF_ERROR_INVALID_STATE;
    }

    p_msg              = &m_tx_buffer[m_tx_insert_index++];
    m_tx_insert_index &= TX_BUFFER_MASK;

    p_msg->req.write_req.gattc_params.handle   = m_service.control_point.handle_value;
    p_msg->req.write_req.gattc_params.p_value  = p_msg->req.write_req.gattc_value;
    p_msg->req.write_req.gattc_params.offset   = 0;
    p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;

    p_msg->req.write_req.gattc_value[i++]      = BLE_ANCS_COMMAND_ID_GET_NOTIFICATION_ATTRIBUTES;
    memcpy(&p_msg->req.write_req.gattc_value[1], p_uid, 4);
    i += 4;

    while (num_attr > 0)
    {
      p_msg->req.write_req.gattc_value[i++] = p_attr->attribute_id;
      if (p_attr->attribute_len > 0)
      {
        p_msg->req.write_req.gattc_value[i++] = (uint8_t) (p_attr->attribute_len);
        p_msg->req.write_req.gattc_value[i++] = (uint8_t) (p_attr->attribute_len << 8);
      }
      p_attr++;
      num_attr--;
    }

    p_msg->req.write_req.gattc_params.len      = i;
    p_msg->conn_handle                         = p_ancs->conn_handle;
    p_msg->type                                = WRITE_REQ;

    tx_buffer_process();
    return NRF_SUCCESS;

}

uint32_t ble_ans_c_service_load(const ble_ancs_c_t * p_ans)
{
    uint32_t err_code;
    uint32_t i;

    err_code = pstorage_load((uint8_t *)m_service_db,
                             &m_flash_handle,
                             (DISCOVERED_SERVICE_DB_SIZE * sizeof(uint32_t)),
                             0);

    if (err_code != NRF_SUCCESS)
    {
        // Problem with loading values from flash, initialize the RAM DB with default.
        for (i = 0; i < BLE_ANCS_MAX_DISCOVERED_CENTRALS; ++i)
        {
            mp_service_db[i].handle = INVALID_SERVICE_HANDLE;
        }

        if (err_code == NRF_ERROR_NOT_FOUND)
        {
            // The flash does not contain any memorized centrals, set the return code to success.
            err_code = NRF_SUCCESS;
        }
    }
    return err_code;
}

uint32_t ble_ans_c_service_store(void)
{
    uint32_t err_code;

    err_code = pstorage_store(&m_flash_handle,
                              (uint8_t *) m_service_db,
                              DISCOVERED_SERVICE_DB_SIZE * sizeof(uint32_t),
                              0);

    return err_code;
}

uint32_t ble_ans_c_service_delete(void)
{
    if (m_client_state == STATE_UNINITIALIZED)
    {
        return NRF_SUCCESS;
    }

    return pstorage_clear(&m_flash_handle, (DISCOVERED_SERVICE_DB_SIZE * sizeof(uint32_t)));
}


text:
description: Learn how to dynamically register applications with Auth0 using the Management API.
crews: crew-2
toc: true
topics:
  - applications
contentType: how-to
useCase:
  - secure-api
  - call-api
---

# Dynamic Client Registration

Dynamic Client Registration enables you to register [third-party applications](/applications/guides/enable-third-party-apps) dynamically.

This feature is based on the [OpenID Connect Dynamic Client Registration specification](https://openid.net/specs/openid-connect-registration-1_0.html) and in this article we will see how you can enable and use it.

## Enable dynamic registration

::: warning
Auth0 supports **Open Dynamic Registration**, which means that if you enable this feature, **anyone** will be able to create applications in your tenant without a token.
:::

By default, the feature is disabled for all tenants. To change this, you have to set the `enable_dynamic_client_registration` flag to `true` in your tenant's settings.

This can be done by enabling the **OIDC Dynamic Application Registration** toggle on your tenant's [Advanced Settings page](${manage_url}/#/tenant/advanced).

Alternatively, you can update this flag using the [Update tenant settings endpoint](/api/management/v2#!/Tenants/patch_settings).

```har
{
  "method": "PATCH",
  "url": "https://${account.namespace}/api/v2/tenants/settings",
  "headers": [
    { "name": "Content-Type", "value": "application/json" },
    { "name": "Authorization", "value": "Bearer API2_ACCESS_TOKEN" },
    { "name": "Cache-Control", "value": "no-cache" }
  ],
  "postData": {
      "mimeType": "application/json",
      "text" : "{ \"flags\": { \"enable_dynamic_client_registration\": true } }"
  }
}
```

You need to update the `API2_ACCESS_TOKEN` with a valid token with the <dfn data-key="scope">scope</dfn> `update:tenant_settings`. See [Access Tokens for the Management API](/api/management/v2/tokens) for details on how to do so.

## Use dynamic registration

In this section we will see how you can dynamically register and configure an application.

### Register your application

To dynamically register an application with Auth0, you need to send an HTTP `POST` message to the Application Registration endpoint: `https://${account.namespace}/oidc/register`. Note that Auth0 supports **Open Dynamic Registration**, which means that the endpoint will accept a registration request without an <dfn data-key="access-token">Access Token</dfn>.

To create an application with the name `My Dynamic application` and the <dfn data-key="callback">callback URLs</dfn> `https://application.example.com/callback` and `https://application.example.com/callback2`, use the following snippet.

```har
{
  "method": "POST",
  "url": "https://${account.namespace}/oidc/register",
  "headers": [
    { "name": "Content-Type", "value": "application/json" }
  ],
  "postData": {
    "mimeType": "application/json",
    "text": "{\"client_name\":\"My Dynamic Application\",\"redirect_uris\": [\"https://application.example.com/callback\", \"https://application.example.com/callback2\"]}"
  }
}
```

Where:
- **client_name**: The name of the Dynamic Application to be created
- **redirect_uris** (required): An array of URLs that Auth0 will deem valid to call at the end of an authentication flow

Optionally, you can set a value for `token_endpoint_auth_method`, which can be `none` or `client_secret_post` (default value). Use `token_endpoint_auth_method: none` in the request payload if creating a SPA.

The response includes the basic application information.

```json
HTTP/1.1 201 Created
Content-Type: application/json
{
  "client_name": "My Dynamic Application",
  "client_id": "8SXWY6j3afl2CP5ntwEOpMdPxxy49Gt2",
  "client_secret": "Q5O...33P",
  "redirect_uris": [
    "https://application.example.com/callback",
    "https://application.example.com/callback2"
  ],
  "client_secret_expires_at": 0
}
```

Where:
- **client_id**: Unique client identifier. This is the ID you will use while configuring your apps to use Auth0. It is generated by the system and it cannot be modified.
- **client_secret**: Alphanumeric 64-bit client secret. This value is used by applications to authenticate to the [token endpoint](/api/authentication#get-token) and for signing and validating [ID Tokens](/tokens/concepts/id-tokens).
- **client_secret_expires_at**: Time at which the `client_secret` will expire. For Auth0 this value will always be zero (`0`) which means that the application never expires.

Make a note of the Client ID and Secret, as these are the most important pieces for executing [authentication](/application-auth) and [authorization](/api-auth) flows.

Also, keep in mind that third-party developers are not allowed to modify the application settings. In case this is necessary, they need to contact the tenant owner with their request.

### Configure your application

Now that you have a Client ID and Secret, you can configure your application to authenticate users with Auth0.

We will go through a simple example, that shows how to call an API from a client-side web app, using the [Implicit Flow](/flows/guides/implicit/call-api-implicit). For a list of tutorials on how to authenticate and authorize users, based on your application type, see the [API Authorization](/api-auth) page.

First, you need to configure your application to send the user to the authorization URL:

```text
https://${account.namespace}/authorize?
  audience={API_AUDIENCE}&
  scope={SCOPE}&
  response_type={RESPONSE_TYPE}&
  client_id=${account.clientId}&
  redirect_uri=${account.callback}&
  nonce={NONCE}
  state={OPAQUE_VALUE}
```

Where:
- <dfn data-key="audience">**audience**</dfn> (optional): The target API for which the Application is requesting access on behalf of the user. Set this parameter if you need API access.
- **scope** (optional): The scopes which you want to request authorization for. These must be separated by a space. You can request any of the [standard OIDC scopes](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) about users, such as `profile` and `email`, custom claims that must conform to a namespaced format (see panel below for more info), or any scopes supported by the target API (for example, `read:contacts`). Set this parameter if you need API access.

  ::: panel Custom claims namespaced format
  In order to add custom claims to ID Tokens or Access Tokens, they must [conform to a namespaced format](/api-auth/tutorials/adoption/scope-custom-claims) to avoid possible collisions with standard OpenID Connect claims. For example, if you choose the namespace `https://foo.com/` and you want to add a custom claim named `myclaim`, you would name the claim `https://foo.com/myclaim`, instead of `myclaim`.
  :::

- **response_type**: The response type. For Implicit Grant you can either use `token` or `id_token token`. This will specify the type of token you will receive at the end of the flow. Use `token` to get only an Access Token, or `id_token token` to get both an ID Token and an Access Token.
- **client_id**: Your application's Client ID.
- **redirect_uri**: The URL to which the Authorization Server (Auth0) will redirect the User Agent (Browser) after authorization has been granted by the User. The Access Token (and optionally an ID Token) will be available in the hash fragment of this URL. This URL must be specified as a valid callback URL under the Application Settings of your application.
- **state**: An opaque value the applications add to the initial request that the authorization server includes when redirecting the back to the application. This value must be used by the application to prevent CSRF attacks.
- **nonce**: A string value which will be included in the ID Token response from Auth0, [used to prevent token replay attacks](/api-auth/tutorials/nonce). It is required for `response_type=id_token token`.

For example:

```html
<a href="https://${account.namespace}/authorize?scope=appointments%20contacts&audience=appointments:api&response_type=id_token%20token&client_id=${account.clientId}&redirect_uri=${account.callback}">
  Sign In
</a>
```

This call will redirect the user to Auth0, and upon successful authentication, back to your application (specifically to the **redirect_uri**).

If you need API access, then following the authentication, you need to extract the Access Token from the hash fragment of the URL, and use it to make calls to the API, by passing it as a `Bearer` token in the `Authorization` header of the HTTP request.


text:
case node['platform']
when 'windows'

  # Configure winrm
  # use attributes to add other configuration
  powershell_script 'enable winrm' do
    code <<-EOH
      winrm quickconfig -q
    EOH
  end

  # check if https listener already exists
  winrm_cmd = 'powershell.exe winrm enumerate winrm/config/listener'
  shell_out = Mixlib::ShellOut.new(winrm_cmd)
  shell_out.run_command

  # Create HTTPS listener
  if !shell_out.stdout.include?('Transport = HTTPS') && node['powershell']['winrm']['enable_https_transport']
    if node['powershell']['winrm']['thumbprint'].nil? || node['powershell']['winrm']['thumbprint'].empty?
      Chef::Log.error('Please specify thumbprint in default attributes for enabling https transport.')
    else
      powershell_script 'winrm-create-https-listener' do
        code "winrm create 'winrm/config/Listener?Address=*+Transport=HTTPS' '@{Hostname=\"#{node['powershell']['winrm']['hostname']}\"; CertificateThumbprint=\"#{node['powershell']['winrm']['thumbprint']}\"}'"
      end
    end
  else
    Chef::Log.warn('WinRM HTTPS listener is already configured. Please delete the existing https listener first to configure new one.')
  end
else
  Chef::Log.warn('WinRM can only be enabled on the Windows platform.')
end


text:
using IvmpDotNet.SDK;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IvmpDotNet.SampleCLRModule {
    public class ExampleModule : IModule {
        System.Timers.Timer timer;
        List<IvmpDotNet.SDK.IVehicle> vehicles;
        ICoreManager coreManager;

        void EventManager_PlayerCommand(object sender, SDK.PlayerCommandArgs e) {
            foreach (string cmd in e.Command) {
                e.Player.SendMessage("ASDF: " + cmd, 0, false);
            }

            if (e.Command[0] == "/asdf") {
                e.Player.SendMessage("You entered valid message", 0, false);
                e.Player.GiveWeapon(Weapons.DesertEagle, 1337);
            } else if (e.Command[0] == "/test") {
                var obj = coreManager.ObjectManager.Create(2627789200, e.Player.Coordinates, new SDK.CVector3());
                obj.AttachToPlayer(e.Player, new CVector3(), new SDK.CVector3(), -1);
            } else {
                e.Player.SendMessage("You entered Invalid Message", 0, false);
            }
        }

        void EventManager_PlayerSpawn(object sender, SDK.PlayerEventArgs e) {
            e.Player.GiveWeapon(Weapons.M4, 1337);
            e.Player.GiveHelmet();
            e.Player.Money = 1337;
            e.Player.DisplayText(100, 100, "asdff", 60 * 1000);
        }

        public void Load(ICoreManager mgr) {
            coreManager = mgr;

            coreManager.EventManager.PlayerSpawn += EventManager_PlayerSpawn;
            coreManager.EventManager.PlayerCommand += EventManager_PlayerCommand;

            vehicles = new List<IVehicle>() {
                coreManager.VehicleManager.Create(
                    VehicleModels.Banshee,
                    new SDK.CVector3() {
                        X = 1657.118408f,
                        Y = 421.462982f,
                        Z = 28.569500f
                    },
                    new SDK.CVector3() {
                        X = 359.828613f,
                        Y = 352.884033f,
                        Z = 267.583008f
                    },
                    0, 0, 0, 0, -1),
                coreManager.VehicleManager.Create(
                    VehicleModels.Burrito,
                    new SDK.CVector3() {
                        X = 1657.118408f,
                        Y = 421.462982f,
                        Z = 38.569500f
                    },
                    new SDK.CVector3() {
                        X = 359.828613f,
                        Y = 352.884033f,
                        Z = 267.583008f
                    },
                    0, 0, 0, 0, -1)
            };

            timer = new System.Timers.Timer();
            timer.Interval = TimeSpan.FromSeconds(10).TotalMilliseconds;
            timer.Elapsed += timer_Elapsed;
            timer.Start();

            Console.WriteLine("Loaded Sample CLR Module");
        }

        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
            coreManager.PlayerManager.SendMessageToAll("SPAAAM", 0, false);
        }

        public void Unload() {
            timer.Elapsed -= timer_Elapsed;
            coreManager.EventManager.PlayerSpawn -= EventManager_PlayerSpawn;
            coreManager.EventManager.PlayerCommand -= EventManager_PlayerCommand;

            foreach (var vehicle in vehicles)
                vehicle.Delete();
        }
    }
}


text:
import { ICommentsState } from 'src/app/routes/project/store/reducers/comment-threads.reducer';
import { EDIT_CONTENT_ATTR, NAME_ATTR, ZERO_WIDTH_SPACE } from 'cd-common/consts';
import { constructElement } from 'cd-common/utils';
import { CHIP_ELEMENT_NAME, CHIP_CLASSNAME, CHIP_DATA_ID_BINDING } from './comments.consts';
import { Dictionary } from '@ngrx/entity';
import * as cd from 'cd-interfaces';

type CommentMap = cd.IStringMap<cd.IComment[]>;

export const getTaggedItems = (
  textFieldParts: cd.ITaggableTextFieldNode[]
): cd.IStringMap<cd.IUser> => {
  return textFieldParts.reduce<cd.IStringMap<cd.IUser>>((acc, item) => {
    const { type, content } = item;
    if (content && type === cd.TextFieldElementType.Chip) {
      const user = content as cd.IUser;
      if (user.email) {
        acc[user.email] = user;
      }
    }
    return acc;
  }, {});
};

export const commentBodyToHtml = (commentBody: cd.ITaggableTextFieldNode[]): string => {
  return commentBody.reduce((htmlString, part) => htmlString + nodeFromType(part), '');
};

export const commentThreadsPerBoard = (
  boardId: string,
  entities: Dictionary<cd.ICommentThreadDocument>
): cd.ICommentThreadDocument[] => {
  return Object.values(entities).filter((value) => {
    return (value as cd.ICommentThreadDocument).targetId === boardId;
  }) as cd.ICommentThreadDocument[];
};

export const filterCommentThreadsByBoardId = (
  boardId: string,
  commentsState: ICommentsState
): cd.ICommentThread[] => {
  const { entities } = commentsState.commentThreads;
  const commentThreadDocuments = commentThreadsPerBoard(boardId, entities);
  const commentDocuments = Object.values(commentsState.comments.entities) as cd.ICommentDocument[];
  const commentsMap = getCommentsMap(commentDocuments);
  const commentThreads = mergeCommentThreadsAndCommentsMap(commentThreadDocuments, commentsMap);

  return commentThreads.sort((a, b) =>
    a.comments.length && b.comments.length ? b.comments[0].createdAt - a.comments[0].createdAt : 0
  );
};

export const getNumberOfResolvedThreads = (threads: cd.ICommentThread[]): number => {
  let count = 0;

  threads.map((item) => {
    if (item.resolved) count++;
  });

  return count;
};

const getCommentsMap = (commentDocuments: cd.ICommentDocument[]): cd.IStringMap<cd.IComment[]> => {
  return commentDocuments.reduce<CommentMap>((commentsMap, doc) => {
    const { threadId, owner } = doc;
    if (!commentsMap[threadId]) commentsMap[threadId] = [];
    const comment: cd.IComment = { ...doc, user: owner };
    commentsMap[threadId].push(comment);
    return commentsMap;
  }, {});
};

const getCommentThread = (
  commentThreadDocument: cd.ICommentThreadDocument,
  commentsMap: CommentMap
) => {
  const { id } = commentThreadDocument;
  const comments: cd.IComment[] = commentsMap[id] || [];
  comments.sort((a, b) => a.createdAt - b.createdAt);
  return { ...commentThreadDocument, comments };
};

const mergeCommentThreadsAndCommentsMap = (
  commentThreadDocuments: cd.ICommentThreadDocument[],
  commentsMap: CommentMap
): cd.ICommentThread[] => {
  return commentThreadDocuments.reduce<cd.ICommentThread[]>((threads, threadDoc) => {
    const commentThread = getCommentThread(threadDoc, commentsMap);
    threads.push(commentThread);
    return threads;
  }, []);
};

export const buildCommentChip = (name: string, email: string) => {
  return constructElement(CHIP_ELEMENT_NAME, CHIP_CLASSNAME, '', [
    [EDIT_CONTENT_ATTR, String(false)],
    [CHIP_DATA_ID_BINDING, email],
    [NAME_ATTR, name],
  ]);
};

const buildChipNode = (content: cd.IUser) => {
  const { email, name } = content as cd.IUser;
  if (!email || !name) return;
  const chip = buildCommentChip(name, email);
  return chip + ZERO_WIDTH_SPACE;
};

const nodeFromType = (part: cd.ITaggableTextFieldNode) => {
  const { type, content } = part;
  if (type === cd.TextFieldElementType.Break) return '<br/>';
  if (type === cd.TextFieldElementType.Chip) return buildChipNode(<cd.IUser>content);
  if (type === cd.TextFieldElementType.Link) return String(content);
  if (type === cd.TextFieldElementType.Text) return String(content);
  return;
};


text:
require({cache:{
'url:dijit/templates/Tooltip.html':"

\n"}});
define("dijit/Tooltip", [
	"dojo/_base/array", // array.forEach array.indexOf array.map
	"dojo/_base/declare", // declare
	"dojo/_base/fx", // fx.fadeIn fx.fadeOut
	"dojo/dom", // dom.byId
	"dojo/dom-class", // domClass.add
	"dojo/dom-geometry", // domGeometry.position
	"dojo/dom-style", // domStyle.set, domStyle.get
	"dojo/_base/lang", // lang.hitch lang.isArrayLike
	"dojo/mouse",
	"dojo/on",
	"dojo/sniff", // has("ie")
	"./_base/manager",	// manager.defaultDuration
	"./place",
	"./_Widget",
	"./_TemplatedMixin",
	"./BackgroundIframe",
	"dojo/text!./templates/Tooltip.html",
	"./main"		// sets dijit.showTooltip etc. for back-compat
], function(array, declare, fx, dom, domClass, domGeometry, domStyle, lang, mouse, on, has,
			manager, place, _Widget, _TemplatedMixin, BackgroundIframe, template, dijit){

	// module:
	//		dijit/Tooltip

	// TODO: Tooltip should really share more positioning code with TooltipDialog, like:
	//		- the orient() method
	//		- the connector positioning code in show()
	//		- the dijitTooltip[Dialog] class
	//
	// The problem is that Tooltip's implementation supplies it's own  and interacts directly
	// with dijit/place, rather than going through dijit/popup like TooltipDialog and other popups (ex: Menu).

	var MasterTooltip = declare("dijit._MasterTooltip", [_Widget, _TemplatedMixin], {
		// summary:
		//		Internal widget that holds the actual tooltip markup,
		//		which occurs once per page.
		//		Called by Tooltip widgets which are just containers to hold
		//		the markup
		// tags:
		//		protected

		// duration: Integer
		//		Milliseconds to fade in/fade out
		duration: manager.defaultDuration,

		templateString: template,

		postCreate: function(){
			this.ownerDocumentBody.appendChild(this.domNode);

			this.bgIframe = new BackgroundIframe(this.domNode);

			// Setup fade-in and fade-out functions.
			this.fadeIn = fx.fadeIn({ node: this.domNode, duration: this.duration, onEnd: lang.hitch(this, "_onShow") });
			this.fadeOut = fx.fadeOut({ node: this.domNode, duration: this.duration, onEnd: lang.hitch(this, "_onHide") });
		},

		show: function(innerHTML, aroundNode, position, rtl, textDir){
			// summary:
			//		Display tooltip w/specified contents to right of specified node
			//		(To left if there's no space on the right, or if rtl == true)
			// innerHTML: String
			//		Contents of the tooltip
			// aroundNode: DomNode|dijit/place.__Rectangle
			//		Specifies that tooltip should be next to this node / area
			// position: String[]?
			//		List of positions to try to position tooltip (ex: ["right", "above"])
			// rtl: Boolean?
			//		Corresponds to `WidgetBase.dir` attribute, where false means "ltr" and true
			//		means "rtl"; specifies GUI direction, not text direction.
			// textDir: String?
			//		Corresponds to `WidgetBase.textdir` attribute; specifies direction of text.

			if(this.aroundNode && this.aroundNode === aroundNode && this.containerNode.innerHTML == innerHTML){
				return;
			}

			if(this.fadeOut.status() == "playing"){
				// previous tooltip is being hidden; wait until the hide completes then show new one
				this._onDeck=arguments;
				return;
			}
			this.containerNode.innerHTML=innerHTML;

			if(textDir){
				this.set("textDir", textDir);
			}

			this.containerNode.align = rtl? "right" : "left"; //fix the text alignment

			var pos = place.around(this.domNode, aroundNode,
				position && position.length ? position : Tooltip.defaultPosition, !rtl, lang.hitch(this, "orient"));

			// Position the tooltip connector for middle alignment.
			// This could not have been done in orient() since the tooltip wasn't positioned at that time.
			var aroundNodeCoords = pos.aroundNodePos;
			if(pos.corner.charAt(0) == 'M' && pos.aroundCorner.charAt(0) == 'M'){
				this.connectorNode.style.top = aroundNodeCoords.y + ((aroundNodeCoords.h - this.connectorNode.offsetHeight) >> 1) - pos.y + "px";
				this.connectorNode.style.left = "";
			}else if(pos.corner.charAt(1) == 'M' && pos.aroundCorner.charAt(1) == 'M'){
				this.connectorNode.style.left = aroundNodeCoords.x + ((aroundNodeCoords.w - this.connectorNode.offsetWidth) >> 1) - pos.x + "px";
			}else{
				// Not *-centered, but just above/below/after/before
				this.connectorNode.style.left = "";
				this.connectorNode.style.top = "";
			}

			// show it
			domStyle.set(this.domNode, "opacity", 0);
			this.fadeIn.play();
			this.isShowingNow = true;
			this.aroundNode = aroundNode;
		},

		orient: function(/*DomNode*/ node, /*String*/ aroundCorner, /*String*/ tooltipCorner, /*Object*/ spaceAvailable, /*Object*/ aroundNodeCoords){
			// summary:
			//		Private function to set CSS for tooltip node based on which position it's in.
			//		This is called by the dijit popup code.   It will also reduce the tooltip's
			//		width to whatever width is available
			// tags:
			//		protected

			this.connectorNode.style.top = ""; //reset to default

			var heightAvailable = spaceAvailable.h,
				widthAvailable = spaceAvailable.w;

			node.className = "dijitTooltip " +
				{
					"MR-ML": "dijitTooltipRight",
					"ML-MR": "dijitTooltipLeft",
					"TM-BM": "dijitTooltipAbove",
					"BM-TM": "dijitTooltipBelow",
					"BL-TL": "dijitTooltipBelow dijitTooltipABLeft",
					"TL-BL": "dijitTooltipAbove dijitTooltipABLeft",
					"BR-TR": "dijitTooltipBelow dijitTooltipABRight",
					"TR-BR": "dijitTooltipAbove dijitTooltipABRight",
					"BR-BL": "dijitTooltipRight",
					"BL-BR": "dijitTooltipLeft"
				}[aroundCorner + "-" + tooltipCorner];

			// reset width; it may have been set by orient() on a previous tooltip show()
			this.domNode.style.width = "auto";

			// Reduce tooltip's width to the amount of width available, so that it doesn't overflow screen.
			// Note that sometimes widthAvailable is negative, but we guard against setting style.width to a
			// negative number since that causes an exception on IE.
			var size = domGeometry.position(this.domNode);
			if(has("ie") == 9){
				// workaround strange IE9 bug where setting width to offsetWidth causes words to wrap
				size.w += 2;
			}

			var width = Math.min((Math.max(widthAvailable,1)), size.w);

			domGeometry.setMarginBox(this.domNode, {w: width});

			// Reposition the tooltip connector.
			if(tooltipCorner.charAt(0) == 'B' && aroundCorner.charAt(0) == 'B'){
				var bb = domGeometry.position(node);
				var tooltipConnectorHeight = this.connectorNode.offsetHeight;
				if(bb.h > heightAvailable){
					// The tooltip starts at the top of the page and will extend past the aroundNode
					var aroundNodePlacement = heightAvailable - ((aroundNodeCoords.h + tooltipConnectorHeight) >> 1);
					this.connectorNode.style.top = aroundNodePlacement + "px";
					this.connectorNode.style.bottom = "";
				}else{
					// Align center of connector with center of aroundNode, except don't let bottom
					// of connector extend below bottom of tooltip content, or top of connector
					// extend past top of tooltip content
					this.connectorNode.style.bottom = Math.min(
						Math.max(aroundNodeCoords.h/2 - tooltipConnectorHeight/2, 0),
						bb.h - tooltipConnectorHeight) + "px";
					this.connectorNode.style.top = "";
				}
			}else{
				// reset the tooltip back to the defaults
				this.connectorNode.style.top = "";
				this.connectorNode.style.bottom = "";
			}

			return Math.max(0, size.w - widthAvailable);
		},

		_onShow: function(){
			// summary:
			//		Called at end of fade-in operation
			// tags:
			//		protected
			if(has("ie")){
				// the arrow won't show up on a node w/an opacity filter
				this.domNode.style.filter="";
			}
		},

		hide: function(aroundNode){
			// summary:
			//		Hide the tooltip

			if(this._onDeck && this._onDeck[1] == aroundNode){
				// this hide request is for a show() that hasn't even started yet;
				// just cancel the pending show()
				this._onDeck=null;
			}else if(this.aroundNode === aroundNode){
				// this hide request is for the currently displayed tooltip
				this.fadeIn.stop();
				this.isShowingNow = false;
				this.aroundNode = null;
				this.fadeOut.play();
			}else{
				// just ignore the call, it's for a tooltip that has already been erased
			}
		},

		_onHide: function(){
			// summary:
			//		Called at end of fade-out operation
			// tags:
			//		protected

			this.domNode.style.cssText="";	// to position offscreen again
			this.containerNode.innerHTML="";
			if(this._onDeck){
				// a show request has been queued up; do it now
				this.show.apply(this, this._onDeck);
				this._onDeck=null;
			}
		}
	});

	if(has("dojo-bidi")){
		MasterTooltip.extend({
			_setAutoTextDir: function(/*Object*/node){
				// summary:
				//		Resolve "auto" text direction for children nodes
				// tags:
				//		private

				this.applyTextDir(node);
				array.forEach(node.children, function(child){ this._setAutoTextDir(child); }, this);
			},

			_setTextDirAttr: function(/*String*/ textDir){
				// summary:
				//		Setter for textDir.
				// description:
				//		Users shouldn't call this function; they should be calling
				//		set('textDir', value)
				// tags:
				//		private

				this._set("textDir", textDir);

				if (textDir == "auto"){
					this._setAutoTextDir(this.containerNode);
				}else{
					this.containerNode.dir = this.textDir;
				}
			}
		});
	}

	dijit.showTooltip = function(innerHTML, aroundNode, position, rtl, textDir){
		// summary:
		//		Static method to display tooltip w/specified contents in specified position.
		//		See description of dijit/Tooltip.defaultPosition for details on position parameter.
		//		If position is not specified then dijit/Tooltip.defaultPosition is used.
		// innerHTML: String
		//		Contents of the tooltip
		// aroundNode: place.__Rectangle
		//		Specifies that tooltip should be next to this node / area
		// position: String[]?
		//		List of positions to try to position tooltip (ex: ["right", "above"])
		// rtl: Boolean?
		//		Corresponds to `WidgetBase.dir` attribute, where false means "ltr" and true
		//		means "rtl"; specifies GUI direction, not text direction.
		// textDir: String?
		//		Corresponds to `WidgetBase.textdir` attribute; specifies direction of text.

		// After/before don't work, but for back-compat convert them to the working after-centered, before-centered.
		// Possibly remove this in 2.0.   Alternately, get before/after to work.
		if(position){
			position = array.map(position, function(val){
				return {after: "after-centered", before: "before-centered"}[val] || val;
			});
		}

		if(!Tooltip._masterTT){ dijit._masterTT = Tooltip._masterTT = new MasterTooltip(); }
		return Tooltip._masterTT.show(innerHTML, aroundNode, position, rtl, textDir);
	};

	dijit.hideTooltip = function(aroundNode){
		// summary:
		//		Static method to hide the tooltip displayed via showTooltip()
		return Tooltip._masterTT && Tooltip._masterTT.hide(aroundNode);
	};

	var Tooltip = declare("dijit.Tooltip", _Widget, {
		// summary:
		//		Pops up a tooltip (a help message) when you hover over a node.
		//		Also provides static show() and hide() methods that can be used without instantiating a dijit/Tooltip.

		// label: String
		//		HTML to display in the tooltip.
		//		Specified as innerHTML when creating the widget from markup.
		label: "",

		// showDelay: Integer
		//		Number of milliseconds to wait after hovering over/focusing on the object, before
		//		the tooltip is displayed.
		showDelay: 400,

		// connectId: String|String[]|DomNode|DomNode[]
		//		Id of domNode(s) to attach the tooltip to.
		//		When user hovers over specified dom node(s), the tooltip will appear.
		connectId: [],

		// position: String[]
		//		See description of `dijit/Tooltip.defaultPosition` for details on position parameter.
		position: [],

		// selector: String?
		//		CSS expression to apply this Tooltip to descendants of connectIds, rather than to
		//		the nodes specified by connectIds themselves.    Useful for applying a Tooltip to
		//		a range of rows in a table, tree, etc.   Use in conjunction with getContent() parameter.
		//		Ex: connectId: myTable, selector: "tr", getContent: function(node){ return ...; }
		//
		//		The application must require() an appropriate level of dojo/query to handle the selector.
		selector: "",

		// TODO: in 2.0 remove support for multiple connectIds.   selector gives the same effect.
		// So, change connectId to a "", remove addTarget()/removeTarget(), etc.

		_setConnectIdAttr: function(/*String|String[]|DomNode|DomNode[]*/ newId){
			// summary:
			//		Connect to specified node(s)

			// Remove connections to old nodes (if there are any)
			array.forEach(this._connections || [], function(nested){
				array.forEach(nested, function(handle){ handle.remove(); });
			}, this);

			// Make array of id's to connect to, excluding entries for nodes that don't exist yet, see startup()
			this._connectIds = array.filter(lang.isArrayLike(newId) ? newId : (newId ? [newId] : []),
					function(id){ return dom.byId(id, this.ownerDocument); }, this);

			// Make connections
			this._connections = array.map(this._connectIds, function(id){
				var node = dom.byId(id, this.ownerDocument),
					selector = this.selector,
					delegatedEvent = selector ?
						function(eventType){ return on.selector(selector, eventType); } :
						function(eventType){ return eventType; },
					self = this;
				return [
					on(node, delegatedEvent(mouse.enter), function(){
						self._onHover(this);
					}),
					on(node, delegatedEvent("focusin"), function(){
						self._onHover(this);
					}),
					on(node, delegatedEvent(mouse.leave), lang.hitch(self, "_onUnHover")),
					on(node, delegatedEvent("focusout"), lang.hitch(self, "_onUnHover"))
				];
			}, this);

			this._set("connectId", newId);
		},

		addTarget: function(/*OomNode|String*/ node){
			// summary:
			//		Attach tooltip to specified node if it's not already connected

			// TODO: remove in 2.0 and just use set("connectId", ...) interface

			var id = node.id || node;
			if(array.indexOf(this._connectIds, id) == -1){
				this.set("connectId", this._connectIds.concat(id));
			}
		},

		removeTarget: function(/*DomNode|String*/ node){
			// summary:
			//		Detach tooltip from specified node

			// TODO: remove in 2.0 and just use set("connectId", ...) interface

			var id = node.id || node,	// map from DOMNode back to plain id string
				idx = array.indexOf(this._connectIds, id);
			if(idx >= 0){
				// remove id (modifies original this._connectIds but that's OK in this case)
				this._connectIds.splice(idx, 1);
				this.set("connectId", this._connectIds);
			}
		},

		buildRendering: function(){
			this.inherited(arguments);
			domClass.add(this.domNode,"dijitTooltipData");
		},

		startup: function(){
			this.inherited(arguments);

			// If this tooltip was created in a template, or for some other reason the specified connectId[s]
			// didn't exist during the widget's initialization, then connect now.
			var ids = this.connectId;
			array.forEach(lang.isArrayLike(ids) ? ids : [ids], this.addTarget, this);
		},

		getContent: function(/*DomNode*/ node){
			// summary:
			//		User overridable function that return the text to display in the tooltip.
			// tags:
			//		extension
			return this.label || this.domNode.innerHTML;
		},

		_onHover: function(/*DomNode*/ target){
			// summary:
			//		Despite the name of this method, it actually handles both hover and focus
			//		events on the target node, setting a timer to show the tooltip.
			// tags:
			//		private
			if(!this._showTimer){
				this._showTimer = this.defer(function(){ this.open(target); }, this.showDelay);
			}
		},

		_onUnHover: function(){
			// summary:
			//		Despite the name of this method, it actually handles both mouseleave and blur
			//		events on the target node, hiding the tooltip.
			// tags:
			//		private

			if(this._showTimer){
				this._showTimer.remove();
				delete this._showTimer;
			}
			this.close();
		},

		open: function(/*DomNode*/ target){
			// summary:
			//		Display the tooltip; usually not called directly.
			// tags:
			//		private

			if(this._showTimer){
				this._showTimer.remove();
				delete this._showTimer;
			}

			var content = this.getContent(target);
			if(!content){
				return;
			}
			Tooltip.show(content, target, this.position, !this.isLeftToRight(), this.textDir);

			this._connectNode = target;		// _connectNode means "tooltip currently displayed for this node"
			this.onShow(target, this.position);
		},

		close: function(){
			// summary:
			//		Hide the tooltip or cancel timer for show of tooltip
			// tags:
			//		private

			if(this._connectNode){
				// if tooltip is currently shown
				Tooltip.hide(this._connectNode);
				delete this._connectNode;
				this.onHide();
			}
			if(this._showTimer){
				// if tooltip is scheduled to be shown (after a brief delay)
				this._showTimer.remove();
				delete this._showTimer;
			}
		},

		onShow: function(/*===== target, position =====*/){
			// summary:
			//		Called when the tooltip is shown
			// tags:
			//		callback
		},

		onHide: function(){
			// summary:
			//		Called when the tooltip is hidden
			// tags:
			//		callback
		},

		destroy: function(){
			this.close();

			// Remove connections manually since they aren't registered to be removed by _WidgetBase
			array.forEach(this._connections || [], function(nested){
				array.forEach(nested, function(handle){ handle.remove(); });
			}, this);

			this.inherited(arguments);
		}
	});

	Tooltip._MasterTooltip = MasterTooltip;		// for monkey patching
	Tooltip.show = dijit.showTooltip;		// export function through module return value
	Tooltip.hide = dijit.hideTooltip;		// export function through module return value

	Tooltip.defaultPosition = ["after-centered", "before-centered"];

	/*=====
	lang.mixin(Tooltip, {
		 // defaultPosition: String[]
		 //		This variable controls the position of tooltips, if the position is not specified to
		 //		the Tooltip widget or *TextBox widget itself.  It's an array of strings with the values
		 //		possible for `dijit/place.around()`.   The recommended values are:
		 //
		 //		- before-centered: centers tooltip to the left of the anchor node/widget, or to the right
		 //		  in the case of RTL scripts like Hebrew and Arabic
		 //		- after-centered: centers tooltip to the right of the anchor node/widget, or to the left
		 //		  in the case of RTL scripts like Hebrew and Arabic
		 //		- above-centered: tooltip is centered above anchor node
		 //		- below-centered: tooltip is centered above anchor node
		 //
		 //		The list is positions is tried, in order, until a position is found where the tooltip fits
		 //		within the viewport.
		 //
		 //		Be careful setting this parameter.  A value of "above-centered" may work fine until the user scrolls
		 //		the screen so that there's no room above the target node.   Nodes with drop downs, like
		 //		DropDownButton or FilteringSelect, are especially problematic, in that you need to be sure
		 //		that the drop down and tooltip don't overlap, even when the viewport is scrolled so that there
		 //		is only room below (or above) the target node, but not both.
	 });
	=====*/
	return Tooltip;
});


text:
Que supports the use of multiple queues in a single job table. This feature is intended to support the case where multiple applications (with distinct codebases) are sharing the same database. For instance, you might have a separate Ruby application that handles only processing credit cards. In that case, you can run that application's workers against a specific queue:

```shell
QUE_QUEUE=credit_cards rake que:work
```

Then you can set jobs to be enqueued in that queue specifically:

```ruby
ProcessCreditCard.enqueue current_user.id, :queue => 'credit_cards'

# Or:

class ProcessCreditCard < Que::Job
  # Set a default queue for this job class; this can be overridden by
  # passing the :queue parameter to enqueue like above.
  @queue = 'credit_cards'
end
```

In some cases, the ProcessCreditCard class may not be defined in the application that is enqueueing the job. In that case, you can specify the job class as a string:

```ruby
Que.enqueue current_user.id, :job_class => 'ProcessCreditCard', :queue => 'credit_cards'
```


text:
package org.datagr4m.drawing.editors.tables;

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

import javax.swing.table.AbstractTableModel;

public class JItemTableModel<T> extends AbstractTableModel {
    private static final long serialVersionUID = -7751624539918393034L;
    protected List<JItemTableEntry<T>> entries;
    protected static String[] columnNames = {
            "Item"/*,
            "Front",
            "Back"*/ };
    /*private static Comparator<?> comparator[]= {
            new NetworkInterfaceComparator(),
            new DeviceComparator()};*/

    public JItemTableModel(){
    }

    public JItemTableModel(List<T> items){
        setItems(items);
    }

    public List<JItemTableEntry<T>> getEntries(){
        return entries;
    }

    public JItemTableEntry<T> getEntry(Integer id){
        return entries.get(id);
    }

    public void setItems(List<T> items){
        entries = new ArrayList<JItemTableEntry<T>>();
        for(T device: items){
            entries.add( new JItemTableEntry<T>(device) );
        }
    }

    @Override
	public int getColumnCount() {
        return columnNames.length;
    }

    @Override
	public int getRowCount() {
        if( entries != null )
            return entries.size();
        return 0;
    }

    @Override
	public String getColumnName(int col) {
        return columnNames[col];
    }

/*    public static Comparator<?> getColumnComparator(int col){
        return comparator[col];
    }*/

    @Override
	public Object getValueAt(int row, int col) {
        if( entries != null ){
            JItemTableEntry<T> entry = entries.get(row);
            if(col == 0)
                return entry.getItem().toString();
        }
        return null;
    }

    @Override
	@SuppressWarnings({ "unchecked", "rawtypes" })
    public Class getColumnClass(int c) {
        if(c==0)
            return String.class;
        return String.class;
    }

    @Override
	public boolean isCellEditable(int row, int col) {
        return false;
    }
}


text:
<?php

namespace Symfony\Component\Mime\Tests\Part\Multipart;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Mime\Part\Multipart\FormDataPart;
use Symfony\Component\Mime\Part\TextPart;

class FormDataPartTest extends TestCase
{
    public function testConstructor()
    {
        $r = new \ReflectionProperty(TextPart::class, 'encoding');
        $r->setAccessible(true);

        $b = new TextPart('content');
        $c = DataPart::fromPath($file = __DIR__.'/../../Fixtures/mimetypes/test.gif');
        $f = new FormDataPart([
            'foo' => $content = 'very very long content that will not be cut even if the length is way more than 76 characters, ok?',
            'bar' => clone $b,
            'baz' => clone $c,
        ]);
        $this->assertEquals('multipart', $f->getMediaType());
        $this->assertEquals('form-data', $f->getMediaSubtype());
        $t = new TextPart($content, 'utf-8', 'plain', '8bit');
        $t->setDisposition('form-data');
        $t->setName('foo');
        $t->getHeaders()->setMaxLineLength(PHP_INT_MAX);
        $b->setDisposition('form-data');
        $b->setName('bar');
        $b->getHeaders()->setMaxLineLength(PHP_INT_MAX);
        $r->setValue($b, '8bit');
        $c->setDisposition('form-data');
        $c->setName('baz');
        $c->getHeaders()->setMaxLineLength(PHP_INT_MAX);
        $r->setValue($c, '8bit');
        $this->assertEquals([$t, $b, $c], $f->getParts());
    }

    public function testNestedArrayParts()
    {
        $p1 = new TextPart('content', 'utf-8', 'plain', '8bit');
        $f = new FormDataPart([
            'foo' => clone $p1,
            'bar' => [
                'baz' => [
                    clone $p1,
                    'qux' => clone $p1,
                ],
            ],
        ]);

        $this->assertEquals('multipart', $f->getMediaType());
        $this->assertEquals('form-data', $f->getMediaSubtype());

        $p1->setName('foo');
        $p1->setDisposition('form-data');

        $p2 = clone $p1;
        $p2->setName('bar[baz][0]');

        $p3 = clone $p1;
        $p3->setName('bar[baz][qux]');

        $this->assertEquals([$p1, $p2, $p3], $f->getParts());
    }

    public function testToString()
    {
        $p = DataPart::fromPath($file = __DIR__.'/../../Fixtures/mimetypes/test.gif');
        $this->assertEquals(base64_encode(file_get_contents($file)), $p->bodyToString());
    }

    public function testContentLineLength()
    {
        $f = new FormDataPart([
            'foo' => new DataPart($foo = str_repeat('foo', 1000), 'foo.txt', 'text/plain'),
            'bar' => $bar = str_repeat('bar', 1000),
        ]);
        $parts = $f->getParts();
        $this->assertEquals($foo, $parts[0]->bodyToString());
        $this->assertEquals($bar, $parts[1]->bodyToString());
    }

    public function testBoundaryContentTypeHeader()
    {
        $f = new FormDataPart([
            'file' => new DataPart('data.csv', 'data.csv', 'text/csv'),
        ]);
        $headers = $f->getPreparedHeaders()->toArray();
        $this->assertMatchesRegularExpression(
            '/^Content-Type: multipart\/form-data; boundary=[a-zA-Z0-9\-_]{8}$/',
            $headers[0]
        );
    }
}


text:
@class QBRTCVideoCapture;

@interface QBRTCLocalVideoTrack : QBRTCMediaStreamTrack

@property (nonatomic, weak) QBRTCVideoCapture *videoCapture;

/// Init is not a supported initializer for this class
- (instancetype)init __attribute__((unavailable("init is not a supported initializer for this class.")));

@end