text:
package org.apache.ignite.internal.processors.cache.persistence;

import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.Function;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.cluster.ClusterState;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.DataRegionConfiguration;
import org.apache.ignite.configuration.DataStorageConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.internal.IgniteEx;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.cache.query.index.IndexProcessor;
import org.apache.ignite.internal.managers.indexing.IndexesRebuildTask;
import org.apache.ignite.internal.processors.cache.CacheGroupContext;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.IgniteCacheUpdateSqlQuerySelfTest;
import org.apache.ignite.internal.processors.cache.persistence.defragmentation.DefragmentationFileUtils;
import org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager;
import org.apache.ignite.internal.processors.query.schema.IndexRebuildCancelToken;
import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.internal.visor.verify.ValidateIndexesClosure;
import org.apache.ignite.internal.visor.verify.VisorValidateIndexesJobResult;
import org.apache.ignite.testframework.junits.WithSystemProperty;
import org.jetbrains.annotations.Nullable;
import org.junit.Test;

import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL;
import static org.apache.ignite.cache.CacheAtomicityMode.TRANSACTIONAL_SNAPSHOT;
import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.DFLT_STORE_DIR;

/**
 * Defragmentation tests with enabled ignite-indexing.
 */
public class IgnitePdsIndexingDefragmentationTest extends IgnitePdsDefragmentationTest {
    /** Use MVCC in tests. */
    private static final String USE_MVCC = "USE_MVCC";

    /** {@inheritDoc} */
    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);

        cfg.setConsistentId(igniteInstanceName);

        DataStorageConfiguration dsCfg = new DataStorageConfiguration();
        dsCfg.setWalSegmentSize(4 * 1024 * 1024);

        dsCfg.setDefaultDataRegionConfiguration(
            new DataRegionConfiguration()
                .setInitialSize(100L * 1024 * 1024)
                .setMaxSize(1024L * 1024 * 1024)
                .setPersistenceEnabled(true)
        );

        cfg.setDataStorageConfiguration(dsCfg);

        CacheConfiguration<?, ?> cache1Cfg = new CacheConfiguration<>(DEFAULT_CACHE_NAME)
            .setAtomicityMode(TRANSACTIONAL)
            .setGroupName(GRP_NAME)
            .setIndexedTypes(
                IgniteCacheUpdateSqlQuerySelfTest.AllTypes.class, byte[].class,
                Integer.class, byte[].class
            )
            .setAffinity(new RendezvousAffinityFunction(false, PARTS));

        CacheConfiguration<?, ?> cache2Cfg = new CacheConfiguration<>(CACHE_2_NAME)
            .setAtomicityMode(TRANSACTIONAL)
            .setGroupName(GRP_NAME)
            .setIndexedTypes(
                IgniteCacheUpdateSqlQuerySelfTest.AllTypes.class, byte[].class,
                Integer.class, byte[].class
            )
            .setAffinity(new RendezvousAffinityFunction(false, PARTS));

        if (Boolean.TRUE.toString().equals(System.getProperty(USE_MVCC))) {
            cache1Cfg.setAtomicityMode(TRANSACTIONAL_SNAPSHOT);
            cache2Cfg.setAtomicityMode(TRANSACTIONAL_SNAPSHOT);
        } else
            cache2Cfg.setExpiryPolicyFactory(new PolicyFactory());

        cfg.setCacheConfiguration(cache1Cfg, cache2Cfg);

        return cfg;
    }

    /** {@inheritDoc} */
    @Override protected void afterTest() throws Exception {
        super.afterTest();

        IndexProcessor.idxRebuildCls = null;
    }

    /**
     * Fill cache, remove half of the entries, defragmentate PDS and check index.
     *
     * @param keyMapper Function that provides key based on the index of entry.
     * @param <T> Type of cache key.
     *
     * @throws Exception If failed.
     */
    private <T> void test(Function<Integer, T> keyMapper) throws Exception {
        IgniteEx ig = startGrid(0);

        ig.cluster().state(ClusterState.ACTIVE);

        fillCache(keyMapper, ig.cache(DEFAULT_CACHE_NAME));

        forceCheckpoint(ig);

        createMaintenanceRecord();

        stopGrid(0);

        File dbWorkDir = U.resolveWorkDirectory(U.defaultWorkDirectory(), DFLT_STORE_DIR, false);
        File nodeWorkDir = new File(dbWorkDir, U.maskForFileName(ig.name()));
        File workDir = new File(nodeWorkDir, FilePageStoreManager.CACHE_GRP_DIR_PREFIX + GRP_NAME);

        long oldIdxFileLen = new File(workDir, FilePageStoreManager.INDEX_FILE_NAME).length();

        startGrid(0);

        waitForDefragmentation(0);

        long newIdxFileLen = new File(workDir, FilePageStoreManager.INDEX_FILE_NAME).length();

        assertTrue(
            "newIdxFileLen=" + newIdxFileLen + ", oldIdxFileLen=" + oldIdxFileLen,
            newIdxFileLen <= oldIdxFileLen
        );

        File completionMarkerFile = DefragmentationFileUtils.defragmentationCompletionMarkerFile(workDir);
        assertTrue(Arrays.toString(workDir.listFiles()), completionMarkerFile.exists());

        stopGrid(0);

        IndexProcessor.idxRebuildCls = CaptureRebuildGridQueryIndexing.class;

        IgniteEx node = startGrid(0);

        awaitPartitionMapExchange();

        CaptureRebuildGridQueryIndexing idxRebuild = (CaptureRebuildGridQueryIndexing) node.context().indexProcessor().idxRebuild();

        assertFalse(idxRebuild.didRebuildIndexes());

        IgniteCache<Object, Object> cache = node.cache(DEFAULT_CACHE_NAME);

        assertFalse(completionMarkerFile.exists());

        validateIndexes(node);

        for (int k = 0; k < ADDED_KEYS_COUNT; k++)
            cache.get(keyMapper.apply(k));
    }

    /**
     * Test that indexes are correct.
     *
     * @param node Node.
     * @throws Exception If failed.
     */
    private static void validateIndexes(IgniteEx node) throws Exception {
        ValidateIndexesClosure clo = new ValidateIndexesClosure(
            () -> false,
            Collections.singleton(DEFAULT_CACHE_NAME),
            0,
            0,
            false,
            true
        );

        node.context().resource().injectGeneric(clo);

        VisorValidateIndexesJobResult call = clo.call();

        assertFalse(call.hasIssues());
    }

    /**
     * Test using integer keys.
     *
     * @throws Exception If failed.
     */
    @Test
    public void testIndexingWithIntegerKey() throws Exception {
        test(Function.identity());
    }

    /**
     * Test using complex keys (integer and string).
     *
     * @throws Exception If failed.
     */
    @Test
    public void testIndexingWithComplexKey() throws Exception {
        test(integer -> new IgniteCacheUpdateSqlQuerySelfTest.AllTypes((long)integer));
    }

    /**
     * Test using integer keys.
     *
     * @throws Exception If failed.
     */
    @Test
    @WithSystemProperty(key = USE_MVCC, value = "true")
    public void testIndexingWithIntegerKeyAndMVCC() throws Exception {
        test(Function.identity());
    }

    /**
     * Test using complex keys (integer and string).
     *
     * @throws Exception If failed.
     */
    @Test
    @WithSystemProperty(key = USE_MVCC, value = "true")
    public void testIndexingWithComplexKeyAndMVCC() throws Exception {
        test(integer -> new IgniteCacheUpdateSqlQuerySelfTest.AllTypes((long)integer));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testMultipleIndexes() throws Exception {
        startGrid(0).cluster().state(ClusterState.ACTIVE);

        IgniteCache<?, ?> cache = grid(0).cache(DEFAULT_CACHE_NAME);

        cache.query(new SqlFieldsQuery("CREATE TABLE TEST (ID INT PRIMARY KEY, VAL_INT INT, VAL_OBJ LONG)"));

        final String cacheName = "SQL_default_TEST";

        cache.query(new SqlFieldsQuery("CREATE INDEX TEST_VAL_INT ON TEST(VAL_INT)"));

        cache.query(new SqlFieldsQuery("CREATE INDEX TEST_VAL_OBJ ON TEST(VAL_OBJ)"));

        for (int i = 0; i < ADDED_KEYS_COUNT; i++)
            cache.query(new SqlFieldsQuery("INSERT INTO TEST VALUES (?, ?, ?)").setArgs(i, i, (long)i));

        cache.query(new SqlFieldsQuery("DELETE FROM TEST WHERE MOD(ID, 2) = 0"));

        createMaintenanceRecord(cacheName);

        CacheGroupContext grp = grid(0).context().cache().cacheGroup(CU.cacheId(cacheName));

        forceCheckpoint();

        // Restart first time.
        stopGrid(0);

        defragmentAndValidateSizesDecreasedAfterDefragmentation(0, grp);

        startGrid(0);

        // Reinit cache object.
        cache = grid(0).cache(DEFAULT_CACHE_NAME);

        assertTrue(explainQuery(cache, "EXPLAIN SELECT * FROM TEST WHERE ID > 0").contains("_key_pk_proxy"));

        cache.query(new SqlFieldsQuery("SELECT * FROM TEST WHERE ID > 0")).getAll();

        assertTrue(explainQuery(cache, "EXPLAIN SELECT * FROM TEST WHERE VAL_INT > 0").contains("test_val_int"));

        cache.query(new SqlFieldsQuery("SELECT * FROM TEST WHERE VAL_INT > 0")).getAll();

        assertTrue(explainQuery(cache, "EXPLAIN SELECT * FROM TEST WHERE VAL_OBJ > 0").contains("test_val_obj"));

        cache.query(new SqlFieldsQuery("SELECT * FROM TEST WHERE VAL_OBJ > 0")).getAll();
    }

    /** */
    private static String explainQuery(IgniteCache<?, ?> cache, String qry) {
        return cache
            .query(new SqlFieldsQuery(qry))
            .getAll()
            .get(0)
            .get(0)
            .toString()
            .toLowerCase();
    }

    /**
     * IgniteH2Indexing that captures index rebuild operations.
     */
    public static class CaptureRebuildGridQueryIndexing extends IndexesRebuildTask {
        /**
         * Whether index rebuild happened.
         */
        private boolean rebuiltIndexes;

        /** {@inheritDoc} */
        @Override @Nullable public IgniteInternalFuture<?> rebuild(
            GridCacheContext cctx,
            boolean force,
            IndexRebuildCancelToken cancelTok
        ) {
            IgniteInternalFuture<?> future = super.rebuild(cctx, force, cancelTok);
            rebuiltIndexes = future != null;

            return future;
        }

        /**
         * Get index rebuild flag.
         *
         * @return Whether index rebuild happened.
         */
        public boolean didRebuildIndexes() {
            return rebuiltIndexes;
        }
    }
}


text:
.group:after {
	content: "";
	display: table;
	clear: both;
}

.ci-media-manager-gallery .ci-upload-to-gallery-preview {
	margin: 10px 0px;
	padding: 5px 0px;
	border: 1px solid #DFDFDF;
	border-radius: 3px 3px 3px 3px;
}

.ci-upload-to-gallery-preview-text {
	font-size: 26px;
	color: #ccc;
}

.thumb + .ci-upload-to-gallery-preview-text {
	display: none;
}

.ci-media-manager-gallery .thumb {
	margin: 5px;
	padding: 3px;
	border: 1px solid #DFDFDF;
	border-radius: 3px 3px 3px 3px;
	float: left;
	width: 100px;
	height: 100px;
	position: relative;
	overflow: hidden;
}

.ci-media-manager-gallery .thumb img {
	max-width: 100px;
}

.ci-media-manager-gallery .thumb .close {
	background-color: #FFFFFF;
	background-position: -96px 4px;
	border-radius: 3px 3px 3px 3px;
	border-width: 0;
	box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3);
	color: #464646;
	display: none;
	font-size: 20px;
	line-height: 20px;
	padding: 0;
	position: absolute;
	right: 5px;
	text-align: center;
	text-decoration: none;
	top: 5px;
	height: 21px;
	width: 21px;
}
.ci-media-manager-gallery .thumb:hover .close {
	display: block;
}
.ci-media-manager-gallery .ci-upload-to-gallery-preview p {
	margin: 5px;
	text-align: center;
}

.ci-upload-preview .upload-preview {
	display: block;
	max-width: 100px;
	position: relative;
}

.ci-upload-preview .upload-preview img {
	border-radius: 3px 3px 3px 3px;
	width: 100px;
	height: 100px;
	position: relative;
	overflow: hidden;
}

.ci-upload-preview .upload-preview .close {
	background-color: #FFFFFF;
	background-position: -96px 4px;
	border-radius: 3px 3px 3px 3px;
	border-width: 0;
	box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.3);
	color: #464646;
	display: none;
	font-size: 20px;
	line-height: 20px;
	padding: 0;
	position: absolute;
	right: 5px;
	text-align: center;
	text-decoration: none;
	top: 5px;
	height: 21px;
	width: 21px;
}
.ci-upload-preview .upload-preview:hover .close {
	display: block;
}

/* Custom field wrappers and tabs */
.ci-cf-wrap { margin-top:12px; }
.ci-cf-section { clear:both; border:solid 1px #e4e4e4; padding:20px; border-radius:2px; position: relative; z-index: 1;}
.ci-cf-section *+* { margin-bottom: 0; }
.ci-cf-section input[type='text'], .ci-cf-section select { min-width: 200px; }
.ci-cf-section .ci-field-group { margin: 0 0 15px 0; }
.ci-cf-section label { display: block; margin-bottom: 5px; }
.ci-cf-section .ci-field-radio label, .ci-cf-section .ci-field-checkbox label { display: inline-block; margin: 0; }
.ci-cf-section textarea { min-height: 100px; }
.ci-cf-inside :last-child { margin-bottom: 0; }
.ci-cf-guide { background: #fffce6; color: #948832; font-size: 12px; border: solid 1px #eeeac9; padding:15px; margin:0 0 15px 0; }
ol.ci-cf-guide { list-style-position: inside; }
.ci-cf-guide code {  background: #f8e19d; border-radius:2px; border:solid 1px #e5cd84; color: #aa5827; }
.ci-cf-guide em { font-family: Consolas,Monaco,monospace; font-style: normal; display:inline-block; padding: 0 3px; margin: 0 1px; border-radius:2px; background: #f1f1f1; color:#fff; border:solid 1px #e6e6e6; color: #333; }
.ci-cf-title { display: none; margin:0 0 10px 0 !important; padding: 0 !important; }
.ci-cf-tabs { margin:0; position:relative; z-index: 3; }
.ci-cf-tab { float:left; margin:0 -1px 0 0; padding:14px 12px 12px 12px; position:relative; top: 1px; z-index: 4; border:solid 1px #e4e4e4; background:#f2f2f2; color:#7e7e7e; cursor:pointer; border-radius:2px;}
.ci-cf-tab:hover { background: #f8f8f8 ;}
.ci-cf-tab-active, .ci-cf-tab-active:hover { border-top: solid 3px #0073AA; border-bottom: solid 1px #fff; background:#fff; color:#23282d; padding: 12px;}
.ci-cf-wrap .wp-picker-container { display: block; margin-top: 3px; }

redpajama_set_name: RedPajamaGithub


text:
<!--
Copyright 2020 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<!--
This file is used to generate a comprehensive list of Omnibox histograms
along with a detailed description for each histogram.

For best practices on writing histogram descriptions, see
https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md

Please follow the instructions in the OWNERS file in this directory to find a
reviewer. If no OWNERS file exists, please consider signing up at
go/reviewing-metrics (Googlers only), as all subdirectories are expected to
have an OWNERS file. As a last resort you can send the CL to
chromium-metrics-reviews@google.com.
-->

<histogram-configuration>

<histograms>

<histogram name="Omnibox.AcceptedKeywordSuggestion"
    enum="OmniboxEnteredKeywordMode2" expires_after="2022-11-10">
  <owner>yoangela@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Records number of accepted keyword searches enumerated by how the user
    entered the keyword mode. See also Omnibox.EnteredKeywordMode2 for the total
    number of times a user enters keyword mode whether or not the keyword
    suggestion was accepted. Note that this only records when a user accepts a
    search suggestion for the keyword search engine and does not record for URL
    suggestions even if the user is in keyword mode.
  </summary>
</histogram>

<histogram name="Omnibox.AnswerParseSuccess" enum="BooleanSuccess"
    expires_after="2022-05-08">
  <owner>jdonnelly@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    For each answer received in suggest responses, the number that are
    well-formed and contain all the required elements.
  </summary>
</histogram>

<histogram name="Omnibox.AnswerParseType" enum="SuggestionAnswerType"
    expires_after="2022-06-05">
  <owner>jdonnelly@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The number of times each omnibox suggestion answer type (e.g., weather,
    sports score) was received and parsed successfully. Can be normalized with
    the count of emits to Omnibox.SuggestRequest.Success.GoogleResponseTime,
    which counts all successful suggest responses from Google, not just those
    with answers attached. Note that GoogleResponseTime is technically off given
    that it will still count cases where we fail to extract, deserialize, or
    parse the response. But these cases are rare to non-existent.
  </summary>
</histogram>

<histogram name="Omnibox.BitmapFetchLatency" units="ms"
    expires_after="2022-05-08">
<!-- Name completed by histogram_suffixes name="Omnibox.BitmapFetchLatencyCacheSplit" -->

  <owner>manukh@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The time elapsed between the ChromeOmniboxClient requesting a suggestion's
    image to receiving the image. This includes both uncached and cached
    requests. See BitmapFetcher.Fetch and BitmapFetcher.Decode for what
    contributes to uncached images latency; however, the sum of those metrics
    can be greater than this metric as image prefetching begins before the
    ChromeOmniboxClient requests an image.
  </summary>
</histogram>

<histogram name="Omnibox.CharTypedToRepaintLatency" units="ms"
    expires_after="2022-05-08">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>asvitkine@chromium.org</owner>
  <summary>
    Records the time taken between a keystroke being typed in the omnibox and
    the text being painted. If there are multiple keystrokes before a paint,
    logs the time since the earliest one.

    This duration is composed of three parts:

    a) the time spent processing the initial input event

    b) the time spent for the repaint task to be scheduled on the message loop

    c) the time spent painting the Omnibox

    d) (on views platforms) the time until the pixels are actually composited

    There's a number of breakdown metrics to help diagnose a regression. First,
    Omnibox.CharTypedToRepaintLatency.ToPaint measures the combined time of (a)
    and (b). Omnibox.QueryTime2 is a good proxy for just (a). And there's also
    Omnibox.PaintTime that corresponds to (c). We don't have a direct metric for
    (d), but if neither Omnibox.CharTypedToRepaintLatency.ToPaint nor
    Omnibox.PaintTime regressed, then the regression must be in (d).

    Note: The semantics of this metric on views platforms changed in M62, as
    previously time (d) was not included in the metric.
  </summary>
</histogram>

<histogram name="Omnibox.CharTypedToRepaintLatency.InsertToPresent" units="ms"
    expires_after="2022-04-24">
  <owner>asvitkine@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    A refinement of Omnibox.CharTypedToRepaintLatency metric. It measures the
    time between the first character insertion in a series that happen during a
    frame, to the time the compositor reports the text was rendered on-screen.
    Compositor-provided timestamps are used for this version of the metric, so
    it is expected to be more accurate: the baseline CharTypedToRepaintLatency
    uses now() from when the subsequent has-processed notification arrives back
    on the UI thread, which may overestimate user-visible latency.
  </summary>
</histogram>

<histogram name="Omnibox.CharTypedToRepaintLatency.PaintToPresent" units="ms"
    expires_after="2021-06-30">
  <owner>asvitkine@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    Records the time between when OnPaint() is called to the time the compositor
    reports pixels were successfully drawn to the screen. This a subset of the
    time reported in Omnibox.CharTypedToRepaintLatency.InsertToPresent.
  </summary>
</histogram>

<histogram name="Omnibox.CharTypedToRepaintLatency.ToPaint" units="ms"
    expires_after="2022-04-24">
  <owner>asvitkine@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    Records the time taken between a keystroke being typed in the omnibox and
    the time when we're ready to paint the omnibox. This is a breakdown
    diagnostic metric for Omnibox.CharTypedToRepaintLatency, to help diagnose
    regressions in that metric. See that metric's description for more info.
  </summary>
</histogram>

<histogram name="Omnibox.ClipboardSuggestionRemovedAge" units="ms"
    expires_after="2022-05-01">
  <owner>gangwu@chromium.org</owner>
  <owner>fgorski@chromium.org</owner>
  <summary>
    Recorded every time the clipboard suggestion is removed from omnibox
    suggestion list and the system clipboard. The value indicates the estimated
    age of the clipboard.
  </summary>
</histogram>

<histogram name="Omnibox.ClipboardSuggestionShownAge" units="ms"
    expires_after="2022-05-22">
  <owner>gangwu@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    Recorded every time the omnibox is focussed and recent content from the
    user's clipboard is suggested. The value indicates the estimated age of the
    clipboard. (If Chrome observed the clipboard modification, this age is
    exact. If Chrome did not observe the modification, then it's a conservative
    estimate: the last time Chrome observed a clipboard modification, which is
    certainly older than the current clipboard. If Chrome never observed a
    clipboard modification, no clipboard suggestion is shown, meaning this
    histogram will never be emitted to.)

    Intended to be compared with MobileOmnibox.PressedClipboardSuggestionAge.
  </summary>
</histogram>

<histogram name="Omnibox.ClipboardSuggestionShownNumTimes" units="units"
    expires_after="2022-05-29">
  <owner>gangwu@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    Recorded every time the omnibox is focussed and a recent content from the
    user's clipboard is suggested. The number emitted is the number of times the
    clipboard content has been suggested within the same session including the
    current time. Thus, the third time it is shown, we'll emit a three to this
    histogram, and this histogram will have previously seen emits of one and
    two. If the clipboard content was the same during a previous run of Chrome
    and this clipboard content was suggested during that run, those impressions
    are not counted. Also, if the clipboard content changes during a particular
    run of Chrome to other content, the omnibox is focused and that clipboard
    content is suggested, then content changes back and Chrome starts suggesting
    the older clipboard content again, the counts start again from scratch.
    Chrome only remembers the number of times the clipboard content was shown
    consecutively.

    This value is useful to compare with the number of times a clipboard
    suggestion has been shown when it is clicked. This value can be obtained
    from OmniboxEvent records in which the selected suggestion is from Clipboard
    provider. In those cases, look in the Clipboard provider's ProviderInfo
    field for |times_returned_results_in_session|. Note that at the time of this
    writing that OmniboxEvent logs aren't recorded in incognito whereas
    histograms are. Thus, the total counts will not be comparable, though the
    distributions should be.
  </summary>
</histogram>

<histogram name="Omnibox.ClipboardSuggestionShownWithCurrentURL"
    enum="BooleanPresent" expires_after="2022-10-01">
  <owner>gangwu@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    Recorded every time the omnibox is focussed and a recent content from the
    user's clipboard is suggested. The value indicates whether the current URL
    was shown (which would appear above the clipboard suggestion) or was absent
    (which ought to only happen when the omnibox is empty / the user is on the
    NTP).

    On Android, the total count for this histogram can be usefully compared with
    the count of the user action FocusLocation in order to determine the rate at
    which a clipboard suggestion is shown in the omnibox. To determine the same
    rate on iOS, one needs to compare this histogram's count with the sum of the
    user actions MobileFocusedOmniboxOnNtp, MobileFocusedFakeboxOnNtp, and
    MobileFocusedOmniboxNotOnNtp.

    Furthermore, on either platform, this histogram's count can be usefully
    compared with the count in the clipboard bucket of the
    Omnibox.SuggestionUsed.Provider histogram to determine the clickthrough rate
    on these suggestions.
  </summary>
</histogram>

<histogram name="Omnibox.CutOrCopyAllText" units="count"
    expires_after="2022-04-17">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The number of cut or copy commands on all selected text in the omnibox.
    Gathered on desktop platforms (Win, Mac, Linux, Chrome OS).
  </summary>
</histogram>

<histogram name="Omnibox.DocumentSuggest.Requests"
    enum="OmniboxDocumentSuggestRequests" expires_after="2022-04-10">
  <owner>manukh@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <owner>skare@chromium.org</owner>
  <summary>
    Counts the number of document suggest requests the omnibox sent, were
    invalidated, and were completed successfully.
  </summary>
</histogram>

<histogram name="Omnibox.DocumentSuggest.ResultCount" units="count"
    expires_after="2022-04-10">
  <owner>manukh@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <owner>skare@chromium.org</owner>
  <summary>
    Number of results returned in each document suggestion reply. Logged for
    successful requests where the provider returned a parseable result set.
  </summary>
</histogram>

<histogram name="Omnibox.ElisionConfig" enum="OmniboxElisionConfig"
    expires_after="M88">
  <obsolete>
    Removed 2020-10.
  </obsolete>
  <owner>livvielin@chromium.org</owner>
  <owner>tommycli@chromium.org</owner>
  <summary>
    The state of URL elision in the omnibox, e.g. URL default behavior,
    prevented by context menu option, or prevented by Chrome extension. This
    histogram is recorded the first time ShouldPreventElision is called on
    ChromeLocationBarModelDelegate with an existing profile. This occurs every
    time a browser window is open, including when opening a new profile or
    moving a tab to a new window. This metric measures the percentage of browser
    windows that use each type of elision behavior.
  </summary>
</histogram>

<histogram name="Omnibox.EnteredKeywordMode2" enum="OmniboxEnteredKeywordMode2"
    expires_after="2022-06-05">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The new enumeration of how many times users enter keyword hint mode
    "Search ___ for:" and how. Note that we don't recognize the
    changing of the keyword itself as entering keyword mode, if the user never
    left keyword mode e.g. if the user was arrowing around the suggestions, so
    we'll preserve the original keyword mode entry method in this case.
  </summary>
</histogram>

<histogram name="Omnibox.FocusResultedInNavigation" enum="BooleanNavigated"
    expires_after="2022-04-10">
  <owner>ender@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>tommycli@chromium.org</owner>
  <summary>
    This records whether user initiated navigation after focusing the Omnibox
    versus switches focus elsewhere without navigating. This metric includes
    accidental focus-then-losing-focus events, including brief ones. It also
    includes ones in which the user did not type any text or otherwise engage
    with the Omnibox. E.g., the user tabbing through all top Chrome UI controls
    will cause this metric to be recorded. If the user switches focus from the
    Chrome window to another window while the Omnibox is focussed, that also
    counts as a loss of focus.

    This metric is not recorded for the Realbox interactions.

    Recorded every time the Omnibox focus is cleared.
  </summary>
</histogram>

<histogram name="Omnibox.FocusToEditTime" units="ms" expires_after="2022-06-30">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The length of time between when a user focused on the omnibox and first
    modifies the omnibox.
  </summary>
</histogram>

<histogram name="Omnibox.FocusToOpenTimeAnyPopupState3" units="ms"
    expires_after="2022-05-08">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The length of time between when a user focused on the omnibox and opened an
    omnibox match (which could be what they typed or a suggestion). This is
    recorded regardless of whether the omnibox dropdown (a.k.a. popup) is open.
    It is not recorded if a match is opened without triggering a focus event,
    e.g., when a user drags a URL to the omnibox to navigate.

    To know how common this last condition is, compare the total count of this
    histogram to the total number of omnibox events.
  </summary>
</histogram>

<histogram name="Omnibox.HoverTime" units="ms" expires_after="2021-10-31">
  <owner>estark@chromium.org</owner>
  <owner>carlosil@chromium.org</owner>
  <summary>
    The time duration that the user hovers the mouse over the omnibox before
    exiting the hover or focusing the omnibox. Whenever the user's mouse enters
    the omnibox, this histogram is recorded when the mouse next exits or the
    omnibox is focused, whichever comes first. The recorded value is a delta
    from a timestamp noted when the user's mouse first entered the omnibox.
  </summary>
</histogram>

<histogram name="Omnibox.IconOrFaviconShown" enum="SuggestionIconOrFaviconType"
    expires_after="M83">
  <obsolete>
    Removed 2020-10.
  </obsolete>
  <owner>ender@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-android-omnibox-team@google.com</owner>
  <summary>
    Records suggestions decorated with specific icon or favicon at the time the
    user exited the omnibox. Exiting the omnibox includes navigating (to entered
    text or any suggestion), pressing the system back key, clearing omnibox,
    blanking screen / locking the phone (whether intentionally or due to
    inactivity), or closing the Chrome app. This metric is logged every time the
    omnibox is exited, including when no answer is present in the list of
    suggestions.

    This histogram is related to Omnibox.SuggestionUsed.IconOrFaviconType.
  </summary>
</histogram>

<histogram name="Omnibox.InputType" enum="OmniboxInputType"
    expires_after="2022-04-10">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The kind of input the user provided when using the omnibox to go somewhere.
    The type can be misleading. For example if the user typed 'http:/', it gets
    marked as a query because it cannot be opened as a URL even though the user
    probably wanted and selected a URL from the list of suggestions.

    In M-74 and earlier, this was only recorded if the user had no incognito
    windows open. In M-75 and later, it records all omnibox interactions
    regardless, in order to be consistent with how user actions and histograms
    are handled.
  </summary>
</histogram>

<histogram name="Omnibox.IsPasteAndGo" enum="Boolean"
    expires_after="2022-05-01">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Whether an omnibox interaction is a paste-and-search/paste-and-go action.
    (This histogram records both of these in the "True" bucket for
    this histogram because both of these are referred to as paste-and-go in the
    code.) These typically involve right-clicking in the omnibox and selecting
    that option from the dropdown.

    In M-74 and earlier, this was only recorded if the user had no incognito
    windows open. In M-75 and later, it records all omnibox interactions
    regardless, in order to be consistent with how user actions and histograms
    are handled.
  </summary>
</histogram>

<histogram name="Omnibox.IsPopupOpen" enum="Boolean" expires_after="2022-01-02">
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Whether the omnibox popup (a.k.a. dropdown) is open at the time the user
    used the omnibox to go somewhere. It can be closed if, for instance, the
    user clicked in the omnibox and hit return to reload the same page. Also,
    because paste-and-search/paste-and-go actions ignore the current content of
    the omnibox dropdown (if it is open) when they happen, we pretend the
    dropdown is closed when logging these.

    In M-74 and earlier, this was only recorded if the user had no incognito
    windows open. In M-75 and later, it records all omnibox interactions
    regardless, in order to be consistent with how user actions and histograms
    are handled.
  </summary>
</histogram>

<histogram name="Omnibox.JustDeletedText" enum="Boolean"
    expires_after="2022-04-10">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Whether the user deleted text immediately before selecting an omnibox
    suggestion. This is usually the result of pressing backspace or delete.

    In M-74 and earlier, this was only recorded if the user had no incognito
    windows open. In M-75 and later, it records all omnibox interactions
    regardless, in order to be consistent with how user actions and histograms
    are handled.
  </summary>
</histogram>

<histogram name="Omnibox.Lens.LensSupportStatus" enum="LensSupportStatus"
    expires_after="2021-11-18">
  <obsolete>
    Removed 2021-03. Switch to use Omnibox.LensSupportStatus.
  </obsolete>
  <owner>yusuyoutube@google.com</owner>
  <owner>benwgold@google.com</owner>
  <owner>fgorski@chromium.org</owner>
  <owner>wylieb@chromium.org</owner>
  <owner>lens-chrome@google.com</owner>
  <summary>
    Whether the user supports the camera assisted search with Google Lens and if
    not, the reason why. Recorded only if the feature is enabled when the
    omnibox is loaded.
  </summary>
</histogram>

<histogram name="Omnibox.Lens.TimeSpentInLens" units="ms" expires_after="M94">
  <obsolete>
    Removed 2021-03. Switch to use Omnibox.TimeSpentBeforeDismissLens.
  </obsolete>
  <owner>yusuyoutube@google.com</owner>
  <owner>benwgold@google.com</owner>
  <owner>fgorski@chromium.org</owner>
  <owner>wylieb@chromium.org</owner>
  <owner>lens-chrome@google.com</owner>
  <summary>
    Logged the elapsed time between the time when user enters the Google Lens
    and the time when user returns to Chrome. Only logged on Android.
  </summary>
</histogram>

<histogram name="Omnibox.LensSupportStatus" enum="LensSupportStatus"
    expires_after="2021-11-18">
  <obsolete>
    Removed 2021-05. Switch to use Lens.Omnibox.LensSupportStatus.
  </obsolete>
  <owner>yusuyoutube@google.com</owner>
  <owner>benwgold@google.com</owner>
  <owner>fgorski@chromium.org</owner>
  <owner>wylieb@chromium.org</owner>
  <owner>lens-chrome@google.com</owner>
  <summary>
    Whether the user supports the camera assisted search with Google Lens and if
    not, the reason why. Recorded only if the feature is enabled when the
    omnibox is loaded.
  </summary>
</histogram>

<histogram name="Omnibox.LocalHistoryZeroSuggest.AsyncDeleteTime" units="ms"
    expires_after="2022-06-05">
  <owner>mahmadi@chromium.org</owner>
  <owner>tommycli@chromium.org</owner>
  <summary>
    The length of time it takes for the corresponding URLs that would produce a
    deleted match to be queried asynchronously and deleted. Triggered when user
    deletes a local history zero-prefix suggestion.
  </summary>
</histogram>

<histogram name="Omnibox.LocalHistoryZeroSuggest.SearchTermsExtractedCount"
    units="count" expires_after="2022-06-05">
  <owner>mahmadi@chromium.org</owner>
  <owner>tommycli@chromium.org</owner>
  <summary>
    The number of search terms extracted from the keyword search terms database
    and examined (e.g., sorted) to produce local zero-prefix suggestions.
    Triggered when zero-prefix suggestions are enabled and requested as a result
    of user focus into the Omnibox or the Realbox on the NTP.
  </summary>
</histogram>

<histogram name="Omnibox.LocalHistoryZeroSuggest.SearchTermsExtractionTime"
    units="ms" expires_after="2022-06-05">
  <owner>mahmadi@chromium.org</owner>
  <owner>tommycli@chromium.org</owner>
  <summary>
    The length of time it takes to extract search terms from the keyword search
    terms database and examine (e.g., sort) them to produce local zero-prefix
    suggestions.
  </summary>
</histogram>

<histogram name="Omnibox.LocalHistoryZeroSuggest.SyncDeleteTime" units="ms"
    expires_after="2022-06-05">
  <owner>mahmadi@chromium.org</owner>
  <owner>tommycli@chromium.org</owner>
  <summary>
    The length of time it takes to handle the deletion request for a match and
    to update the list of provider matches synchronously. Triggered when user
    requests to delete a local history zero-prefix suggestion.
  </summary>
</histogram>

<histogram name="Omnibox.MatchStability.AsyncMatchChange2" units="position"
    expires_after="2022-07-29">
  <owner>tommycli@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    This tracks how unstable our matches are due to asynchronous updates.
    Whenever a dropdown position gets asynchronously set to a new match that's
    different from the old match, this histogram logs the index.

    We primarily care the default match, which is logged at index 0. All indices
    matter though, so we track the other indices too. When the number of matches
    changes asynchronously, matches that are removed are considered a
    "change" and logged here. Matches that are appended are less
    disruptive to the user, and are not logged.

    This is because this metric is primarily interested in how many times the
    user could be looking at a match with the intention of selecting it, and
    then it surprisingly goes away.

    Note that merely adding a new asynchronous provider will increase these
    counts. That's intentional. Swapping matches out annoys users, and to avoid
    this, we should do some things like: caching, update coaslescing, update
    deferral until next keystroke, provider timeouts, etc.

    This metric is designed to be normalized by the True count of
    Omnibox.Start.WantAsyncMatches, which will yield the number of match changes
    asynchronously per keystroke or other user gesture.
  </summary>
</histogram>

<histogram name="Omnibox.MatchStability.AsyncMatchChangedInAnyPosition"
    enum="BooleanChanged" expires_after="2022-07-29">
  <owner>tommycli@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    This tracks how unstable our matches are due to asynchronous updates.

    For each asynchronous autocomplete update, this histogram logs whether any
    match in any position has changed. Note: if the only change is new matches
    appended to the end of the list, that does not count as a change, since it's
    not very disruptive to the user.

    This metric is designed to be normalized by the True count of
    Omnibox.Start.WantAsyncMatches, which will yield the number of times any
    match changes asynchronously per keystroke or other user gesture.

    This histogram can be considered a boolean analogue to
    Omnibox.MatchStability.AsyncMatchChange2.
  </summary>
</histogram>

<histogram name="Omnibox.NumEvents" enum="UsedOmnibox"
    expires_after="2022-06-30">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The number of times users used the omnibox to go somewhere.

    In M-74 and earlier, this was only recorded if the user had no incognito
    windows open. In M-75 and later, it records all omnibox interactions
    regardless, in order to be consistent with how user actions and histograms
    are handled.
  </summary>
</histogram>

<histogram name="Omnibox.NumTypedTerms" units="terms"
    expires_after="2022-06-05">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The number of terms in the text the user entered in the omnibox when they
    used the omnibox to go somewhere. Terms are defined by splitting on
    whitespace. All values larger than 6 are recorded in bucket 6.

    In M-74 and earlier, this was only recorded if the user had no incognito
    windows open. In M-75 and later, it records all omnibox interactions
    regardless, in order to be consistent with how user actions and histograms
    are handled.
  </summary>
</histogram>

<histogram name="Omnibox.OnDeviceHeadSuggest.AsyncQueryTime" units="ms"
    expires_after="2021-12-12">
  <owner>cch@chromium.org</owner>
  <owner>suggest-2g@google.com</owner>
  <summary>
    Time it takes for omnibox on device head provider to fulfill the
    asynchronous suggest request.
  </summary>
</histogram>

<histogram name="Omnibox.OnDeviceHeadSuggest.ResultCount" units="count"
    expires_after="2021-12-12">
  <owner>cch@chromium.org</owner>
  <owner>suggest-2g@google.com</owner>
  <summary>
    The number of results returned by the on device head model which matches the
    user input. Note all numbers greater than 5 are recorded in bucket 5.
  </summary>
</histogram>

<histogram name="Omnibox.PaintTime" units="ms" expires_after="2022-05-01">
  <owner>asvitkine@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    Records the time to paint the omnibox contents. This is a subcomponent of
    Omnibox.CharTypedToRepaintLatency. Implemented on desktop platforms.
  </summary>
</histogram>

<histogram name="Omnibox.Paste" units="count" expires_after="2022-01-02">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The number of paste commands on the text in the omnibox. Reported every time
    a paste command is done.
  </summary>
</histogram>

<histogram name="Omnibox.PasteAndGo" units="count" expires_after="M89">
  <obsolete>
    Removed 2021-01 due to redundancy with Omnibox.IsPasteAndGo.
  </obsolete>
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    The number of paste-and-go commands on the text in the omnibox. Reported
    every time a paste-and-go command is done.
  </summary>
</histogram>

<histogram name="Omnibox.PedalShown" enum="SuggestionPedalType"
    expires_after="2022-06-05">
  <owner>jdonnelly@chromium.org</owner>
  <owner>orinj@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Counts the type (concept ID) of omnibox pedals shown when the user used the
    omnibox to go somewhere.

    Pedals are a button attached to a search suggestion that either navigate to
    a chrome:// URL or trigger a Chrome action (for example, opening the page
    translation dialog or opening a new window in Incognito mode).

    Note that, while it is uncommon, it is possible for multiple pedals to be
    shown at one time so this can't be used as a count of how many times a pedal
    or pedals were present.

    This histogram is related to Omnibox.SuggestionUsed.Pedal.
  </summary>
</histogram>

<histogram name="Omnibox.ProviderTime2" units="ms" expires_after="2022-04-17">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The length of time taken by the named provider"s synchronous pass.
  </summary>
</histogram>

<histogram name="Omnibox.QueryTime2" units="ms" expires_after="2022-05-08">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Time it takes for the omnibox to become responsive to user input after the
    user has typed N characters. This measures the time it takes to start all
    autocomplete providers (but not wait for the asynchronous ones to finish).
  </summary>
</histogram>

<histogram name="Omnibox.ResumeJourneyShown" units="position"
    expires_after="2022-08-24">
  <owner>tommycli@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Emits the position of any "Resume Journey" omnibox actions shown
    in the popup. The position index is 0-based, so an action shown in the
    topmost match is logged as value 0, consistent with
    Omnibox.SelectedPosition.

    Note that these are emitted when the user uses the omnibox to go somewhere.
    When that happens, one count is emitted per action visible in the popup.
    These are NOT emitted per-keystroke, in order to make this a suitable
    denominator for Omnibox.SuggestionUsed.ResumeJourney.
  </summary>
</histogram>

<histogram name="Omnibox.Search.OffTheRecord" enum="BooleanOffTheRecord"
    expires_after="2022-02-02">
  <owner>rhalavati@chromium.org</owner>
  <owner>chrome-incognito@google.com</owner>
  <summary>
    This histogram records the number of searches done from omnibox using
    default search engine on desktop and android devices, sliced based on being
    in regular mode or private modes.
  </summary>
</histogram>

<histogram name="Omnibox.SearchEngineType" enum="OmniboxSearchEngineType"
    expires_after="2022-06-05">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The type of search engine associated with a match opened from the omnibox.
  </summary>
</histogram>

<histogram name="Omnibox.SearchPrefetch.PrefetchEligibilityReason"
    enum="SearchPrefetchEligibilityReason" expires_after="2022-06-05">
  <owner>ryansturm@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The reason that a search prefetch request from the autocomplete/omnibox
    suggest pipeline was not eligible to be prefetched (or 'Prefetched' if it
    was prefetched). Recorded when a prefetch is requested from suggest if the
    prefetch match type (default match) is allowed by feature policy.
  </summary>
</histogram>

<histogram name="Omnibox.SearchPrefetch.PrefetchFinalStatus"
    enum="SearchPrefetchFinalStatus" expires_after="2022-06-05">
  <owner>ryansturm@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The status of a Search Prefetch request when it is deleted by expiration or
    by serving the request.
  </summary>
</histogram>

<histogram name="Omnibox.SearchPrefetch.PrefetchServingReason"
    enum="SearchPrefetchServingReason" expires_after="2022-06-05">
  <owner>ryansturm@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The reason that a navigation request could or could not serve a prefetch
    request. Recorded for all main frame navigations.
  </summary>
</histogram>

<histogram name="Omnibox.SearchProviderMatches" units="units"
    expires_after="2022-05-08">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The number of matches returned by SearchProvider. Emitted on every call to
    SearchProvider::Start(), which effectively means every key stroke in the
    omnibox.
  </summary>
</histogram>

<histogram name="Omnibox.SelectedPosition" units="position"
    expires_after="2022-05-08">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The index of the item that the user selected in the omnibox popup (a.k.a.
    dropdown) list. 0 means the inline suggestion shown within the omnibox. This
    is also the same suggestion shown as the top item in the dropdown. The
    second item in the dropdown will be recorded as bucket 1. The selected
    position is always set to 0 when the popup is closed at the time of
    navigation or if the user did a paste-and-search or paste-and-go action.

    In M-74 and earlier, this was only recorded if the user had no incognito
    windows open. In M-75 and later, it records all omnibox interactions
    regardless, in order to be consistent with how user actions and histograms
    are handled.
  </summary>
</histogram>

<histogram name="Omnibox.ShowFullUrlsEnabled" enum="BooleanEnabled"
    expires_after="M88">
  <obsolete>
    Removed 2020-10.
  </obsolete>
  <owner>livvielin@chromium.org</owner>
  <owner>tommycli@chromium.org</owner>
  <summary>
    Tracks whether the context menu option to prevent URL elisions in the
    omnibox is enabled. Recorded when the pref is toggled.
  </summary>
</histogram>

<histogram name="Omnibox.Start.WantAsyncMatches" enum="Boolean"
    expires_after="2022-07-29">
  <owner>tommycli@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    Whether asynchronous matches are requested. Recorded every time
    AutocompleteController::Start() is called.

    False counts roughly correspond to non-interactive invocations of
    AutocompleteController - like when we are classifying user text as a Search
    or URL.

    True counts roughly correspond to keystrokes or on-focus events, and can be
    used as a normalizer for per-user-gesture metrics.
  </summary>
</histogram>

<histogram name="Omnibox.SuggestionUsed.AnswerInSuggest"
    enum="SuggestionAnswerOptionalType" expires_after="2022-04-17">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Counts how often omnibox suggestions are used, and in the case an Answer
    suggestion was selected - records the type of an answer. This histogram is
    useful because there is no distinct suggestion type recorded for answers so
    their use is not recorded by Omnibox.SuggestionUsed.ProviderAndResultType.
  </summary>
</histogram>

<histogram name="Omnibox.SuggestionUsed.OfferedTabMatch" enum="BooleanOffered"
    expires_after="2022-06-05">
  <owner>gangwu@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    Measures whether the suggestion that was selected by the user offered a tab
    match. A tab match occurs when the URL specified by the suggestion matches
    the URL navigated to by another tab in the browser, within the margin of our
    URL stripping scheme.

    This metric typically only makes sense with respect to
    Omnibox.SuggestionUsed.OfferedTabMatch. Only recent versions of the browser
    send the metric. Therefore, other metrics may include datapoints not covered
    by this metric (unless one narrows the data by version.)

    In M-74 and earlier, this was only recorded if the user had no incognito
    windows open. In M-75 and later, it records all omnibox interactions
    regardless, in order to be consistent with how user actions and histograms
    are handled.
  </summary>
</histogram>

<histogram name="Omnibox.SuggestionUsed.Pedal" enum="SuggestionPedalType"
    expires_after="2022-06-05">
  <owner>jdonnelly@chromium.org</owner>
  <owner>orinj@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Counts how often omnibox pedals are used and records the type (concept ID)
    of the pedal used.

    Pedals are a button attached to a search suggestion that either navigate to
    a chrome:// URL or trigger a Chrome action (for example, opening the page
    translation dialog or opening a new window in Incognito mode).

    This histogram is related to Omnibox.PedalShown.
  </summary>
</histogram>

<histogram name="Omnibox.SuggestionUsed.ResumeJourney" units="position"
    expires_after="2022-08-24">
  <owner>tommycli@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Logs the position of "Resume Journey" omnibox actions actually
    selected by the user. The position index is 0-based, so a selected action in
    the topmost match is logged as value 0, consistent with
    Omnibox.SelectedPosition.

    This can be combined with Omnibox.ResumeJourneyShown to compute the Usage
    (or CTR) of the "Resume Journey" omnibox action on a per-position
    basis.

    It's safe to compare the total count of this metric to the total count of
    Omnibox.ResumeJourneyShown because within a single popup, only zero or one
    "Resume Journey" can be shown. If multiple actions start being
    shown in the popup, comparing to the total count becomes misleading to
    interpret as a CTR.
  </summary>
</histogram>

<histogram
    name="Omnibox.SuggestionUsed.Search.Experimental.NavigationToFirstMeaningfulPaint"
    units="ms" expires_after="2022-06-05">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Measures the time from navigation start to first meaningful paint. Only
    recorded for a search query suggestion selected from the omnibox.
  </summary>
</histogram>

<histogram
    name="Omnibox.SuggestionUsed.Search.NavigationToFirstContentfulPaint"
    units="ms" expires_after="2022-05-08">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Measures the time from navigation start to first contentful paint. Only
    recorded for a search query suggestion selected from the omnibox.
  </summary>
</histogram>

<histogram name="Omnibox.SuggestionUsed.SelectedTabMatch"
    enum="BooleanSelected" expires_after="2022-06-05">
  <owner>gangwu@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    Measures whether the suggestion that was selected by the user offered a tab
    match and specifically that the user chose the tab match over normal
    navigation. A tab match occurs when the URL specified by the suggestion
    matches the URL navigated to by another tab in the browser, within the
    margin of our URL stripping scheme. By selecting the tab match, the browser
    simply switches focus to the matching tab.

    This metric typically only makes sense with respect to
    Omnibox.SuggestionUsed.OfferedTabMatch. Only recent versions of the browser
    send the metric. Therefore, other metrics may include datapoints not covered
    by this metric (unless one narrows the data by version.)

    This metric should be stricly less than
    Omnibox.SuggestionUsed.OfferedTabMatch, and is typically used to discover
    the percentage of offered tab matches that the user accepts.

    In M-74 and earlier, this was only recorded if the user had no incognito
    windows open. In M-75 and later, it records all omnibox interactions
    regardless, in order to be consistent with how user actions and histograms
    are handled.
  </summary>
</histogram>

<histogram
    name="Omnibox.SuggestionUsed.URL.Experimental.NavigationToFirstMeaningfulPaint"
    units="ms" expires_after="2022-04-24">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Measures the time from navigation start to first meaningful paint. Only
    recorded for a URL suggestion selected from the omnibox.
  </summary>
</histogram>

<histogram name="Omnibox.SuggestionUsed.URL.NavigationToFirstContentfulPaint"
    units="ms" expires_after="2022-04-10">
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Measures the time from navigation start to first contentful paint. Only
    recorded for a URL suggestion selected from the omnibox.
  </summary>
</histogram>

<histogram name="Omnibox.SuggestRequest.Failure.GoogleResponseTime" units="ms"
    expires_after="2022-05-08">
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <owner>cch@chromium.org</owner>
  <summary>
    The time elapsed between the sending of a suggest request to Google until
    the time the request was returned with status==failed. Ignores requests that
    were canceled before being returned.
  </summary>
</histogram>

<histogram name="Omnibox.SuggestRequest.Success.GoogleResponseTime" units="ms"
    expires_after="2022-05-08">
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <owner>cch@chromium.org</owner>
  <summary>
    The time elapsed between the sending of a suggest request to Google until
    the time the request was returned with status==success. Ignores requests
    that were canceled before being returned.
  </summary>
</histogram>

<histogram name="Omnibox.SuggestRequest.Success.PrefetchImagesCount"
    units="count" expires_after="2022-05-01">
  <owner>manukh@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The number of images prefetched by the search provider on retrieving a
    successful search response.
  </summary>
</histogram>

<histogram name="Omnibox.SuggestRequests" enum="OmniboxSuggestRequests"
    expires_after="2022-05-08">
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <owner>cch@chromium.org</owner>
  <summary>
    Counts about the number of suggest requests the omnibox sent, invalidated,
    and replies received.
  </summary>
</histogram>

<histogram name="Omnibox.TabMatchTime" units="microseconds"
    expires_after="2022-04-17">
  <owner>gangwu@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    This histogram reports the amount of time it takes to match one set of
    suggestions against all open tabs. This metric is collected once for every
    time a new set of suggestions is received. This includes the Omnibox Focus
    event (when zero-prefix suggestions are offered) and every subsequent key
    stroke, including deletion, backspace etc.

    Each keystroke produces multiple events offering autocomplete matches: a)
    one synchronous, when Start() is called. b) any number of intermediate
    events, depending on whether Providers request the update. c) one at the
    end, when the process completes.

    Since these are produced about 3 times per keystroke, the total time
    consumed per Omnibox interaction is - optimistically -
    3*Omnibox.TypedLength*TabMatchTime. this excludes all the time spent
    formulating the query, such as correcting the input. This metric does not
    express the cumulative time spent matching the tabs (because we do not have
    a metric that counts the number of suggestions the user actually fetched -
    eg. we do not count the number of suggestions received when user pressed the
    backspace key).

    This histogram only records metrics on machines with high-resolution clocks.
  </summary>
</histogram>

<histogram name="Omnibox.TimeSpentBeforeDismissLens" units="ms"
    expires_after="2022-04-24">
  <owner>yusuyoutube@google.com</owner>
  <owner>benwgold@google.com</owner>
  <owner>fgorski@chromium.org</owner>
  <owner>wylieb@chromium.org</owner>
  <owner>lens-chrome@google.com</owner>
  <summary>
    Logs the elapsed time between the time when user enters the Google Lens and
    the time when user dismisses Lens and returns to Chrome. Only logged on
    Android.
  </summary>
</histogram>

<histogram name="Omnibox.ToggleSuggestionGroupId.Off" enum="SuggestionGroupId"
    expires_after="2022-05-01">
  <owner>mahmadi@google.com</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Counts the number of times a suggestion group ID is prevented form appearing
    in the results. This is recorded when the user hides a set of grouped
    suggestions, such as proactive zero-suggest, in the omnibox UI using the
    control in the grouped suggestions' header.
  </summary>
</histogram>

<histogram name="Omnibox.ToggleSuggestionGroupId.On" enum="SuggestionGroupId"
    expires_after="2022-05-01">
  <owner>mahmadi@google.com</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Counts the number of times a suggestion group ID is permitted to appear in
    the results. This is recorded when the user makes a set of previously hidden
    grouped suggestions, such as proactive zero-suggest, visible in the omnibox
    UI using the control in the grouped suggestions' header.
  </summary>
</histogram>

<histogram name="Omnibox.URLNavigationScheme" enum="NavigationScheme"
    expires_after="2022-05-01">
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    The scheme of the destination URL for the selected omnibox suggestion. This
    could be a what-you-typed suggestion (if the user fully typed a URL), an
    inline autocompletion, or something in the dropdown, anything as long as
    it's a URL navigation, not a search query. Excludes omnibox URL navigations
    that are effectively reloads as well as cut-and-pastes of URLs. Also does
    not take into account any redirects that destination URL may do before
    finally serving a page. In other words, it's the scheme of the first request
    in a possible chain.

    Due to a bug, recorded paste-and-go actions through M-88 (inclusive).
    Excluded in M-89+.
  </summary>
</histogram>

<histogram name="Omnibox.UserTextCleared" enum="OmniboxUserTextCleared"
    expires_after="M85">
  <obsolete>
    Removed 2021-01.
  </obsolete>
  <owner>kenjibaheux@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    Counts the number of times that the user text is cleared. IME users are
    sometimes in the situation that IME was unintentionally turned on and failed
    to input latin alphabets (ASCII characters) or the opposite case. In that
    case, users may delete all the text and the user text gets cleared. This
    histogram helps us estimate how often this scenario happens.

    Note that since we don't currently correlate "text cleared" events
    with IME usage, this also captures many other cases where users clear the
    text; though it explicitly doesn't log deleting all the permanent text as
    the first action of an editing sequence (see comments in
    OnAfterPossibleChange()).
  </summary>
</histogram>

<histogram name="Omnibox.WarmupTime" units="ms" expires_after="M85">
  <obsolete>
    Deprecated as of 03/2021. Code is removed.
  </obsolete>
  <owner>etienneb@chromium.org</owner>
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    Time it takes for the omnibox to process the first user interaction after
    startup. This measures the time it takes to start all autocomplete providers
    and their initialisation steps. This metric may be recorded twice as there
    is the normal omnibox path and also the "classify text" path to
    the autocomplete system.
  </summary>
</histogram>

<histogram name="Omnibox.ZeroSuggest.Eligible.OnFocusV2"
    enum="ZeroSuggestEligibleOnFocus" expires_after="2022-04-17">
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    Whether the user has settings configured so that the current page URL can be
    sent to the suggest server to request contextual suggestions. For example,
    this is only supported for users who have Google as their default search
    engine (unmodified version of Google), have search suggest enabled, are
    signed-in and syncing without a custom passphrase, and don't have an
    incognito window open. There are other criteria too. Recorded on focus in
    the omnibox if there is default search provider and we've constructed a
    suggest URL.

    Some additional guidelines: if an incognito window is open, all focus events
    will go into the "generally ineligible" bucket. Likewise, if the
    current page is a search results page, we don't allow contextual suggestions
    either so focus events on those pages go in the "generally
    ineligible" bucket. The difference between "eligible" and
    "generally eligible but not this time" depends only the properties
    of the current URL.

    Recorded regardless of whether contextual or non-contextual zero suggest is
    currently enabled on the user's platform. However, if zero suggest (in all
    forms) is entirely disabled, the user will be perpetually ineligible.

    This histogram captures all scenarios that are generally ineligible for zero
    suggest suggestions (including incognito mode), and reports eligibility for
    suggestions even if kOmniboxPopupShortcutIconsInZeroState is enabled
    (meaning: suggestions are not shown, but current URL is eligible).
  </summary>
</histogram>

<histogram name="Omnibox.ZeroSuggest.Eligible.OnProfileOpen"
    enum="BooleanSupported" expires_after="2022-01-02">
  <owner>mpearson@chromium.org</owner>
  <owner>jdonnelly@chromium.org</owner>
  <summary>
    Whether the user has settings configured so that the current page URL could
    be sent to the suggest server to request contextual suggestions. For
    example, this is only supported for users who have Google as their default
    search engine (unmodified version of Google), have search suggest enabled,
    and are signed-in and syncing without a custom passphrase. There are other
    criteria too. Recorded on profile open. Note that opening an incognito
    window (if none are currently open under the given profile) counts as
    opening a new profile.

    Some additional guidelines: unlike Omnibox.ZeroSuggest.Eligible.OnFocus,
    because this is recorded on profile open, users cannot be declared
    ineligible because they have an incognito window open (it's impossible to
    have an incognito window open for a given profile at the time of profile
    open) and also cannot be declared ineligible because the user is viewing a
    search results page. (We test this on-profile-open using an arbitrary URL.)

    Recorded regardless of whether contextual or non-contextual zero suggest is
    currently enabled on the user's platform. However, if zero suggest (in all
    forms) is entirely disabled, the user will be perpetually ineligible.
  </summary>
</histogram>

<histogram name="Omnibox.ZeroSuggestRequests" enum="OmniboxZeroSuggestRequests"
    expires_after="2022-06-05">
  <owner>ender@chromium.org</owner>
  <owner>tommycli@chromium.org</owner>
  <owner>chrome-omnibox-team@google.com</owner>
  <summary>
    Counts about the number of zero suggest requests (requests for suggestions
    when the user has focused but not modified the omnibox) the omnibox sent,
    invalidated, and replies received.
  </summary>
</histogram>

</histograms>

</histogram-configuration>


text:
package org.apache.camel.model.language;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

import org.apache.camel.spi.Metadata;

/**
 * To use OGNL scripts in Camel expressions or predicates.
 */
@Metadata(firstVersion = "1.1.0", label = "language,java", title = "OGNL")
@XmlRootElement(name = "ognl")
@XmlAccessorType(XmlAccessType.FIELD)
public class OgnlExpression extends ExpressionDefinition {

    public OgnlExpression() {
    }

    public OgnlExpression(String expression) {
        super(expression);
    }

    public String getLanguage() {
        return "ognl";
    }
}


text:
@interface Connection () <NSNetServiceDelegate, NSStreamDelegate>

@property (assign, readwrite, nonatomic) ConnectionState connectionState;

@property (strong, readwrite, nonatomic) NSInputStream *inputStream;
@property (strong, readwrite, nonatomic) NSOutputStream *outputStream;

@property (assign, nonatomic) CFSocketNativeHandle socket;;
@property (strong, nonatomic) NSNetService *netService;

- (void)setupWithReadStream:(CFReadStreamRef)readStream writeStream:(CFWriteStreamRef)writeStream;

@property (strong, nonatomic) NSRunLoop *runLoop;

@end

@implementation Connection

//TODO
- (instancetype)initWithSocket:(CFSocketNativeHandle)socket delegate:(id<ConnectionDelegate>)delegate {
    self = [super init];
    if(self) {
        self.socket = socket;
        self.delegate = delegate;

        self.connectionState = ConnectionStateNotConnected;
    }
    return self;
}

- (instancetype)initWithNetService:(NSNetService *)service delegate:(id<ConnectionDelegate>)delegate {
    self = [super init];
    if(self) {
        self.netService = service;
        self.netService.delegate = self;
        self.delegate = delegate;

        self.connectionState = ConnectionStateNotConnected;
    }
    return self;
}

- (void)connectToSocket:(CFSocketNativeHandle)socketHandle {
    CFReadStreamRef readStream = NULL;
    CFWriteStreamRef writeStream = NULL;
    CFStreamCreatePairWithSocket(kCFAllocatorDefault, socketHandle,
                                 &readStream, &writeStream);
    [self setupWithReadStream:readStream writeStream:writeStream];
}

- (void)connectToAddress:(NSString *)address port:(int)port {
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)(address), port, &readStream, &writeStream);
    [self setupWithReadStream:readStream writeStream:writeStream];
}

- (void)setupWithReadStream:(CFReadStreamRef)readStream writeStream:(CFWriteStreamRef)writeStream {
    self.connectionState = ConnectionStateConnected;

    self.inputStream = (__bridge NSInputStream *)readStream;
    self.outputStream = (__bridge NSOutputStream *)writeStream;

    self.inputStream.delegate = self;
    self.outputStream.delegate = self;
    // here: change the queue type and use a background queue (you can change priority)
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^ {
        [self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        [self.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

        [self.inputStream open];
        [self.outputStream open];
        self.runLoop = [NSRunLoop currentRunLoop];
        dispatch_async(dispatch_get_main_queue(), ^ {
            if([self.delegate respondsToSelector:@selector(connectionDidConnect:)]) {
                [self.delegate connectionDidConnect:self];
            }
        });
        [[NSRunLoop currentRunLoop] run];
    });

    if (readStream != NULL) {
        CFRelease(readStream);
    }
    if(writeStream != NULL) {
        CFRelease(writeStream);
    }
}

- (void)connect {
    if(self.connectionState == ConnectionStateConnected) {
        if([self.delegate respondsToSelector:@selector(connectionDidNotConnect:reason:errorDictionary:)]) {
            [self.delegate connectionDidNotConnect:self reason:CommunicatorErrorCodeAlreadyConnected errorDictionary:nil];
        }
        return;
    }
    if(self.connectionState != ConnectionStateConnecting) {
        self.connectionState = ConnectionStateConnecting;
        if([self.delegate respondsToSelector:@selector(connectionDidStartConnecting:)]) {
            [self.delegate connectionDidStartConnecting:self];
        }
    }

    if(self.socket) {
        CFReadStreamRef readStream = NULL;
        CFWriteStreamRef writeStream = NULL;
        CFStreamCreatePairWithSocket(NULL, self.socket, &readStream, &writeStream);

        if (readStream && writeStream) {
            [self setupWithReadStream:readStream writeStream:writeStream];
        }
    }
    else {
        [self.netService resolveWithTimeout:10];
    }
}

- (void)netServiceDidResolveAddress:(NSNetService *)service {
    if(!self.netService) {
        return;
    }
    self.netService.delegate = nil;
    self.netService = nil;
    char addressBuffer[INET6_ADDRSTRLEN];

    for (NSData *data in service.addresses)
    {
        memset(addressBuffer, 0, INET6_ADDRSTRLEN);

        typedef union {
            struct sockaddr sa;
            struct sockaddr_in ipv4;
            struct sockaddr_in6 ipv6;
        } ip_socket_address;

        ip_socket_address *socketAddress = (ip_socket_address *)[data bytes];

        if (socketAddress && (socketAddress->sa.sa_family == AF_INET))// || socketAddress->sa.sa_family == AF_INET6))
        {
            const char *addressStr = inet_ntop(socketAddress->sa.sa_family,
                                               (void *)&(socketAddress->ipv4.sin_addr),
                                               addressBuffer,
                                               sizeof(addressBuffer));

            int port = ntohs(socketAddress->ipv4.sin_port);

            if (addressStr && port)
            {
                [self connectToAddress:[NSString stringWithCString:addressStr encoding:NSUTF8StringEncoding] port:port];
                break;
            }
        }
    }
}

- (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict {
    self.connectionState = ConnectionStateErrorConnecting;
    if([self.delegate respondsToSelector:@selector(connectionDidNotConnect:reason:errorDictionary:)]) {
        [self.delegate connectionDidNotConnect:self reason:CommunicatorErrorCodeFailedToConnect errorDictionary:errorDict];
    }
}

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
    if(eventCode == NSStreamEventEndEncountered || eventCode == NSStreamEventErrorOccurred) {
        if([self.delegate respondsToSelector:@selector(connectionDidDisconnect:)]) {
            [self.delegate connectionDidDisconnect:self];
        }
    }
    else if(eventCode == NSStreamEventHasBytesAvailable) {
        NSUInteger infoLength = [DataInfo length];

        uint8_t infoBuffer[infoLength];
        [self.inputStream read:infoBuffer maxLength:infoLength];
        NSData *infoData = [[NSData alloc]initWithBytes:(const void *)infoBuffer length:infoLength];
        DataInfo *dataInfo = [[DataInfo alloc]initWithData:infoData];
        if(dataInfo.dataType == CommunicationDataTypeTermination) {
            [self disconnect:NO];
            return;
        }

        if([self.delegate respondsToSelector:@selector(connectionDidStartReceivingData:)]) {
            dispatch_async(dispatch_get_main_queue(),^ {
                [self.delegate connectionDidStartReceivingData:self];
            });
        }

        NSInteger headerLength = dataInfo.headerLength;
        NSData *headerData = [self read:headerLength callback:nil];

        DataHeader *header = [[DataHeader alloc]initWithData:headerData];

        NSInteger contentLength = dataInfo.contentLength;
        NSData *contentData = [self read:contentLength callback:^(NSInteger bytesRead, NSInteger length) {
            if([self.delegate respondsToSelector:@selector(connection:didUpdateReceivingData:)]) {
                CGFloat completion = (CGFloat)(bytesRead)/(CGFloat)(length);
                dispatch_async(dispatch_get_main_queue(),^ {
                    [self.delegate connection:self didUpdateReceivingData:completion];
                });
            }
        }];

        DataContent *content = [[DataContent alloc]initWithData:contentData];

        NSInteger footerLength = dataInfo.footerLength;
        NSData *footerData = [self read:footerLength callback:nil];

        DataFooter *footer = [[DataFooter alloc]initWithData:footerData];

        CommunicationData *receivedData = [[CommunicationData alloc]initWithType:dataInfo.dataType header:header content:content footer:footer];
        dispatch_async(dispatch_get_main_queue(),^ {
            if([self.delegate respondsToSelector:@selector(connection:didReceiveData:)]) {
                [self.delegate connection:self didReceiveData:receivedData];
            }
        });
    }
}

- (NSData *)read:(NSInteger)length callback:(void(^)(NSInteger bytesRead, NSInteger length))callback {
    NSMutableData *data = [[NSMutableData alloc]init];
    if(length > 0) {
        NSInteger maxPacketSize = MIN(length, 4096);
        NSInteger bytesRead = 0;

        while (bytesRead < length) {
            uint8_t buffer[maxPacketSize];
            NSInteger readResult = [self.inputStream read:buffer maxLength:maxPacketSize];
            if(readResult > 0) {
                bytesRead += readResult;
                [data appendBytes:buffer length:readResult];
            }
            else {
                return nil;
            }
            if(callback) {
                callback(bytesRead, length);
            }
        }
    }
    return data;
}

- (void)sendString:(NSString *)string {
    [self sendString:string encoding:NSUTF8StringEncoding];
}

- (void)sendString:(NSString *)string encoding:(NSStringEncoding)encoding {
    [self sendCommunicationData:[CommunicationData fromString:string withEncoding:encoding]];
}

#if TARGET_OS_IPHONE

- (void)sendImage:(UIImage *)image {
    [self sendImage:image name:@"Untitled"];
}

- (void)sendImage:(UIImage *)image name:(NSString*)name {
    [self sendCommunicationData:[CommunicationData fromImage:image name:name]];
}

#elif TARGET_OS_MAC

- (void)sendImage:(NSImage *)image {
    [self sendImage:image name:@"Untitled"];
}

- (void)sendImage:(NSImage *)image name:(NSString*)name {
    [self sendCommunicationData:[CommunicationData fromImage:image name:name]];
}

#endif

- (void)sendFile:(NSString *)file {
    [self sendFile:file name:[file lastPathComponent]];
}

- (void)sendFile:(NSString *)filePath name:(NSString *)name {
    [self sendCommunicationData:[CommunicationData fromFile:filePath name:name]];
}

- (void)sendDictionary:(NSDictionary *)dictionary {
    [self sendCommunicationData:[CommunicationData fromDictionary:dictionary]];
}

- (void)sendArray:(NSArray *)array {
    [self sendCommunicationData:[CommunicationData fromArray:array]];
}

- (void)sendJSONString:(NSString *)JSON {
    NSData *data = [JSON dataUsingEncoding:NSUTF8StringEncoding];

    id JSONObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
    if(!JSONObject) {
        [self sendString:JSON];
    }
    else {
        JSONObjectType objectType = JSONObjectTypeOther;
        if([JSONObject isKindOfClass:[NSArray class]]) {
            objectType = JSONObjectTypeArray;
        }
        else if([JSONObject isKindOfClass:[NSDictionary class]]) {
            objectType = JSONObjectTypeDictionary;
        }
        [self sendCommunicationData:[CommunicationData fromJSONData:data JSONObjectType:objectType]];
    }
}

- (void)sendData:(NSData *)data {
    [self sendCommunicationData:[CommunicationData fromData:data]];
}

- (void)sendCommunicationData:(CommunicationData *)communicationData {
    if(!communicationData) {
        return;
    }

    [self.outputStream write:[[communicationData.dataInfo getData] bytes] maxLength:[DataInfo length]];
    if(communicationData.header.length > 0) {
        NSInteger headerBytesWritten = 0;
        NSData *headerData = [communicationData.header getData];
        while (headerData.length > headerBytesWritten )
        {
            while (!self.outputStream.hasSpaceAvailable) {
                [NSThread sleepForTimeInterval:0.05];
            }

            NSInteger writeResult = [self.outputStream write:[headerData bytes] + headerBytesWritten maxLength:communicationData.header.length - headerBytesWritten];
            if (writeResult != -1 ) {
                headerBytesWritten += writeResult;
            }
        }
    }
    if(communicationData.content.length > 0) {
        NSInteger dataBytesWritten = 0;
        NSData *contentData = [communicationData.content getData];
        while (contentData.length > dataBytesWritten )
        {
            while (!self.outputStream.hasSpaceAvailable) {
                [NSThread sleepForTimeInterval:0.05];
            }

            NSInteger writeResult = [self.outputStream write:[contentData bytes] + dataBytesWritten maxLength:communicationData.content.length - dataBytesWritten];
            if (writeResult != -1 ) {
                dataBytesWritten += writeResult;
            }
        }
    }
    if(communicationData.footer.length > 0) {
        NSInteger footerBytesWritten = 0;
        NSData *footerData = [communicationData.footer getData];
        while (footerData.length > footerBytesWritten )
        {
            while (!self.outputStream.hasSpaceAvailable) {
                [NSThread sleepForTimeInterval:0.05];
            }

            NSInteger writeResult = [self.outputStream write:[footerData bytes] + footerBytesWritten maxLength:communicationData.footer.length - footerBytesWritten];
            if (writeResult != -1 ) {
                footerBytesWritten += writeResult;
            }
        }
    }

    if([self.delegate respondsToSelector:@selector(connection:didSendData:)]) {
        [self.delegate connection:self didSendData:communicationData];
    }
}

- (void)disconnect:(BOOL)sendTerminationMessage {
    if(sendTerminationMessage) {
        [self sendCommunicationData:[CommunicationData terminationData]];
    }
    else {
        self.connectionState = ConnectionStateDisconnected;
        [self.inputStream close];
        [self.inputStream removeFromRunLoop:self.runLoop forMode: NSDefaultRunLoopMode];
        self.inputStream.delegate = nil;
        self.inputStream = nil;

        [self.outputStream close];
        [self.inputStream removeFromRunLoop:self.runLoop forMode: NSDefaultRunLoopMode];
        self.outputStream.delegate = nil;
        self.outputStream = nil;

        self.runLoop = nil;

        if([self.delegate respondsToSelector:@selector(connectionDidDisconnect:)]) {
            [self.delegate connectionDidDisconnect:self];
        }
    }
}

@end


text:
package org.trashacker.service;

import java.sql.Time;
import java.util.GregorianCalendar;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.trashacker.data.domain.GarbageType;
import org.trashacker.data.domain.PointType;
import org.trashacker.repository.ClothesRecyclingBoxRepo;
import org.trashacker.repository.GarbageTruckRoadmapRepo;
import org.trashacker.repository.MedicationDisposalSiteRepo;
import org.trashacker.repository.PedestrianTrashBoxRepo;
import org.trashacker.repository.RecyclingFoodWasteDepotRepo;
import org.trashacker.repository.WedSunFoodWasteDepotRepo;

@Service
public class SearchCollectPointService {

	@Autowired
	ClothesRecyclingBoxRepo clothesRecyclingBoxRepo;

	@Autowired
	MedicationDisposalSiteRepo medicationDisposalSiteRepo;

	@Autowired
	RecyclingFoodWasteDepotRepo recyclingFoodWasteDepotRepo;

	@Autowired
	WedSunFoodWasteDepotRepo wedSunFoodWasteDepotRepo;

	@Autowired
	GarbageTruckRoadmapRepo garbageTruckRoadmapRepo;

	@Autowired
	PedestrianTrashBoxRepo pedestrianTrashBoxRepo;

	public SearchResultBean searchAllTypePointsByLocation(List<String> queryTypes, float maxLat, float minLat, float maxLng, float minLng){
		SearchResultBean result = new SearchResultBean();

		if (queryTypes.contains(GarbageType.GENERAL.getName()) || queryTypes.contains(GarbageType.RECYCLE.getName()) || queryTypes.contains(GarbageType.FOOD_SCRAP.getName())){
			result.setFixedPoints(recyclingFoodWasteDepotRepo.getByLocationRange(maxLat, minLat, maxLng, minLng));
			result.setGarbageCar(garbageTruckRoadmapRepo.getByLocationRange(maxLat, minLat, maxLng, minLng));
			result.setTrashBoxs(pedestrianTrashBoxRepo.getByLocationRange(maxLat, minLat, maxLng, minLng));
		}

		if (queryTypes.contains(GarbageType.FOOD_SCRAP.getName())){
			result.setFoodScrapsPoints(wedSunFoodWasteDepotRepo.getByLocationRange(maxLat, minLat, maxLng, minLng));
		}

		if (queryTypes.contains(GarbageType.DRUG.getName())){
			result.setDrugsPoints(medicationDisposalSiteRepo.getByLocationRange(maxLat, minLat, maxLng, minLng));
		}

		if (queryTypes.contains(GarbageType.CLOTHES.getName())){
			result.setClothesPoints(clothesRecyclingBoxRepo.getByLocationRange(maxLat, minLat, maxLng, minLng));
		}

		return result;
	}

	public SearchResultBean searchAllTypePointsByTime(List<String> queryTypes, Time arrive, Time leave){
		SearchResultBean result = new SearchResultBean();

		GregorianCalendar queryStartTime = new GregorianCalendar(0,0,0,arrive.toLocalTime().getHour(),leave.toLocalTime().getHour());

		if (queryTypes.contains(GarbageType.GENERAL.getName()) || queryTypes.contains(GarbageType.RECYCLE.getName()) || queryTypes.contains(GarbageType.FOOD_SCRAP.getName())){
			result.setGarbageCar(garbageTruckRoadmapRepo.getByTimeRange(arrive, leave));

			if (queryStartTime.after(PointType.FIXED_POINT.getStartTime()) && queryStartTime.before(PointType.FIXED_POINT.getEndTime())){
				result.setFixedPoints(recyclingFoodWasteDepotRepo.findAll());
			}

		}

		if (queryTypes.contains(GarbageType.FOOD_SCRAP.getName())){
			if (queryStartTime.after(PointType.FOOD_SCRAPS_ONLY_POINT.getStartTime()) && queryStartTime.before(PointType.FOOD_SCRAPS_ONLY_POINT.getEndTime())){
				result.setFoodScrapsPoints(wedSunFoodWasteDepotRepo.findAll());
			}
		}

		return result;
	}

	public SearchResultBean searchByTimeAndLocation(List<String> queryTypes, float maxLat, float minLat, float maxLng, float minLng,Time arrive, Time leave){
		SearchResultBean result = new SearchResultBean();

		GregorianCalendar queryStartTime = new GregorianCalendar(0,0,0,arrive.toLocalTime().getHour(),leave.toLocalTime().getHour());

		if (queryTypes.contains(GarbageType.GENERAL.getName()) || queryTypes.contains(GarbageType.RECYCLE.getName()) || queryTypes.contains(GarbageType.FOOD_SCRAP.getName())){

			result.setGarbageCar(garbageTruckRoadmapRepo.getByLocationAndTimeRange(maxLat, minLat, maxLng, minLng, arrive, leave));
			result.setTrashBoxs(pedestrianTrashBoxRepo.getByLocationRange(maxLat, minLat, maxLng, minLng));
			if (queryStartTime.after(PointType.FIXED_POINT.getStartTime()) && queryStartTime.before(PointType.FIXED_POINT.getEndTime())){
				result.setFixedPoints(recyclingFoodWasteDepotRepo.getByLocationRange(maxLat, minLat, maxLng, minLng));
			}
		}

		if (queryTypes.contains(GarbageType.FOOD_SCRAP.getName())){
			if (queryStartTime.after(PointType.FOOD_SCRAPS_ONLY_POINT.getStartTime()) && queryStartTime.before(PointType.FOOD_SCRAPS_ONLY_POINT.getEndTime())){
				result.setFoodScrapsPoints(wedSunFoodWasteDepotRepo.getByLocationRange(maxLat, minLat, maxLng, minLng));
			}
		}

		if (queryTypes.contains(GarbageType.DRUG.getName())){
			result.setDrugsPoints(medicationDisposalSiteRepo.getByLocationRange(maxLat, minLat, maxLng, minLng));
		}

		if (queryTypes.contains(GarbageType.CLOTHES.getName())){
			result.setClothesPoints(clothesRecyclingBoxRepo.getByLocationRange(maxLat, minLat, maxLng, minLng));
		}

		return result;
	}
}


text:
asciidoc-dblatex-customization-example
======================================

This is an example of some possible customizations for asciidoc dblatex
backend. It features:

* *Letter paper size* -- How to override the default A4 paper size in dblatex.
* *Custom cover page* -- Cover page with company logo and custom layout.
* *Custom fonts* -- Such as using Charter as roman font and Inconsolata as monospace font.
* *White background in code listings* -- Overriding default dblatex color/grey background.

Overrides and configurations are placed into custom
`asciidoc-dblatex-custom.sty` style file. Take a look into supplied `Makefile`
for `a2x` command example. Run `make clean pdf` to build PDF from asciidoc
source `example.txt`. The output should look like `output/example.pdf`.

Tested on OS X and Ubuntu with asciidoc v8.6.8, TexLive 2012 and dblatex v0.3.4.


text:
package client.css
import scalacss.Defaults._

object ProjectCSS {

  object Style extends StyleSheet.Inline {
    import dsl._

    val displayInitialbtn = style(
      display.initial,
      float.right,
      marginLeft(-30.px),
      marginRight(10.px)
    )
    val displayModalbtn = style(
      display.initial
    //      float.right,
    //      marginRight(10.px)
    )
    val textareaWidth = style(
      // width(100.%%),
      maxWidth(100.%%),
      minWidth(100.%%)
    )
    val projectdropdownbtn = style(
      fontSize(15.px),
      border(1.px, solid, gray),
      marginBottom(15.px),
      backgroundColor(transparent)
    )
  }
}


text:
If you want a more up to date script, please report to **[PyFunceble](https://github.com/funilrys/PyFunceble)**

# Funceble

> A script to check domains or IP accessibility.

[![license](https://img.shields.io/github/license/funilrys/funceble.svg)](https://github.com/funilrys/funceble/blob/master/LICENSE) [![GitHub tag](https://img.shields.io/github/tag/funilrys/funceble.svg)](https://github.com/funilrys/funceble/tags) [![GitHub release](https://img.shields.io/github/release/funilrys/funceble.svg)](https://github.com/funilrys/funceble/releases/latest)

[![GitHub issues open](https://img.shields.io/github/issues/funilrys/funceble.svg)]() [![GitHub closed issues](https://img.shields.io/github/issues-closed/funilrys/funceble.svg)](https://github.com/funilrys/)

[![Github file size](https://img.shields.io/github/size/funilrys/funceble/funceble.svg)](https://github.com/funilrys/funceble/blob/master/funceble)

The main idea was to create a script that can check if a given domain, a `hosts` file or a **list of domains** are/is **ACTIVE** or **INACTIVE**. And, in between, if wanted, **generate a `hosts` file** based on the results.

Have any question? Fill a new issue and I'll do my best to answer as soon as possible.

## :book: Wiki as place to be :star2::star2::star2:

Want to know more about **Funceble**? All information to know are under the [wiki](https://github.com/funilrys/funceble/wiki)! You can also contribute there if you want! :smile:

You can get a copy of the wiki with the following:

```shell
git clone https://github.com/funilrys/funceble.wiki.git
```

## Main Features

- Read an existing `hosts`file and check every domain present into it.
- Generate `hosts` file

  - With custom IP
  - ONLY with **ACTIVE** domains

- Show on screen

  - The status of a given domain is **ACTIVE**, **INACTIVE** or **INVALID** (live update)
  - The percentage of **ACTIVE**, **INACTIVE** and **INVALID** (at the end)

- Save on single file

  - Result of execution (live update)
  - The percentage of **ACTIVE**, **INACTIVE** and **INVALID** (at the end)

- Save on separated files (when needed)

  - **ACTIVE** domain
  - **INACTIVE** domain
  - **INVALID** domain

## Valuable links

They updated their hosts file or blocklist with the help of [Funceble](https://github.com/funilrys/funceble/) or [dead-hosts](https://github.com/funilrys/dead-hosts).

Repo / List Name                               | Author                                             | Repository / Website                                                                       | Raw
---------------------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------
add.2o7Net                                     | [Tomasz Przybył](https://github.com/FadeMind)      | [Repository](https://github.com/FadeMind/hosts.extras/tree/master/add.2o7Net)              | [Raw](https://raw.githubusercontent.com/FadeMind/hosts.extras/master/add.2o7Net/hosts)
add.Dead                                       | [Tomasz Przybył](https://github.com/FadeMind)      | [Repository](https://github.com/FadeMind/hosts.extras/tree/master/add.Dead)                | [Raw](https://raw.githubusercontent.com/FadeMind/hosts.extras/master/add.Dead/hosts)
add.Risk                                       | [Tomasz Przybył](https://github.com/FadeMind)      | [Repository](https://github.com/FadeMind/hosts.extras/tree/master/add.Risk)                | [Raw](https://raw.githubusercontent.com/FadeMind/hosts.extras/master/add.Risk/hosts)
add.Spam                                       | [Tomasz Przybył](https://github.com/FadeMind)      | [Repository](https://github.com/FadeMind/hosts.extras/tree/master/add.Spam)                | [Raw](https://raw.githubusercontent.com/FadeMind/hosts.extras/master/add.Spam/hosts)
Badd-Boyz-Hosts                                | [Mitchell Krog](https://github.com/mitchellkrogza) | [Repository](https://github.com/mitchellkrogza/Badd-Boyz-Hosts)                            | [Raw](https://raw.githubusercontent.com/mitchellkrogza/Badd-Boyz-Hosts/master/PULL_REQUESTS/domains.txt)
KADhosts                                       | [KAD](https://github.com/azet12)                   | [Repository](https://github.com/azet12/KADhosts)                                           | [Raw](https://raw.githubusercontent.com/azet12/KADhosts/master/KADhosts.txt)
Nginx Ultimate Bad Bot & Referrer Spam Blocker | [Mitchell Krog](https://github.com/mitchellkrogza) | [Repository](https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/)            | [Raw](https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-referrers.list)
SpotifyAds                                     | [Tomasz Przybył](https://github.com/FadeMind)      | [Repository](https://github.com/FadeMind/hosts.extras/tree/master/SpotifyAds)              | [Raw](https://raw.githubusercontent.com/FadeMind/hosts.extras/master/SpotifyAds/hosts)
The Big List of Hacked Malware Web Sites       | [Mitchell Krog](https://github.com/mitchellkrogza) | [Repository](https://github.com//mitchellkrogza/The-Big-List-of-Hacked-Malware-Web-Sites/) | [Raw](https://raw.githubusercontent.com/mitchellkrogza/The-Big-List-of-Hacked-Malware-Web-Sites/master/.dev-tools/_strip_domains/domains.txt)
UncheckyAds                                    | [Tomasz Przybył](https://github.com/FadeMind)      | [Repository](https://github.com/FadeMind/hosts.extras/tree/master/UncheckyAds)             | [Raw](https://raw.githubusercontent.com/FadeMind/hosts.extras/master/UncheckyAds/hosts)

Your list or repository is not listed here? Fill a new issue [here](https://github.com/funilrys/funceble/issues/new?title=Please%20add%20my%20list%20or%20repository%20to%20the%20valuable%20links) :smile_cat:

--------------------------------------------------------------------------------

# Special Thanks

Thank you for your awesome `hosts` lists, support or contributions which helped _(and/or still help)_ me build this script. :smile: :+1:

- Adam Warner - [@PromoFaux](https://github.com/PromoFaux)
- Mitchell Krog - [@mitchellkrogza](https://github.com/mitchellkrogza)
- [Pi-Hole](https://github.com/pi-hole/pi-hole)

# Contributors

Thank you for your awesome ideas or contributions which make or made funceble better!! :+1: :100: :1st_place_medal:

- Mitchell Krog - [@mitchellkrogza](https://github.com/mitchellkrogza)

- WaLLy3K - [@WaLLy3K](https://github.com/WaLLy3K)

- xxcriticxx - [@xxcriticxx](https://github.com/xxcriticxx)

--------------------------------------------------------------------------------

# Supporting the project

[Funceble](https://github.com/funilrys/funceble) and [dead-hosts](https://github.com/funilrys/dead-hosts) are powered by :coffee:!

This project helps you and or you like it? Why don't you buy me a cup of :coffee:? :smile_cat:

[![Buy me a cup of coffee](https://img.shields.io/badge/Buy%20-me%20a%20cup%20of%20%E2%98%95-blue.svg)](https://www.paypal.me/funilrys/)

--------------------------------------------------------------------------------

# `Hosts` files

## What is a hosts file?

A hosts file, named `hosts` (with no file extension), is a plain-text file used by all operating systems to map hostnames to IP addresses.

In most operating systems, the `hosts` file is preferential to `DNS`. Therefore if a domain is resolved by the `hosts` file, the request never leaves your computer.

Having a smart `hosts` file goes a long way towards blocking malware, adware, ransomware, porn and other nuisance websites.

A hosts file like this causes any lookups to any of the listed domains to resolve back to your localhost so it prevents any outgoing connections to the listed domains.

## Recommendations

I'd personally recommend using [Steven's hosts](https://github.com/StevenBlack/hosts) or [Pi-Hole](https://github.com/pi-hole/pi-hole) which are in my opinion the best out there.

--------------------------------------------------------------------------------

# License

```
MIT License

Copyright (c) 2017 Nissar Chababy <contact at funilrys dot com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```