diff --git a/cli/js/40_jupyter.js b/cli/js/40_jupyter.js index 5a30a6b8e8..c4b27ad0b6 100644 --- a/cli/js/40_jupyter.js +++ b/cli/js/40_jupyter.js @@ -1,17 +1,429 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. +/* + * @module mod + * @description + * This module provides a `display()` function for the Jupyter Deno Kernel, similar to IPython's display. + * It can be used to asynchronously display objects in Jupyter frontends. There are also tagged template functions + * for quickly creating HTML, Markdown, and SVG views. + * + * @example + * Displaying objects asynchronously in Jupyter frontends. + * ```typescript + * import { display, html, md } from "https://deno.land/x/deno_jupyter/mod.ts"; + * + * await display(html`

Hello, world!

`); + * await display(md`# Notebooks in TypeScript via Deno ![Deno logo](https://github.com/denoland.png?size=32) + * + * * TypeScript ${Deno.version.typescript} + * * V8 ${Deno.version.v8} + * * Deno ${Deno.version.deno} + * + * Interactive compute with Jupyter _built into Deno_! + * `); + * ``` + * + * @example + * Emitting raw MIME bundles. + * ```typescript + * import { display } from "https://deno.land/x/deno_jupyter/mod.ts"; + * + * await display({ + * "text/plain": "Hello, world!", + * "text/html": "

Hello, world!

", + * "text/markdown": "# Hello, world!", + * }, { raw: true }); + * ``` + */ + const core = globalThis.Deno.core; + const internals = globalThis.__bootstrap.internals; +const $display = Symbol.for("Jupyter.display"); + +/** Escape copied from https://deno.land/std@0.192.0/html/entities.ts */ +const rawToEntityEntries = [ + ["&", "&"], + ["<", "<"], + [">", ">"], + ['"', """], + ["'", "'"], +]; + +const rawToEntity = new Map(rawToEntityEntries); + +const rawRe = new RegExp(`[${[...rawToEntity.keys()].join("")}]`, "g"); + +function escapeHTML(str) { + return str.replaceAll( + rawRe, + (m) => rawToEntity.has(m) ? rawToEntity.get(m) : m, + ); +} + +/** Duck typing our way to common visualization and tabular libraries */ +/** Vegalite */ +function isVegaLike(obj) { + return obj !== null && typeof obj === "object" && "toSpec" in obj; +} +function extractVega(obj) { + const spec = obj.toSpec(); + if (!("$schema" in spec)) { + return null; + } + if (typeof spec !== "object") { + return null; + } + let mediaType = "application/vnd.vega.v5+json"; + if (spec.$schema === "https://vega.github.io/schema/vega-lite/v4.json") { + mediaType = "application/vnd.vegalite.v4+json"; + } else if ( + spec.$schema === "https://vega.github.io/schema/vega-lite/v5.json" + ) { + mediaType = "application/vnd.vegalite.v5+json"; + } + return { + [mediaType]: spec, + }; +} +/** Polars */ +function isDataFrameLike(obj) { + const isObject = obj !== null && typeof obj === "object"; + if (!isObject) { + return false; + } + const df = obj; + return df.schema !== void 0 && typeof df.schema === "object" && + df.head !== void 0 && typeof df.head === "function" && + df.toRecords !== void 0 && typeof df.toRecords === "function"; +} +/** + * Map Polars DataType to JSON Schema data types. + * @param dataType - The Polars DataType. + * @returns The corresponding JSON Schema data type. + */ +function mapPolarsTypeToJSONSchema(colType) { + const typeMapping = { + Null: "null", + Bool: "boolean", + Int8: "integer", + Int16: "integer", + Int32: "integer", + Int64: "integer", + UInt8: "integer", + UInt16: "integer", + UInt32: "integer", + UInt64: "integer", + Float32: "number", + Float64: "number", + Date: "string", + Datetime: "string", + Utf8: "string", + Categorical: "string", + List: "array", + Struct: "object", + }; + // These colTypes are weird. When you console.dir or console.log them + // they show a `DataType` field, however you can't access it directly until you + // convert it to JSON + const dataType = colType.toJSON()["DataType"]; + return typeMapping[dataType] || "string"; +} + +function extractDataFrame(df) { + const fields = []; + const schema = { + fields, + }; + let data = []; + // Convert DataFrame schema to Tabular DataResource schema + for (const [colName, colType] of Object.entries(df.schema)) { + const dataType = mapPolarsTypeToJSONSchema(colType); + schema.fields.push({ + name: colName, + type: dataType, + }); + } + // Convert DataFrame data to row-oriented JSON + // + // TODO(rgbkrk): Determine how to get the polars format max rows + // Since pl.setTblRows just sets env var POLARS_FMT_MAX_ROWS, + // we probably just have to pick a number for now. + // + + data = df.head(50).toRecords(); + let htmlTable = ""; + htmlTable += ""; + schema.fields.forEach((field) => { + htmlTable += ``; + }); + htmlTable += ""; + htmlTable += ""; + df.head(10).toRecords().forEach((row) => { + htmlTable += ""; + schema.fields.forEach((field) => { + htmlTable += ``; + }); + htmlTable += ""; + }); + htmlTable += "
${escapeHTML(String(field.name))}
${escapeHTML(String(row[field.name]))}
"; + return { + "application/vnd.dataresource+json": { data, schema }, + "text/html": htmlTable, + }; +} + +/** Canvas */ +function isCanvasLike(obj) { + return obj !== null && typeof obj === "object" && "toDataURL" in obj; +} + +/** Possible HTML and SVG Elements */ +function isSVGElementLike(obj) { + return obj !== null && typeof obj === "object" && "outerHTML" in obj && + typeof obj.outerHTML === "string" && obj.outerHTML.startsWith(" obj, + }; +} + +/** + * Format an object for displaying in Deno + * + * @param obj - The object to be displayed + * @returns MediaBundle + */ +async function format(obj) { + if (hasDisplaySymbol(obj)) { + return await obj[$display](); + } + if (typeof obj !== "object") { + return { + "text/plain": Deno[Deno.internal].inspectArgs(["%o", obj], { + colors: !Deno.noColor, + }), + }; + } + + if (isCanvasLike(obj)) { + const dataURL = obj.toDataURL(); + const parts = dataURL.split(","); + const mime = parts[0].split(":")[1].split(";")[0]; + const data = parts[1]; + return { + [mime]: data, + }; + } + if (isVegaLike(obj)) { + return extractVega(obj); + } + if (isDataFrameLike(obj)) { + return extractDataFrame(obj); + } + if (isSVGElementLike(obj)) { + return { + "image/svg+xml": obj.outerHTML, + }; + } + if (isHTMLElementLike(obj)) { + return { + "text/html": obj.outerHTML, + }; + } + return { + "text/plain": Deno[Deno.internal].inspectArgs(["%o", obj], { + colors: !Deno.noColor, + }), + }; +} + +/** + * This function creates a tagged template function for a given media type. + * The tagged template function takes a template string and returns a displayable object. + * + * @param mediatype - The media type for the tagged template function. + * @returns A function that takes a template string and returns a displayable object. + */ +function createTaggedTemplateDisplayable(mediatype) { + return (strings, ...values) => { + const payload = strings.reduce( + (acc, string, i) => + acc + string + (values[i] !== undefined ? values[i] : ""), + "", + ); + return makeDisplayable({ [mediatype]: payload }); + }; +} + +/** + * Show Markdown in Jupyter frontends with a tagged template function. + * + * Takes a template string and returns a displayable object for Jupyter frontends. + * + * @example + * Create a Markdown view. + * + * ```typescript + * md`# Notebooks in TypeScript via Deno ![Deno logo](https://github.com/denoland.png?size=32) + * + * * TypeScript ${Deno.version.typescript} + * * V8 ${Deno.version.v8} + * * Deno ${Deno.version.deno} + * + * Interactive compute with Jupyter _built into Deno_! + * ` + * ``` + */ +const md = createTaggedTemplateDisplayable("text/markdown"); + +/** + * Show HTML in Jupyter frontends with a tagged template function. + * + * Takes a template string and returns a displayable object for Jupyter frontends. + * + * @example + * Create an HTML view. + * ```typescript + * html`

Hello, world!

` + * ``` + */ +const html = createTaggedTemplateDisplayable("text/html"); +/** + * SVG Tagged Template Function. + * + * Takes a template string and returns a displayable object for Jupyter frontends. + * + * Example usage: + * + * svg` + * + * ` + */ +const svg = createTaggedTemplateDisplayable("image/svg+xml"); + +function isMediaBundle(obj) { + if (obj == null || typeof obj !== "object" || Array.isArray(obj)) { + return false; + } + for (const key in obj) { + if (typeof key !== "string") { + return false; + } + } + return true; +} + +async function formatInner(obj, raw) { + if (raw && isMediaBundle(obj)) { + return obj; + } else { + return await format(obj); + } +} + +internals.jupyter = { formatInner }; + function enableJupyter() { const { op_jupyter_broadcast, } = core.ensureFastOps(); + async function broadcast( + msgType, + content, + { metadata = {}, buffers = [] } = {}, + ) { + await op_jupyter_broadcast(msgType, content, metadata, buffers); + } + + async function broadcastResult(executionCount, result) { + try { + if (result === undefined) { + return; + } + + const data = await format(result); + await broadcast("execute_result", { + execution_count: executionCount, + data, + metadata: {}, + }); + } catch (err) { + if (err instanceof Error) { + const stack = err.stack || ""; + await broadcast("error", { + ename: err.name, + evalue: err.message, + traceback: stack.split("\n"), + }); + } else if (typeof err == "string") { + await broadcast("error", { + ename: "Error", + evalue: err, + traceback: [], + }); + } else { + await broadcast("error", { + ename: "Error", + evalue: + "An error occurred while formatting a result, but it could not be identified", + traceback: [], + }); + } + } + } + + internals.jupyter.broadcastResult = broadcastResult; + + /** + * Display function for Jupyter Deno Kernel. + * Mimics the behavior of IPython's `display(obj, raw=True)` function to allow + * asynchronous displaying of objects in Jupyter. + * + * @param obj - The object to be displayed + * @param options - Display options + */ + async function display(obj, options = { raw: false, update: false }) { + const bundle = await formatInner(obj, options.raw); + let messageType = "display_data"; + if (options.update) { + messageType = "update_display_data"; + } + let transient = {}; + if (options.display_id) { + transient = { display_id: options.display_id }; + } + await broadcast(messageType, { + data: bundle, + metadata: {}, + transient, + }); + return; + } + globalThis.Deno.jupyter = { - async broadcast(msgType, content, { metadata = {}, buffers = [] } = {}) { - await op_jupyter_broadcast(msgType, content, metadata, buffers); - }, + broadcast, + display, + format, + md, + html, + svg, + $display, }; } diff --git a/cli/tests/testdata/jupyter/integration_test.ipynb b/cli/tests/testdata/jupyter/integration_test.ipynb index b8aed651c1..19667938ca 100644 --- a/cli/tests/testdata/jupyter/integration_test.ipynb +++ b/cli/tests/testdata/jupyter/integration_test.ipynb @@ -108,7 +108,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "id": "08a17340", "metadata": { "hidden": true @@ -120,7 +120,7 @@ "{ color: \u001b[32m\"red\"\u001b[39m, area: \u001b[33m10000\u001b[39m }" ] }, - "execution_count": 4, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -165,7 +165,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "bbf2c09b", "metadata": { "hidden": true @@ -188,7 +188,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "d9801d80", "metadata": { "hidden": true @@ -200,7 +200,7 @@ "\u001b[1mnull\u001b[22m" ] }, - "execution_count": 6, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -222,7 +222,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "cfaac330", "metadata": { "hidden": true @@ -234,7 +234,7 @@ "\u001b[33mtrue\u001b[39m" ] }, - "execution_count": 7, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -256,7 +256,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "id": "ec3be2da", "metadata": { "hidden": true @@ -268,7 +268,7 @@ "\u001b[33m42\u001b[39m" ] }, - "execution_count": 8, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -290,7 +290,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "id": "997cf2d7", "metadata": { "hidden": true @@ -302,7 +302,7 @@ "\u001b[32m\"this is a test of the emergency broadcast system\"\u001b[39m" ] }, - "execution_count": 9, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -324,7 +324,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "id": "44b63807", "metadata": { "hidden": true @@ -336,7 +336,7 @@ "\u001b[33m31337n\u001b[39m" ] }, - "execution_count": 10, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -358,7 +358,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "e10c0d31", "metadata": { "hidden": true @@ -370,7 +370,7 @@ "\u001b[32mSymbol(foo)\u001b[39m" ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -392,7 +392,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 14, "id": "81c99233", "metadata": { "hidden": true @@ -404,7 +404,7 @@ "{ foo: \u001b[32m\"bar\"\u001b[39m }" ] }, - "execution_count": 12, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -426,7 +426,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 15, "id": "43c1581b", "metadata": { "hidden": true @@ -438,7 +438,7 @@ "Promise { \u001b[32m\"it worked!\"\u001b[39m }" ] }, - "execution_count": 13, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -449,7 +449,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "id": "9a34b725", "metadata": { "hidden": true @@ -464,7 +464,7 @@ "}" ] }, - "execution_count": 14, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -475,7 +475,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 17, "id": "b5c7b819", "metadata": { "scrolled": true @@ -501,7 +501,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 18, "id": "14844fc9-536e-4121-a9bd-fc2d3f7b6395", "metadata": {}, "outputs": [ @@ -522,23 +522,17 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 20, "id": "72d01fdd", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Promise {\n", - " \u001b[36m\u001b[39m NotFound: No such file or directory (os error 2): readfile ''\n", - " at async Object.readFile (ext:deno_fs/30_fs.js:716:18) {\n", - " name: \u001b[32m\"NotFound\"\u001b[39m,\n", - " code: \u001b[32m\"ENOENT\"\u001b[39m\n", - " }\n", - "}" + "Promise { \u001b[36m\u001b[39m }" ] }, - "execution_count": 19, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -549,7 +543,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 21, "id": "28cf59d0-6908-4edc-bb10-c325beeee362", "metadata": {}, "outputs": [ @@ -567,7 +561,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 22, "id": "8d5485c3-0da3-43fe-8ef5-a61e672f5e81", "metadata": {}, "outputs": [ @@ -585,7 +579,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 23, "id": "1401d9d5-6994-4c7b-b55a-db3c16a1e2dc", "metadata": {}, "outputs": [ @@ -595,7 +589,7 @@ "\u001b[32m\"Cool 🫡\"\u001b[39m" ] }, - "execution_count": 22, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -606,7 +600,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 24, "id": "7afdaa0a-a2a0-4f52-8c7d-b6c5f237aa0d", "metadata": {}, "outputs": [ @@ -638,7 +632,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 25, "id": "b33808fd", "metadata": {}, "outputs": [ @@ -648,10 +642,10 @@ "text": [ "passing test ... \u001b[0m\u001b[32mok\u001b[0m \u001b[0m\u001b[38;5;245m(1ms)\u001b[0m\n", "passing test with steps ...\n", - " step 1 ... \u001b[0m\u001b[32mok\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", + " step 1 ... \u001b[0m\u001b[32mok\u001b[0m \u001b[0m\u001b[38;5;245m(1ms)\u001b[0m\n", " step 2 ... \u001b[0m\u001b[32mok\u001b[0m \u001b[0m\u001b[38;5;245m(0ms)\u001b[0m\n", "passing test with steps ... \u001b[0m\u001b[32mok\u001b[0m \u001b[0m\u001b[38;5;245m(1ms)\u001b[0m\n", - "failing test ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(1ms)\u001b[0m\n", + "failing test ... \u001b[0m\u001b[31mFAILED\u001b[0m \u001b[0m\u001b[38;5;245m(2ms)\u001b[0m\n", "\n", "\u001b[0m\u001b[1m\u001b[37m\u001b[41m ERRORS \u001b[0m\n", "\n", @@ -690,7 +684,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 26, "id": "8e93df23-06eb-414b-98d4-51fbebb53d1f", "metadata": {}, "outputs": [ @@ -746,7 +740,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 27, "id": "6e9b530f-554d-4ef7-a5d6-69432283fd40", "metadata": {}, "outputs": [], @@ -793,17 +787,17 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 33, "id": "f678313e-06c6-4fb8-a4ef-54a417129a82", "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
" + "
" ] }, - "execution_count": 26, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -811,7 +805,7 @@ "source": [ "class SuperColor {\n", " constructor() {\n", - " this.color = \"#239814\"\n", + " this.color = \"#ff5398\"\n", " }\n", " hex() {\n", " return this.color\n", @@ -830,17 +824,17 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 32, "id": "c1296291-a3e8-457b-8329-6cc58a1e528a", "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
" + "
" ] }, - "execution_count": 27, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -848,7 +842,7 @@ "source": [ "class SuperColorAsync {\n", " constructor() {\n", - " this.color = \"#239814\"\n", + " this.color = \"#5398ff\"\n", " }\n", " hex() {\n", " return this.color\n", @@ -864,6 +858,3553 @@ "let sc = new SuperColorAsync()\n", "sc" ] + }, + { + "cell_type": "markdown", + "id": "60b7d0da-53bf-4b42-a7d1-8370c7e2314d", + "metadata": {}, + "source": [ + "## Some classes will have built in support / handling via `Deno.jupyter.format` under the hood." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "a46fb36b-bdf4-48d9-ae8c-9842d23b5456", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.dataresource+json": { + "data": [ + { + "abbrev": "Kos.", + "abbrev_len": 4, + "adm0_a3": "KOS", + "adm0_a3_is": "SRB", + "adm0_a3_un": -99, + "adm0_a3_us": "KOS", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Kosovo", + "brk_a3": "B57", + "brk_diff": 1, + "brk_group": null, + "brk_name": "Kosovo", + "continent": "Europe", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Kosovo", + "formal_fr": null, + "gdp_md_est": 5352, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Kosovo", + "gu_a3": "KOS", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "-99", + "iso_a3": "-99", + "iso_n3": -99, + "labelrank": 6, + "lastcensus": 1981, + "level": 2, + "long_len": 6, + "mapcolor13": 11, + "mapcolor7": 2, + "mapcolor8": 2, + "mapcolor9": 3, + "name": "Kosovo", + "name_alt": null, + "name_len": 6, + "name_long": "Kosovo", + "name_sort": "Kosovo", + "note_adm0": null, + "note_brk": "Self admin.; Claimed by Serbia", + "pop_est": 1804838, + "pop_year": -99, + "postal": "KO", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "KOS", + "sovereignt": "Kosovo", + "su_a3": "KOS", + "su_dif": 0, + "subregion": "Southern Europe", + "subunit": "Kosovo", + "tiny": -99, + "type": "Sovereign country", + "un_a3": -99, + "wb_a2": "KV", + "wb_a3": "KSV", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Solnd.", + "abbrev_len": 6, + "adm0_a3": "SOL", + "adm0_a3_is": "SOM", + "adm0_a3_un": -99, + "adm0_a3_us": "SOM", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Somaliland", + "brk_a3": "B30", + "brk_diff": 1, + "brk_group": null, + "brk_name": "Somaliland", + "continent": "Africa", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Somaliland", + "formal_fr": null, + "gdp_md_est": 12250, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Somaliland", + "gu_a3": "SOL", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "-99", + "iso_a3": "-99", + "iso_n3": -99, + "labelrank": 5, + "lastcensus": -99, + "level": 2, + "long_len": 10, + "mapcolor13": 2, + "mapcolor7": 3, + "mapcolor8": 6, + "mapcolor9": 5, + "name": "Somaliland", + "name_alt": null, + "name_len": 10, + "name_long": "Somaliland", + "name_sort": "Somaliland", + "note_adm0": "Self admin.", + "note_brk": "Self admin.; Claimed by Somalia", + "pop_est": 3500000, + "pop_year": -99, + "postal": "SL", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "SOL", + "sovereignt": "Somaliland", + "su_a3": "SOL", + "su_dif": 0, + "subregion": "Eastern Africa", + "subunit": "Somaliland", + "tiny": -99, + "type": "Indeterminate", + "un_a3": -99, + "wb_a2": "-99", + "wb_a3": "-99", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "N. Cy.", + "abbrev_len": 6, + "adm0_a3": "CYN", + "adm0_a3_is": "CYP", + "adm0_a3_un": -99, + "adm0_a3_us": "CYP", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Northern Cyprus", + "brk_a3": "B20", + "brk_diff": 1, + "brk_group": null, + "brk_name": "N. Cyprus", + "continent": "Asia", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Turkish Republic of Northern Cyprus", + "formal_fr": null, + "gdp_md_est": 3600, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Northern Cyprus", + "gu_a3": "CYN", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "-99", + "iso_a3": "-99", + "iso_n3": -99, + "labelrank": 6, + "lastcensus": -99, + "level": 2, + "long_len": 15, + "mapcolor13": 8, + "mapcolor7": 3, + "mapcolor8": 1, + "mapcolor9": 4, + "name": "N. Cyprus", + "name_alt": null, + "name_len": 9, + "name_long": "Northern Cyprus", + "name_sort": "Cyprus, Northern", + "note_adm0": "Self admin.", + "note_brk": "Self admin.; Claimed by Cyprus", + "pop_est": 265100, + "pop_year": -99, + "postal": "CN", + "region_un": "Asia", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "CYN", + "sovereignt": "Northern Cyprus", + "su_a3": "CYN", + "su_dif": 0, + "subregion": "Western Asia", + "subunit": "Northern Cyprus", + "tiny": -99, + "type": "Sovereign country", + "un_a3": -99, + "wb_a2": "-99", + "wb_a3": "-99", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Afg.", + "abbrev_len": 4, + "adm0_a3": "AFG", + "adm0_a3_is": "AFG", + "adm0_a3_un": -99, + "adm0_a3_us": "AFG", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Afghanistan", + "brk_a3": "AFG", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Afghanistan", + "continent": "Asia", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Islamic State of Afghanistan", + "formal_fr": null, + "gdp_md_est": 22270, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Afghanistan", + "gu_a3": "AFG", + "homepart": 1, + "income_grp": "5. Low income", + "iso_a2": "AF", + "iso_a3": "AFG", + "iso_n3": 4, + "labelrank": 3, + "lastcensus": 1979, + "level": 2, + "long_len": 11, + "mapcolor13": 7, + "mapcolor7": 5, + "mapcolor8": 6, + "mapcolor9": 8, + "name": "Afghanistan", + "name_alt": null, + "name_len": 11, + "name_long": "Afghanistan", + "name_sort": "Afghanistan", + "note_adm0": null, + "note_brk": null, + "pop_est": 28400000, + "pop_year": -99, + "postal": "AF", + "region_un": "Asia", + "region_wb": "South Asia", + "scalerank": 1, + "sov_a3": "AFG", + "sovereignt": "Afghanistan", + "su_a3": "AFG", + "su_dif": 0, + "subregion": "Southern Asia", + "subunit": "Afghanistan", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 4, + "wb_a2": "AF", + "wb_a3": "AFG", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Ang.", + "abbrev_len": 4, + "adm0_a3": "AGO", + "adm0_a3_is": "AGO", + "adm0_a3_un": -99, + "adm0_a3_us": "AGO", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Angola", + "brk_a3": "AGO", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Angola", + "continent": "Africa", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "People's Republic of Angola", + "formal_fr": null, + "gdp_md_est": 110300, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Angola", + "gu_a3": "AGO", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "AO", + "iso_a3": "AGO", + "iso_n3": 24, + "labelrank": 3, + "lastcensus": 1970, + "level": 2, + "long_len": 6, + "mapcolor13": 1, + "mapcolor7": 3, + "mapcolor8": 2, + "mapcolor9": 6, + "name": "Angola", + "name_alt": null, + "name_len": 6, + "name_long": "Angola", + "name_sort": "Angola", + "note_adm0": null, + "note_brk": null, + "pop_est": 12799293, + "pop_year": -99, + "postal": "AO", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "AGO", + "sovereignt": "Angola", + "su_a3": "AGO", + "su_dif": 0, + "subregion": "Middle Africa", + "subunit": "Angola", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 24, + "wb_a2": "AO", + "wb_a3": "AGO", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Alb.", + "abbrev_len": 4, + "adm0_a3": "ALB", + "adm0_a3_is": "ALB", + "adm0_a3_un": -99, + "adm0_a3_us": "ALB", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Albania", + "brk_a3": "ALB", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Albania", + "continent": "Europe", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Albania", + "formal_fr": null, + "gdp_md_est": 21810, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Albania", + "gu_a3": "ALB", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "AL", + "iso_a3": "ALB", + "iso_n3": 8, + "labelrank": 6, + "lastcensus": 2001, + "level": 2, + "long_len": 7, + "mapcolor13": 6, + "mapcolor7": 1, + "mapcolor8": 4, + "mapcolor9": 1, + "name": "Albania", + "name_alt": null, + "name_len": 7, + "name_long": "Albania", + "name_sort": "Albania", + "note_adm0": null, + "note_brk": null, + "pop_est": 3639453, + "pop_year": -99, + "postal": "AL", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "ALB", + "sovereignt": "Albania", + "su_a3": "ALB", + "su_dif": 0, + "subregion": "Southern Europe", + "subunit": "Albania", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 8, + "wb_a2": "AL", + "wb_a3": "ALB", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "U.A.E.", + "abbrev_len": 6, + "adm0_a3": "ARE", + "adm0_a3_is": "ARE", + "adm0_a3_un": -99, + "adm0_a3_us": "ARE", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "United Arab Emirates", + "brk_a3": "ARE", + "brk_diff": 0, + "brk_group": null, + "brk_name": "United Arab Emirates", + "continent": "Asia", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "United Arab Emirates", + "formal_fr": null, + "gdp_md_est": 184300, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "United Arab Emirates", + "gu_a3": "ARE", + "homepart": 1, + "income_grp": "2. High income: nonOECD", + "iso_a2": "AE", + "iso_a3": "ARE", + "iso_n3": 784, + "labelrank": 4, + "lastcensus": 2010, + "level": 2, + "long_len": 20, + "mapcolor13": 3, + "mapcolor7": 2, + "mapcolor8": 1, + "mapcolor9": 3, + "name": "United Arab Emirates", + "name_alt": null, + "name_len": 20, + "name_long": "United Arab Emirates", + "name_sort": "United Arab Emirates", + "note_adm0": null, + "note_brk": null, + "pop_est": 4798491, + "pop_year": -99, + "postal": "AE", + "region_un": "Asia", + "region_wb": "Middle East & North Africa", + "scalerank": 1, + "sov_a3": "ARE", + "sovereignt": "United Arab Emirates", + "su_a3": "ARE", + "su_dif": 0, + "subregion": "Western Asia", + "subunit": "United Arab Emirates", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 784, + "wb_a2": "AE", + "wb_a3": "ARE", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Arg.", + "abbrev_len": 4, + "adm0_a3": "ARG", + "adm0_a3_is": "ARG", + "adm0_a3_un": -99, + "adm0_a3_us": "ARG", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Argentina", + "brk_a3": "ARG", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Argentina", + "continent": "South America", + "economy": "5. Emerging region: G20", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Argentine Republic", + "formal_fr": null, + "gdp_md_est": 573900, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Argentina", + "gu_a3": "ARG", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "AR", + "iso_a3": "ARG", + "iso_n3": 32, + "labelrank": 2, + "lastcensus": 2010, + "level": 2, + "long_len": 9, + "mapcolor13": 13, + "mapcolor7": 3, + "mapcolor8": 1, + "mapcolor9": 3, + "name": "Argentina", + "name_alt": null, + "name_len": 9, + "name_long": "Argentina", + "name_sort": "Argentina", + "note_adm0": null, + "note_brk": null, + "pop_est": 40913584, + "pop_year": -99, + "postal": "AR", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "ARG", + "sovereignt": "Argentina", + "su_a3": "ARG", + "su_dif": 0, + "subregion": "South America", + "subunit": "Argentina", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 32, + "wb_a2": "AR", + "wb_a3": "ARG", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Arm.", + "abbrev_len": 4, + "adm0_a3": "ARM", + "adm0_a3_is": "ARM", + "adm0_a3_un": -99, + "adm0_a3_us": "ARM", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Armenia", + "brk_a3": "ARM", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Armenia", + "continent": "Asia", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Armenia", + "formal_fr": null, + "gdp_md_est": 18770, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Armenia", + "gu_a3": "ARM", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "AM", + "iso_a3": "ARM", + "iso_n3": 51, + "labelrank": 6, + "lastcensus": 2001, + "level": 2, + "long_len": 7, + "mapcolor13": 10, + "mapcolor7": 3, + "mapcolor8": 1, + "mapcolor9": 2, + "name": "Armenia", + "name_alt": null, + "name_len": 7, + "name_long": "Armenia", + "name_sort": "Armenia", + "note_adm0": null, + "note_brk": null, + "pop_est": 2967004, + "pop_year": -99, + "postal": "ARM", + "region_un": "Asia", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "ARM", + "sovereignt": "Armenia", + "su_a3": "ARM", + "su_dif": 0, + "subregion": "Western Asia", + "subunit": "Armenia", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 51, + "wb_a2": "AM", + "wb_a3": "ARM", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Ant.", + "abbrev_len": 4, + "adm0_a3": "ATA", + "adm0_a3_is": "ATA", + "adm0_a3_un": -99, + "adm0_a3_us": "ATA", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Antarctica", + "brk_a3": "ATA", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Antarctica", + "continent": "Antarctica", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": null, + "formal_fr": null, + "gdp_md_est": 760.4, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Antarctica", + "gu_a3": "ATA", + "homepart": 1, + "income_grp": "2. High income: nonOECD", + "iso_a2": "AQ", + "iso_a3": "ATA", + "iso_n3": 10, + "labelrank": 4, + "lastcensus": -99, + "level": 2, + "long_len": 10, + "mapcolor13": -99, + "mapcolor7": 4, + "mapcolor8": 5, + "mapcolor9": 1, + "name": "Antarctica", + "name_alt": null, + "name_len": 10, + "name_long": "Antarctica", + "name_sort": "Antarctica", + "note_adm0": null, + "note_brk": "Multiple claims held in abeyance", + "pop_est": 3802, + "pop_year": -99, + "postal": "AQ", + "region_un": "Antarctica", + "region_wb": "Antarctica", + "scalerank": 1, + "sov_a3": "ATA", + "sovereignt": "Antarctica", + "su_a3": "ATA", + "su_dif": 0, + "subregion": "Antarctica", + "subunit": "Antarctica", + "tiny": -99, + "type": "Indeterminate", + "un_a3": -99, + "wb_a2": "-99", + "wb_a3": "-99", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Fr. S.A.L.", + "abbrev_len": 10, + "adm0_a3": "ATF", + "adm0_a3_is": "ATF", + "adm0_a3_un": -99, + "adm0_a3_us": "ATF", + "adm0_a3_wb": -99, + "adm0_dif": 1, + "admin": "French Southern and Antarctic Lands", + "brk_a3": "ATF", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Fr. S. and Antarctic Lands", + "continent": "Seven seas (open ocean)", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Territory of the French Southern and Antarctic Lands", + "formal_fr": null, + "gdp_md_est": 16, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "French Southern and Antarctic Lands", + "gu_a3": "ATF", + "homepart": -99, + "income_grp": "2. High income: nonOECD", + "iso_a2": "TF", + "iso_a3": "ATF", + "iso_n3": 260, + "labelrank": 6, + "lastcensus": -99, + "level": 2, + "long_len": 35, + "mapcolor13": 11, + "mapcolor7": 7, + "mapcolor8": 5, + "mapcolor9": 9, + "name": "Fr. S. Antarctic Lands", + "name_alt": null, + "name_len": 22, + "name_long": "French Southern and Antarctic Lands", + "name_sort": "French Southern and Antarctic Lands", + "note_adm0": "Fr.", + "note_brk": null, + "pop_est": 140, + "pop_year": -99, + "postal": "TF", + "region_un": "Seven seas (open ocean)", + "region_wb": "Sub-Saharan Africa", + "scalerank": 3, + "sov_a3": "FR1", + "sovereignt": "France", + "su_a3": "ATF", + "su_dif": 0, + "subregion": "Seven seas (open ocean)", + "subunit": "French Southern and Antarctic Lands", + "tiny": 2, + "type": "Dependency", + "un_a3": -99, + "wb_a2": "-99", + "wb_a3": "-99", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Auz.", + "abbrev_len": 4, + "adm0_a3": "AUS", + "adm0_a3_is": "AUS", + "adm0_a3_un": -99, + "adm0_a3_us": "AUS", + "adm0_a3_wb": -99, + "adm0_dif": 1, + "admin": "Australia", + "brk_a3": "AUS", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Australia", + "continent": "Oceania", + "economy": "2. Developed region: nonG7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Commonwealth of Australia", + "formal_fr": null, + "gdp_md_est": 800200, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Australia", + "gu_a3": "AUS", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "AU", + "iso_a3": "AUS", + "iso_n3": 36, + "labelrank": 2, + "lastcensus": 2006, + "level": 2, + "long_len": 9, + "mapcolor13": 7, + "mapcolor7": 1, + "mapcolor8": 2, + "mapcolor9": 2, + "name": "Australia", + "name_alt": null, + "name_len": 9, + "name_long": "Australia", + "name_sort": "Australia", + "note_adm0": null, + "note_brk": null, + "pop_est": 21262641, + "pop_year": -99, + "postal": "AU", + "region_un": "Oceania", + "region_wb": "East Asia & Pacific", + "scalerank": 1, + "sov_a3": "AU1", + "sovereignt": "Australia", + "su_a3": "AUS", + "su_dif": 0, + "subregion": "Australia and New Zealand", + "subunit": "Australia", + "tiny": -99, + "type": "Country", + "un_a3": 36, + "wb_a2": "AU", + "wb_a3": "AUS", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Aust.", + "abbrev_len": 5, + "adm0_a3": "AUT", + "adm0_a3_is": "AUT", + "adm0_a3_un": -99, + "adm0_a3_us": "AUT", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Austria", + "brk_a3": "AUT", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Austria", + "continent": "Europe", + "economy": "2. Developed region: nonG7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Austria", + "formal_fr": null, + "gdp_md_est": 329500, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Austria", + "gu_a3": "AUT", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "AT", + "iso_a3": "AUT", + "iso_n3": 40, + "labelrank": 4, + "lastcensus": 2011, + "level": 2, + "long_len": 7, + "mapcolor13": 4, + "mapcolor7": 3, + "mapcolor8": 1, + "mapcolor9": 3, + "name": "Austria", + "name_alt": null, + "name_len": 7, + "name_long": "Austria", + "name_sort": "Austria", + "note_adm0": null, + "note_brk": null, + "pop_est": 8210281, + "pop_year": -99, + "postal": "A", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "AUT", + "sovereignt": "Austria", + "su_a3": "AUT", + "su_dif": 0, + "subregion": "Western Europe", + "subunit": "Austria", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 40, + "wb_a2": "AT", + "wb_a3": "AUT", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Aze.", + "abbrev_len": 4, + "adm0_a3": "AZE", + "adm0_a3_is": "AZE", + "adm0_a3_un": -99, + "adm0_a3_us": "AZE", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Azerbaijan", + "brk_a3": "AZE", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Azerbaijan", + "continent": "Asia", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Azerbaijan", + "formal_fr": null, + "gdp_md_est": 77610, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Azerbaijan", + "gu_a3": "AZE", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "AZ", + "iso_a3": "AZE", + "iso_n3": 31, + "labelrank": 5, + "lastcensus": 2009, + "level": 2, + "long_len": 10, + "mapcolor13": 8, + "mapcolor7": 1, + "mapcolor8": 6, + "mapcolor9": 5, + "name": "Azerbaijan", + "name_alt": null, + "name_len": 10, + "name_long": "Azerbaijan", + "name_sort": "Azerbaijan", + "note_adm0": null, + "note_brk": null, + "pop_est": 8238672, + "pop_year": -99, + "postal": "AZ", + "region_un": "Asia", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "AZE", + "sovereignt": "Azerbaijan", + "su_a3": "AZE", + "su_dif": 0, + "subregion": "Western Asia", + "subunit": "Azerbaijan", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 31, + "wb_a2": "AZ", + "wb_a3": "AZE", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bur.", + "abbrev_len": 4, + "adm0_a3": "BDI", + "adm0_a3_is": "BDI", + "adm0_a3_un": -99, + "adm0_a3_us": "BDI", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Burundi", + "brk_a3": "BDI", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Burundi", + "continent": "Africa", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Burundi", + "formal_fr": null, + "gdp_md_est": 3102, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Burundi", + "gu_a3": "BDI", + "homepart": 1, + "income_grp": "5. Low income", + "iso_a2": "BI", + "iso_a3": "BDI", + "iso_n3": 108, + "labelrank": 6, + "lastcensus": 2008, + "level": 2, + "long_len": 7, + "mapcolor13": 8, + "mapcolor7": 2, + "mapcolor8": 2, + "mapcolor9": 5, + "name": "Burundi", + "name_alt": null, + "name_len": 7, + "name_long": "Burundi", + "name_sort": "Burundi", + "note_adm0": null, + "note_brk": null, + "pop_est": 8988091, + "pop_year": -99, + "postal": "BI", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "BDI", + "sovereignt": "Burundi", + "su_a3": "BDI", + "su_dif": 0, + "subregion": "Eastern Africa", + "subunit": "Burundi", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 108, + "wb_a2": "BI", + "wb_a3": "BDI", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Belg.", + "abbrev_len": 5, + "adm0_a3": "BEL", + "adm0_a3_is": "BEL", + "adm0_a3_un": -99, + "adm0_a3_us": "BEL", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Belgium", + "brk_a3": "BEL", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Belgium", + "continent": "Europe", + "economy": "2. Developed region: nonG7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Kingdom of Belgium", + "formal_fr": null, + "gdp_md_est": 389300, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Belgium", + "gu_a3": "BEL", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "BE", + "iso_a3": "BEL", + "iso_n3": 56, + "labelrank": 2, + "lastcensus": 2011, + "level": 2, + "long_len": 7, + "mapcolor13": 8, + "mapcolor7": 3, + "mapcolor8": 2, + "mapcolor9": 1, + "name": "Belgium", + "name_alt": null, + "name_len": 7, + "name_long": "Belgium", + "name_sort": "Belgium", + "note_adm0": null, + "note_brk": null, + "pop_est": 10414336, + "pop_year": -99, + "postal": "B", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "BEL", + "sovereignt": "Belgium", + "su_a3": "BEL", + "su_dif": 0, + "subregion": "Western Europe", + "subunit": "Belgium", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 56, + "wb_a2": "BE", + "wb_a3": "BEL", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Benin", + "abbrev_len": 5, + "adm0_a3": "BEN", + "adm0_a3_is": "BEN", + "adm0_a3_un": -99, + "adm0_a3_us": "BEN", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Benin", + "brk_a3": "BEN", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Benin", + "continent": "Africa", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Benin", + "formal_fr": null, + "gdp_md_est": 12830, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Benin", + "gu_a3": "BEN", + "homepart": 1, + "income_grp": "5. Low income", + "iso_a2": "BJ", + "iso_a3": "BEN", + "iso_n3": 204, + "labelrank": 5, + "lastcensus": 2002, + "level": 2, + "long_len": 5, + "mapcolor13": 12, + "mapcolor7": 1, + "mapcolor8": 2, + "mapcolor9": 2, + "name": "Benin", + "name_alt": null, + "name_len": 5, + "name_long": "Benin", + "name_sort": "Benin", + "note_adm0": null, + "note_brk": null, + "pop_est": 8791832, + "pop_year": -99, + "postal": "BJ", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "BEN", + "sovereignt": "Benin", + "su_a3": "BEN", + "su_dif": 0, + "subregion": "Western Africa", + "subunit": "Benin", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 204, + "wb_a2": "BJ", + "wb_a3": "BEN", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "B.F.", + "abbrev_len": 4, + "adm0_a3": "BFA", + "adm0_a3_is": "BFA", + "adm0_a3_un": -99, + "adm0_a3_us": "BFA", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Burkina Faso", + "brk_a3": "BFA", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Burkina Faso", + "continent": "Africa", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Burkina Faso", + "formal_fr": null, + "gdp_md_est": 17820, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Burkina Faso", + "gu_a3": "BFA", + "homepart": 1, + "income_grp": "5. Low income", + "iso_a2": "BF", + "iso_a3": "BFA", + "iso_n3": 854, + "labelrank": 3, + "lastcensus": 2006, + "level": 2, + "long_len": 12, + "mapcolor13": 11, + "mapcolor7": 2, + "mapcolor8": 1, + "mapcolor9": 5, + "name": "Burkina Faso", + "name_alt": null, + "name_len": 12, + "name_long": "Burkina Faso", + "name_sort": "Burkina Faso", + "note_adm0": null, + "note_brk": null, + "pop_est": 15746232, + "pop_year": -99, + "postal": "BF", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "BFA", + "sovereignt": "Burkina Faso", + "su_a3": "BFA", + "su_dif": 0, + "subregion": "Western Africa", + "subunit": "Burkina Faso", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 854, + "wb_a2": "BF", + "wb_a3": "BFA", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bang.", + "abbrev_len": 5, + "adm0_a3": "BGD", + "adm0_a3_is": "BGD", + "adm0_a3_un": -99, + "adm0_a3_us": "BGD", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Bangladesh", + "brk_a3": "BGD", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Bangladesh", + "continent": "Asia", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "People's Republic of Bangladesh", + "formal_fr": null, + "gdp_md_est": 224000, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Bangladesh", + "gu_a3": "BGD", + "homepart": 1, + "income_grp": "5. Low income", + "iso_a2": "BD", + "iso_a3": "BGD", + "iso_n3": 50, + "labelrank": 3, + "lastcensus": 2011, + "level": 2, + "long_len": 10, + "mapcolor13": 7, + "mapcolor7": 3, + "mapcolor8": 4, + "mapcolor9": 7, + "name": "Bangladesh", + "name_alt": null, + "name_len": 10, + "name_long": "Bangladesh", + "name_sort": "Bangladesh", + "note_adm0": null, + "note_brk": null, + "pop_est": 156050883, + "pop_year": -99, + "postal": "BD", + "region_un": "Asia", + "region_wb": "South Asia", + "scalerank": 1, + "sov_a3": "BGD", + "sovereignt": "Bangladesh", + "su_a3": "BGD", + "su_dif": 0, + "subregion": "Southern Asia", + "subunit": "Bangladesh", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 50, + "wb_a2": "BD", + "wb_a3": "BGD", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bulg.", + "abbrev_len": 5, + "adm0_a3": "BGR", + "adm0_a3_is": "BGR", + "adm0_a3_un": -99, + "adm0_a3_us": "BGR", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Bulgaria", + "brk_a3": "BGR", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Bulgaria", + "continent": "Europe", + "economy": "2. Developed region: nonG7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Bulgaria", + "formal_fr": null, + "gdp_md_est": 93750, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Bulgaria", + "gu_a3": "BGR", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "BG", + "iso_a3": "BGR", + "iso_n3": 100, + "labelrank": 4, + "lastcensus": 2011, + "level": 2, + "long_len": 8, + "mapcolor13": 8, + "mapcolor7": 4, + "mapcolor8": 5, + "mapcolor9": 1, + "name": "Bulgaria", + "name_alt": null, + "name_len": 8, + "name_long": "Bulgaria", + "name_sort": "Bulgaria", + "note_adm0": null, + "note_brk": null, + "pop_est": 7204687, + "pop_year": -99, + "postal": "BG", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "BGR", + "sovereignt": "Bulgaria", + "su_a3": "BGR", + "su_dif": 0, + "subregion": "Eastern Europe", + "subunit": "Bulgaria", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 100, + "wb_a2": "BG", + "wb_a3": "BGR", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bhs.", + "abbrev_len": 4, + "adm0_a3": "BHS", + "adm0_a3_is": "BHS", + "adm0_a3_un": -99, + "adm0_a3_us": "BHS", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "The Bahamas", + "brk_a3": "BHS", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Bahamas", + "continent": "North America", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Commonwealth of the Bahamas", + "formal_fr": null, + "gdp_md_est": 9093, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "The Bahamas", + "gu_a3": "BHS", + "homepart": 1, + "income_grp": "2. High income: nonOECD", + "iso_a2": "BS", + "iso_a3": "BHS", + "iso_n3": 44, + "labelrank": 4, + "lastcensus": 2010, + "level": 2, + "long_len": 7, + "mapcolor13": 5, + "mapcolor7": 1, + "mapcolor8": 1, + "mapcolor9": 2, + "name": "Bahamas", + "name_alt": null, + "name_len": 7, + "name_long": "Bahamas", + "name_sort": "Bahamas, The", + "note_adm0": null, + "note_brk": null, + "pop_est": 309156, + "pop_year": -99, + "postal": "BS", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "BHS", + "sovereignt": "The Bahamas", + "su_a3": "BHS", + "su_dif": 0, + "subregion": "Caribbean", + "subunit": "The Bahamas", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 44, + "wb_a2": "BS", + "wb_a3": "BHS", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "B.H.", + "abbrev_len": 4, + "adm0_a3": "BIH", + "adm0_a3_is": "BIH", + "adm0_a3_un": -99, + "adm0_a3_us": "BIH", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Bosnia and Herzegovina", + "brk_a3": "BIH", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Bosnia and Herz.", + "continent": "Europe", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Bosnia and Herzegovina", + "formal_fr": null, + "gdp_md_est": 29700, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Bosnia and Herzegovina", + "gu_a3": "BIH", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "BA", + "iso_a3": "BIH", + "iso_n3": 70, + "labelrank": 5, + "lastcensus": 1991, + "level": 2, + "long_len": 22, + "mapcolor13": 2, + "mapcolor7": 1, + "mapcolor8": 1, + "mapcolor9": 1, + "name": "Bosnia and Herz.", + "name_alt": null, + "name_len": 16, + "name_long": "Bosnia and Herzegovina", + "name_sort": "Bosnia and Herzegovina", + "note_adm0": null, + "note_brk": null, + "pop_est": 4613414, + "pop_year": -99, + "postal": "BiH", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "BIH", + "sovereignt": "Bosnia and Herzegovina", + "su_a3": "BIH", + "su_dif": 0, + "subregion": "Southern Europe", + "subunit": "Bosnia and Herzegovina", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 70, + "wb_a2": "BA", + "wb_a3": "BIH", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bela.", + "abbrev_len": 5, + "adm0_a3": "BLR", + "adm0_a3_is": "BLR", + "adm0_a3_un": -99, + "adm0_a3_us": "BLR", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Belarus", + "brk_a3": "BLR", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Belarus", + "continent": "Europe", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Belarus", + "formal_fr": null, + "gdp_md_est": 114100, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Belarus", + "gu_a3": "BLR", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "BY", + "iso_a3": "BLR", + "iso_n3": 112, + "labelrank": 4, + "lastcensus": 2009, + "level": 2, + "long_len": 7, + "mapcolor13": 11, + "mapcolor7": 1, + "mapcolor8": 1, + "mapcolor9": 5, + "name": "Belarus", + "name_alt": null, + "name_len": 7, + "name_long": "Belarus", + "name_sort": "Belarus", + "note_adm0": null, + "note_brk": null, + "pop_est": 9648533, + "pop_year": -99, + "postal": "BY", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "BLR", + "sovereignt": "Belarus", + "su_a3": "BLR", + "su_dif": 0, + "subregion": "Eastern Europe", + "subunit": "Belarus", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 112, + "wb_a2": "BY", + "wb_a3": "BLR", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Belize", + "abbrev_len": 6, + "adm0_a3": "BLZ", + "adm0_a3_is": "BLZ", + "adm0_a3_un": -99, + "adm0_a3_us": "BLZ", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Belize", + "brk_a3": "BLZ", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Belize", + "continent": "North America", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Belize", + "formal_fr": null, + "gdp_md_est": 2536, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Belize", + "gu_a3": "BLZ", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "BZ", + "iso_a3": "BLZ", + "iso_n3": 84, + "labelrank": 6, + "lastcensus": 2010, + "level": 2, + "long_len": 6, + "mapcolor13": 7, + "mapcolor7": 1, + "mapcolor8": 4, + "mapcolor9": 5, + "name": "Belize", + "name_alt": null, + "name_len": 6, + "name_long": "Belize", + "name_sort": "Belize", + "note_adm0": null, + "note_brk": null, + "pop_est": 307899, + "pop_year": -99, + "postal": "BZ", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "BLZ", + "sovereignt": "Belize", + "su_a3": "BLZ", + "su_dif": 0, + "subregion": "Central America", + "subunit": "Belize", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 84, + "wb_a2": "BZ", + "wb_a3": "BLZ", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bolivia", + "abbrev_len": 7, + "adm0_a3": "BOL", + "adm0_a3_is": "BOL", + "adm0_a3_un": -99, + "adm0_a3_us": "BOL", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Bolivia", + "brk_a3": "BOL", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Bolivia", + "continent": "South America", + "economy": "5. Emerging region: G20", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Plurinational State of Bolivia", + "formal_fr": null, + "gdp_md_est": 43270, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Bolivia", + "gu_a3": "BOL", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "BO", + "iso_a3": "BOL", + "iso_n3": 68, + "labelrank": 3, + "lastcensus": 2001, + "level": 2, + "long_len": 7, + "mapcolor13": 3, + "mapcolor7": 1, + "mapcolor8": 5, + "mapcolor9": 2, + "name": "Bolivia", + "name_alt": null, + "name_len": 7, + "name_long": "Bolivia", + "name_sort": "Bolivia", + "note_adm0": null, + "note_brk": null, + "pop_est": 9775246, + "pop_year": -99, + "postal": "BO", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "BOL", + "sovereignt": "Bolivia", + "su_a3": "BOL", + "su_dif": 0, + "subregion": "South America", + "subunit": "Bolivia", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 68, + "wb_a2": "BO", + "wb_a3": "BOL", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Brazil", + "abbrev_len": 6, + "adm0_a3": "BRA", + "adm0_a3_is": "BRA", + "adm0_a3_un": -99, + "adm0_a3_us": "BRA", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Brazil", + "brk_a3": "BRA", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Brazil", + "continent": "South America", + "economy": "3. Emerging region: BRIC", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Federative Republic of Brazil", + "formal_fr": null, + "gdp_md_est": 1993000, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Brazil", + "gu_a3": "BRA", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "BR", + "iso_a3": "BRA", + "iso_n3": 76, + "labelrank": 2, + "lastcensus": 2010, + "level": 2, + "long_len": 6, + "mapcolor13": 7, + "mapcolor7": 5, + "mapcolor8": 6, + "mapcolor9": 5, + "name": "Brazil", + "name_alt": null, + "name_len": 6, + "name_long": "Brazil", + "name_sort": "Brazil", + "note_adm0": null, + "note_brk": null, + "pop_est": 198739269, + "pop_year": -99, + "postal": "BR", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "BRA", + "sovereignt": "Brazil", + "su_a3": "BRA", + "su_dif": 0, + "subregion": "South America", + "subunit": "Brazil", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 76, + "wb_a2": "BR", + "wb_a3": "BRA", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Brunei", + "abbrev_len": 6, + "adm0_a3": "BRN", + "adm0_a3_is": "BRN", + "adm0_a3_un": -99, + "adm0_a3_us": "BRN", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Brunei", + "brk_a3": "BRN", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Brunei", + "continent": "Asia", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Negara Brunei Darussalam", + "formal_fr": null, + "gdp_md_est": 20250, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Brunei", + "gu_a3": "BRN", + "homepart": 1, + "income_grp": "2. High income: nonOECD", + "iso_a2": "BN", + "iso_a3": "BRN", + "iso_n3": 96, + "labelrank": 6, + "lastcensus": 2001, + "level": 2, + "long_len": 17, + "mapcolor13": 12, + "mapcolor7": 4, + "mapcolor8": 6, + "mapcolor9": 6, + "name": "Brunei", + "name_alt": null, + "name_len": 6, + "name_long": "Brunei Darussalam", + "name_sort": "Brunei", + "note_adm0": null, + "note_brk": null, + "pop_est": 388190, + "pop_year": -99, + "postal": "BN", + "region_un": "Asia", + "region_wb": "East Asia & Pacific", + "scalerank": 1, + "sov_a3": "BRN", + "sovereignt": "Brunei", + "su_a3": "BRN", + "su_dif": 0, + "subregion": "South-Eastern Asia", + "subunit": "Brunei", + "tiny": 2, + "type": "Sovereign country", + "un_a3": 96, + "wb_a2": "BN", + "wb_a3": "BRN", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bhutan", + "abbrev_len": 6, + "adm0_a3": "BTN", + "adm0_a3_is": "BTN", + "adm0_a3_un": -99, + "adm0_a3_us": "BTN", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Bhutan", + "brk_a3": "BTN", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Bhutan", + "continent": "Asia", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Kingdom of Bhutan", + "formal_fr": null, + "gdp_md_est": 3524, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Bhutan", + "gu_a3": "BTN", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "BT", + "iso_a3": "BTN", + "iso_n3": 64, + "labelrank": 5, + "lastcensus": 2005, + "level": 2, + "long_len": 6, + "mapcolor13": 8, + "mapcolor7": 5, + "mapcolor8": 6, + "mapcolor9": 1, + "name": "Bhutan", + "name_alt": null, + "name_len": 6, + "name_long": "Bhutan", + "name_sort": "Bhutan", + "note_adm0": null, + "note_brk": null, + "pop_est": 691141, + "pop_year": -99, + "postal": "BT", + "region_un": "Asia", + "region_wb": "South Asia", + "scalerank": 1, + "sov_a3": "BTN", + "sovereignt": "Bhutan", + "su_a3": "BTN", + "su_dif": 0, + "subregion": "Southern Asia", + "subunit": "Bhutan", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 64, + "wb_a2": "BT", + "wb_a3": "BTN", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Bwa.", + "abbrev_len": 4, + "adm0_a3": "BWA", + "adm0_a3_is": "BWA", + "adm0_a3_un": -99, + "adm0_a3_us": "BWA", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Botswana", + "brk_a3": "BWA", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Botswana", + "continent": "Africa", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Botswana", + "formal_fr": null, + "gdp_md_est": 27060, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Botswana", + "gu_a3": "BWA", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "BW", + "iso_a3": "BWA", + "iso_n3": 72, + "labelrank": 4, + "lastcensus": 2011, + "level": 2, + "long_len": 8, + "mapcolor13": 3, + "mapcolor7": 6, + "mapcolor8": 5, + "mapcolor9": 7, + "name": "Botswana", + "name_alt": null, + "name_len": 8, + "name_long": "Botswana", + "name_sort": "Botswana", + "note_adm0": null, + "note_brk": null, + "pop_est": 1990876, + "pop_year": -99, + "postal": "BW", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "BWA", + "sovereignt": "Botswana", + "su_a3": "BWA", + "su_dif": 0, + "subregion": "Southern Africa", + "subunit": "Botswana", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 72, + "wb_a2": "BW", + "wb_a3": "BWA", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "C.A.R.", + "abbrev_len": 6, + "adm0_a3": "CAF", + "adm0_a3_is": "CAF", + "adm0_a3_un": -99, + "adm0_a3_us": "CAF", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Central African Republic", + "brk_a3": "CAF", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Central African Rep.", + "continent": "Africa", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Central African Republic", + "formal_fr": null, + "gdp_md_est": 3198, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Central African Republic", + "gu_a3": "CAF", + "homepart": 1, + "income_grp": "5. Low income", + "iso_a2": "CF", + "iso_a3": "CAF", + "iso_n3": 140, + "labelrank": 4, + "lastcensus": 2003, + "level": 2, + "long_len": 24, + "mapcolor13": 9, + "mapcolor7": 5, + "mapcolor8": 6, + "mapcolor9": 6, + "name": "Central African Rep.", + "name_alt": null, + "name_len": 20, + "name_long": "Central African Republic", + "name_sort": "Central African Republic", + "note_adm0": null, + "note_brk": null, + "pop_est": 4511488, + "pop_year": -99, + "postal": "CF", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "CAF", + "sovereignt": "Central African Republic", + "su_a3": "CAF", + "su_dif": 0, + "subregion": "Middle Africa", + "subunit": "Central African Republic", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 140, + "wb_a2": "CF", + "wb_a3": "CAF", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Can.", + "abbrev_len": 4, + "adm0_a3": "CAN", + "adm0_a3_is": "CAN", + "adm0_a3_un": -99, + "adm0_a3_us": "CAN", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Canada", + "brk_a3": "CAN", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Canada", + "continent": "North America", + "economy": "1. Developed region: G7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Canada", + "formal_fr": null, + "gdp_md_est": 1300000, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Canada", + "gu_a3": "CAN", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "CA", + "iso_a3": "CAN", + "iso_n3": 124, + "labelrank": 2, + "lastcensus": 2011, + "level": 2, + "long_len": 6, + "mapcolor13": 2, + "mapcolor7": 6, + "mapcolor8": 6, + "mapcolor9": 2, + "name": "Canada", + "name_alt": null, + "name_len": 6, + "name_long": "Canada", + "name_sort": "Canada", + "note_adm0": null, + "note_brk": null, + "pop_est": 33487208, + "pop_year": -99, + "postal": "CA", + "region_un": "Americas", + "region_wb": "North America", + "scalerank": 1, + "sov_a3": "CAN", + "sovereignt": "Canada", + "su_a3": "CAN", + "su_dif": 0, + "subregion": "Northern America", + "subunit": "Canada", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 124, + "wb_a2": "CA", + "wb_a3": "CAN", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Switz.", + "abbrev_len": 6, + "adm0_a3": "CHE", + "adm0_a3_is": "CHE", + "adm0_a3_un": -99, + "adm0_a3_us": "CHE", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Switzerland", + "brk_a3": "CHE", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Switzerland", + "continent": "Europe", + "economy": "2. Developed region: nonG7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Swiss Confederation", + "formal_fr": null, + "gdp_md_est": 316700, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Switzerland", + "gu_a3": "CHE", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "CH", + "iso_a3": "CHE", + "iso_n3": 756, + "labelrank": 4, + "lastcensus": 2010, + "level": 2, + "long_len": 11, + "mapcolor13": 3, + "mapcolor7": 5, + "mapcolor8": 2, + "mapcolor9": 7, + "name": "Switzerland", + "name_alt": null, + "name_len": 11, + "name_long": "Switzerland", + "name_sort": "Switzerland", + "note_adm0": null, + "note_brk": null, + "pop_est": 7604467, + "pop_year": -99, + "postal": "CH", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "CHE", + "sovereignt": "Switzerland", + "su_a3": "CHE", + "su_dif": 0, + "subregion": "Western Europe", + "subunit": "Switzerland", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 756, + "wb_a2": "CH", + "wb_a3": "CHE", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Chile", + "abbrev_len": 5, + "adm0_a3": "CHL", + "adm0_a3_is": "CHL", + "adm0_a3_un": -99, + "adm0_a3_us": "CHL", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Chile", + "brk_a3": "CHL", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Chile", + "continent": "South America", + "economy": "5. Emerging region: G20", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Chile", + "formal_fr": null, + "gdp_md_est": 244500, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Chile", + "gu_a3": "CHL", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "CL", + "iso_a3": "CHL", + "iso_n3": 152, + "labelrank": 2, + "lastcensus": 2002, + "level": 2, + "long_len": 5, + "mapcolor13": 9, + "mapcolor7": 5, + "mapcolor8": 1, + "mapcolor9": 5, + "name": "Chile", + "name_alt": null, + "name_len": 5, + "name_long": "Chile", + "name_sort": "Chile", + "note_adm0": null, + "note_brk": null, + "pop_est": 16601707, + "pop_year": -99, + "postal": "CL", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "CHL", + "sovereignt": "Chile", + "su_a3": "CHL", + "su_dif": 0, + "subregion": "South America", + "subunit": "Chile", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 152, + "wb_a2": "CL", + "wb_a3": "CHL", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "China", + "abbrev_len": 5, + "adm0_a3": "CHN", + "adm0_a3_is": "CHN", + "adm0_a3_un": -99, + "adm0_a3_us": "CHN", + "adm0_a3_wb": -99, + "adm0_dif": 1, + "admin": "China", + "brk_a3": "CHN", + "brk_diff": 0, + "brk_group": null, + "brk_name": "China", + "continent": "Asia", + "economy": "3. Emerging region: BRIC", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "People's Republic of China", + "formal_fr": null, + "gdp_md_est": 7973000, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "China", + "gu_a3": "CHN", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "CN", + "iso_a3": "CHN", + "iso_n3": 156, + "labelrank": 2, + "lastcensus": 2010, + "level": 2, + "long_len": 5, + "mapcolor13": 3, + "mapcolor7": 4, + "mapcolor8": 4, + "mapcolor9": 4, + "name": "China", + "name_alt": null, + "name_len": 5, + "name_long": "China", + "name_sort": "China", + "note_adm0": null, + "note_brk": null, + "pop_est": 1338612970, + "pop_year": -99, + "postal": "CN", + "region_un": "Asia", + "region_wb": "East Asia & Pacific", + "scalerank": 1, + "sov_a3": "CH1", + "sovereignt": "China", + "su_a3": "CHN", + "su_dif": 0, + "subregion": "Eastern Asia", + "subunit": "China", + "tiny": -99, + "type": "Country", + "un_a3": 156, + "wb_a2": "CN", + "wb_a3": "CHN", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "I.C.", + "abbrev_len": 4, + "adm0_a3": "CIV", + "adm0_a3_is": "CIV", + "adm0_a3_un": -99, + "adm0_a3_us": "CIV", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Ivory Coast", + "brk_a3": "CIV", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Côte d'Ivoire", + "continent": "Africa", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Ivory Coast", + "formal_fr": "Republic of Cote D'Ivoire", + "gdp_md_est": 33850, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Ivory Coast", + "gu_a3": "CIV", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "CI", + "iso_a3": "CIV", + "iso_n3": 384, + "labelrank": 3, + "lastcensus": 1998, + "level": 2, + "long_len": 13, + "mapcolor13": 3, + "mapcolor7": 4, + "mapcolor8": 6, + "mapcolor9": 3, + "name": "Côte d'Ivoire", + "name_alt": null, + "name_len": 13, + "name_long": "Côte d'Ivoire", + "name_sort": "Côte d'Ivoire", + "note_adm0": null, + "note_brk": null, + "pop_est": 20617068, + "pop_year": -99, + "postal": "CI", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "CIV", + "sovereignt": "Ivory Coast", + "su_a3": "CIV", + "su_dif": 0, + "subregion": "Western Africa", + "subunit": "Ivory Coast", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 384, + "wb_a2": "CI", + "wb_a3": "CIV", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Cam.", + "abbrev_len": 4, + "adm0_a3": "CMR", + "adm0_a3_is": "CMR", + "adm0_a3_un": -99, + "adm0_a3_us": "CMR", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Cameroon", + "brk_a3": "CMR", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Cameroon", + "continent": "Africa", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Cameroon", + "formal_fr": null, + "gdp_md_est": 42750, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Cameroon", + "gu_a3": "CMR", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "CM", + "iso_a3": "CMR", + "iso_n3": 120, + "labelrank": 3, + "lastcensus": 2005, + "level": 2, + "long_len": 8, + "mapcolor13": 3, + "mapcolor7": 1, + "mapcolor8": 4, + "mapcolor9": 1, + "name": "Cameroon", + "name_alt": null, + "name_len": 8, + "name_long": "Cameroon", + "name_sort": "Cameroon", + "note_adm0": null, + "note_brk": null, + "pop_est": 18879301, + "pop_year": -99, + "postal": "CM", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "CMR", + "sovereignt": "Cameroon", + "su_a3": "CMR", + "su_dif": 0, + "subregion": "Middle Africa", + "subunit": "Cameroon", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 120, + "wb_a2": "CM", + "wb_a3": "CMR", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "D.R.C.", + "abbrev_len": 6, + "adm0_a3": "COD", + "adm0_a3_is": "COD", + "adm0_a3_un": -99, + "adm0_a3_us": "COD", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Democratic Republic of the Congo", + "brk_a3": "COD", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Democratic Republic of the Congo", + "continent": "Africa", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Democratic Republic of the Congo", + "formal_fr": null, + "gdp_md_est": 20640, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Democratic Republic of the Congo", + "gu_a3": "COD", + "homepart": 1, + "income_grp": "5. Low income", + "iso_a2": "CD", + "iso_a3": "COD", + "iso_n3": 180, + "labelrank": 2, + "lastcensus": 1984, + "level": 2, + "long_len": 32, + "mapcolor13": 7, + "mapcolor7": 4, + "mapcolor8": 4, + "mapcolor9": 4, + "name": "Dem. Rep. Congo", + "name_alt": null, + "name_len": 15, + "name_long": "Democratic Republic of the Congo", + "name_sort": "Congo, Dem. Rep.", + "note_adm0": null, + "note_brk": null, + "pop_est": 68692542, + "pop_year": -99, + "postal": "DRC", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "COD", + "sovereignt": "Democratic Republic of the Congo", + "su_a3": "COD", + "su_dif": 0, + "subregion": "Middle Africa", + "subunit": "Democratic Republic of the Congo", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 180, + "wb_a2": "ZR", + "wb_a3": "ZAR", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Rep. Congo", + "abbrev_len": 10, + "adm0_a3": "COG", + "adm0_a3_is": "COG", + "adm0_a3_un": -99, + "adm0_a3_us": "COG", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Republic of Congo", + "brk_a3": "COG", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Republic of Congo", + "continent": "Africa", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Congo", + "formal_fr": null, + "gdp_md_est": 15350, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Republic of Congo", + "gu_a3": "COG", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "CG", + "iso_a3": "COG", + "iso_n3": 178, + "labelrank": 4, + "lastcensus": 2007, + "level": 2, + "long_len": 17, + "mapcolor13": 10, + "mapcolor7": 2, + "mapcolor8": 1, + "mapcolor9": 3, + "name": "Congo", + "name_alt": null, + "name_len": 5, + "name_long": "Republic of Congo", + "name_sort": "Congo, Rep.", + "note_adm0": null, + "note_brk": null, + "pop_est": 4012809, + "pop_year": -99, + "postal": "CG", + "region_un": "Africa", + "region_wb": "Sub-Saharan Africa", + "scalerank": 1, + "sov_a3": "COG", + "sovereignt": "Republic of Congo", + "su_a3": "COG", + "su_dif": 0, + "subregion": "Middle Africa", + "subunit": "Republic of Congo", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 178, + "wb_a2": "CG", + "wb_a3": "COG", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Col.", + "abbrev_len": 4, + "adm0_a3": "COL", + "adm0_a3_is": "COL", + "adm0_a3_un": -99, + "adm0_a3_us": "COL", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Colombia", + "brk_a3": "COL", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Colombia", + "continent": "South America", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Colombia", + "formal_fr": null, + "gdp_md_est": 395400, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Colombia", + "gu_a3": "COL", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "CO", + "iso_a3": "COL", + "iso_n3": 170, + "labelrank": 2, + "lastcensus": 2006, + "level": 2, + "long_len": 8, + "mapcolor13": 1, + "mapcolor7": 2, + "mapcolor8": 1, + "mapcolor9": 3, + "name": "Colombia", + "name_alt": null, + "name_len": 8, + "name_long": "Colombia", + "name_sort": "Colombia", + "note_adm0": null, + "note_brk": null, + "pop_est": 45644023, + "pop_year": -99, + "postal": "CO", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "COL", + "sovereignt": "Colombia", + "su_a3": "COL", + "su_dif": 0, + "subregion": "South America", + "subunit": "Colombia", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 170, + "wb_a2": "CO", + "wb_a3": "COL", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "C.R.", + "abbrev_len": 4, + "adm0_a3": "CRI", + "adm0_a3_is": "CRI", + "adm0_a3_un": -99, + "adm0_a3_us": "CRI", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Costa Rica", + "brk_a3": "CRI", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Costa Rica", + "continent": "North America", + "economy": "5. Emerging region: G20", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Costa Rica", + "formal_fr": null, + "gdp_md_est": 48320, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Costa Rica", + "gu_a3": "CRI", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "CR", + "iso_a3": "CRI", + "iso_n3": 188, + "labelrank": 5, + "lastcensus": 2011, + "level": 2, + "long_len": 10, + "mapcolor13": 2, + "mapcolor7": 3, + "mapcolor8": 2, + "mapcolor9": 4, + "name": "Costa Rica", + "name_alt": null, + "name_len": 10, + "name_long": "Costa Rica", + "name_sort": "Costa Rica", + "note_adm0": null, + "note_brk": null, + "pop_est": 4253877, + "pop_year": -99, + "postal": "CR", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "CRI", + "sovereignt": "Costa Rica", + "su_a3": "CRI", + "su_dif": 0, + "subregion": "Central America", + "subunit": "Costa Rica", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 188, + "wb_a2": "CR", + "wb_a3": "CRI", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Cuba", + "abbrev_len": 4, + "adm0_a3": "CUB", + "adm0_a3_is": "CUB", + "adm0_a3_un": -99, + "adm0_a3_us": "CUB", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Cuba", + "brk_a3": "CUB", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Cuba", + "continent": "North America", + "economy": "5. Emerging region: G20", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Cuba", + "formal_fr": null, + "gdp_md_est": 108200, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Cuba", + "gu_a3": "CUB", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "CU", + "iso_a3": "CUB", + "iso_n3": 192, + "labelrank": 3, + "lastcensus": 2002, + "level": 2, + "long_len": 4, + "mapcolor13": 4, + "mapcolor7": 3, + "mapcolor8": 5, + "mapcolor9": 3, + "name": "Cuba", + "name_alt": null, + "name_len": 4, + "name_long": "Cuba", + "name_sort": "Cuba", + "note_adm0": null, + "note_brk": null, + "pop_est": 11451652, + "pop_year": -99, + "postal": "CU", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "CUB", + "sovereignt": "Cuba", + "su_a3": "CUB", + "su_dif": 0, + "subregion": "Caribbean", + "subunit": "Cuba", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 192, + "wb_a2": "CU", + "wb_a3": "CUB", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Cyp.", + "abbrev_len": 4, + "adm0_a3": "CYP", + "adm0_a3_is": "CYP", + "adm0_a3_un": -99, + "adm0_a3_us": "CYP", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Cyprus", + "brk_a3": "CYP", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Cyprus", + "continent": "Asia", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Cyprus", + "formal_fr": null, + "gdp_md_est": 22700, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Cyprus", + "gu_a3": "CYP", + "homepart": 1, + "income_grp": "2. High income: nonOECD", + "iso_a2": "CY", + "iso_a3": "CYP", + "iso_n3": 196, + "labelrank": 5, + "lastcensus": 2001, + "level": 2, + "long_len": 6, + "mapcolor13": 7, + "mapcolor7": 1, + "mapcolor8": 2, + "mapcolor9": 3, + "name": "Cyprus", + "name_alt": null, + "name_len": 6, + "name_long": "Cyprus", + "name_sort": "Cyprus", + "note_adm0": null, + "note_brk": null, + "pop_est": 531640, + "pop_year": -99, + "postal": "CY", + "region_un": "Asia", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "CYP", + "sovereignt": "Cyprus", + "su_a3": "CYP", + "su_dif": 0, + "subregion": "Western Asia", + "subunit": "Cyprus", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 196, + "wb_a2": "CY", + "wb_a3": "CYP", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Cz. Rep.", + "abbrev_len": 8, + "adm0_a3": "CZE", + "adm0_a3_is": "CZE", + "adm0_a3_un": -99, + "adm0_a3_us": "CZE", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Czech Republic", + "brk_a3": "CZE", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Czech Rep.", + "continent": "Europe", + "economy": "2. Developed region: nonG7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Czech Republic", + "formal_fr": null, + "gdp_md_est": 265200, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Czech Republic", + "gu_a3": "CZE", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "CZ", + "iso_a3": "CZE", + "iso_n3": 203, + "labelrank": 5, + "lastcensus": 2011, + "level": 2, + "long_len": 14, + "mapcolor13": 6, + "mapcolor7": 1, + "mapcolor8": 1, + "mapcolor9": 2, + "name": "Czech Rep.", + "name_alt": null, + "name_len": 10, + "name_long": "Czech Republic", + "name_sort": "Czech Republic", + "note_adm0": null, + "note_brk": null, + "pop_est": 10211904, + "pop_year": -99, + "postal": "CZ", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "CZE", + "sovereignt": "Czech Republic", + "su_a3": "CZE", + "su_dif": 0, + "subregion": "Eastern Europe", + "subunit": "Czech Republic", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 203, + "wb_a2": "CZ", + "wb_a3": "CZE", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Ger.", + "abbrev_len": 4, + "adm0_a3": "DEU", + "adm0_a3_is": "DEU", + "adm0_a3_un": -99, + "adm0_a3_us": "DEU", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Germany", + "brk_a3": "DEU", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Germany", + "continent": "Europe", + "economy": "1. Developed region: G7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Federal Republic of Germany", + "formal_fr": null, + "gdp_md_est": 2918000, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Germany", + "gu_a3": "DEU", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "DE", + "iso_a3": "DEU", + "iso_n3": 276, + "labelrank": 2, + "lastcensus": 2011, + "level": 2, + "long_len": 7, + "mapcolor13": 1, + "mapcolor7": 2, + "mapcolor8": 5, + "mapcolor9": 5, + "name": "Germany", + "name_alt": null, + "name_len": 7, + "name_long": "Germany", + "name_sort": "Germany", + "note_adm0": null, + "note_brk": null, + "pop_est": 82329758, + "pop_year": -99, + "postal": "D", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "DEU", + "sovereignt": "Germany", + "su_a3": "DEU", + "su_dif": 0, + "subregion": "Western Europe", + "subunit": "Germany", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 276, + "wb_a2": "DE", + "wb_a3": "DEU", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Dji.", + "abbrev_len": 4, + "adm0_a3": "DJI", + "adm0_a3_is": "DJI", + "adm0_a3_un": -99, + "adm0_a3_us": "DJI", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Djibouti", + "brk_a3": "DJI", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Djibouti", + "continent": "Africa", + "economy": "7. Least developed region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Djibouti", + "formal_fr": null, + "gdp_md_est": 1885, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Djibouti", + "gu_a3": "DJI", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "DJ", + "iso_a3": "DJI", + "iso_n3": 262, + "labelrank": 5, + "lastcensus": 2009, + "level": 2, + "long_len": 8, + "mapcolor13": 8, + "mapcolor7": 1, + "mapcolor8": 2, + "mapcolor9": 4, + "name": "Djibouti", + "name_alt": null, + "name_len": 8, + "name_long": "Djibouti", + "name_sort": "Djibouti", + "note_adm0": null, + "note_brk": null, + "pop_est": 516055, + "pop_year": -99, + "postal": "DJ", + "region_un": "Africa", + "region_wb": "Middle East & North Africa", + "scalerank": 1, + "sov_a3": "DJI", + "sovereignt": "Djibouti", + "su_a3": "DJI", + "su_dif": 0, + "subregion": "Eastern Africa", + "subunit": "Djibouti", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 262, + "wb_a2": "DJ", + "wb_a3": "DJI", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Den.", + "abbrev_len": 4, + "adm0_a3": "DNK", + "adm0_a3_is": "DNK", + "adm0_a3_un": -99, + "adm0_a3_us": "DNK", + "adm0_a3_wb": -99, + "adm0_dif": 1, + "admin": "Denmark", + "brk_a3": "DNK", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Denmark", + "continent": "Europe", + "economy": "2. Developed region: nonG7", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Kingdom of Denmark", + "formal_fr": null, + "gdp_md_est": 203600, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Denmark", + "gu_a3": "DNK", + "homepart": 1, + "income_grp": "1. High income: OECD", + "iso_a2": "DK", + "iso_a3": "DNK", + "iso_n3": 208, + "labelrank": 4, + "lastcensus": 2011, + "level": 2, + "long_len": 7, + "mapcolor13": 12, + "mapcolor7": 4, + "mapcolor8": 1, + "mapcolor9": 3, + "name": "Denmark", + "name_alt": null, + "name_len": 7, + "name_long": "Denmark", + "name_sort": "Denmark", + "note_adm0": null, + "note_brk": null, + "pop_est": 5500510, + "pop_year": -99, + "postal": "DK", + "region_un": "Europe", + "region_wb": "Europe & Central Asia", + "scalerank": 1, + "sov_a3": "DN1", + "sovereignt": "Denmark", + "su_a3": "DNK", + "su_dif": 0, + "subregion": "Northern Europe", + "subunit": "Denmark", + "tiny": -99, + "type": "Country", + "un_a3": 208, + "wb_a2": "DK", + "wb_a3": "DNK", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Dom. Rep.", + "abbrev_len": 9, + "adm0_a3": "DOM", + "adm0_a3_is": "DOM", + "adm0_a3_un": -99, + "adm0_a3_us": "DOM", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Dominican Republic", + "brk_a3": "DOM", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Dominican Rep.", + "continent": "North America", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Dominican Republic", + "formal_fr": null, + "gdp_md_est": 78000, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Dominican Republic", + "gu_a3": "DOM", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "DO", + "iso_a3": "DOM", + "iso_n3": 214, + "labelrank": 5, + "lastcensus": 2010, + "level": 2, + "long_len": 18, + "mapcolor13": 7, + "mapcolor7": 5, + "mapcolor8": 2, + "mapcolor9": 5, + "name": "Dominican Rep.", + "name_alt": null, + "name_len": 14, + "name_long": "Dominican Republic", + "name_sort": "Dominican Republic", + "note_adm0": null, + "note_brk": null, + "pop_est": 9650054, + "pop_year": -99, + "postal": "DO", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "DOM", + "sovereignt": "Dominican Republic", + "su_a3": "DOM", + "su_dif": 0, + "subregion": "Caribbean", + "subunit": "Dominican Republic", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 214, + "wb_a2": "DO", + "wb_a3": "DOM", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Alg.", + "abbrev_len": 4, + "adm0_a3": "DZA", + "adm0_a3_is": "DZA", + "adm0_a3_un": -99, + "adm0_a3_us": "DZA", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Algeria", + "brk_a3": "DZA", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Algeria", + "continent": "Africa", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "People's Democratic Republic of Algeria", + "formal_fr": null, + "gdp_md_est": 232900, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Algeria", + "gu_a3": "DZA", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "DZ", + "iso_a3": "DZA", + "iso_n3": 12, + "labelrank": 3, + "lastcensus": 2008, + "level": 2, + "long_len": 7, + "mapcolor13": 3, + "mapcolor7": 5, + "mapcolor8": 1, + "mapcolor9": 6, + "name": "Algeria", + "name_alt": null, + "name_len": 7, + "name_long": "Algeria", + "name_sort": "Algeria", + "note_adm0": null, + "note_brk": null, + "pop_est": 34178188, + "pop_year": -99, + "postal": "DZ", + "region_un": "Africa", + "region_wb": "Middle East & North Africa", + "scalerank": 1, + "sov_a3": "DZA", + "sovereignt": "Algeria", + "su_a3": "DZA", + "su_dif": 0, + "subregion": "Northern Africa", + "subunit": "Algeria", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 12, + "wb_a2": "DZ", + "wb_a3": "DZA", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Ecu.", + "abbrev_len": 4, + "adm0_a3": "ECU", + "adm0_a3_is": "ECU", + "adm0_a3_un": -99, + "adm0_a3_us": "ECU", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Ecuador", + "brk_a3": "ECU", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Ecuador", + "continent": "South America", + "economy": "6. Developing region", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Republic of Ecuador", + "formal_fr": null, + "gdp_md_est": 107700, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Ecuador", + "gu_a3": "ECU", + "homepart": 1, + "income_grp": "3. Upper middle income", + "iso_a2": "EC", + "iso_a3": "ECU", + "iso_n3": 218, + "labelrank": 3, + "lastcensus": 2010, + "level": 2, + "long_len": 7, + "mapcolor13": 12, + "mapcolor7": 1, + "mapcolor8": 5, + "mapcolor9": 2, + "name": "Ecuador", + "name_alt": null, + "name_len": 7, + "name_long": "Ecuador", + "name_sort": "Ecuador", + "note_adm0": null, + "note_brk": null, + "pop_est": 14573101, + "pop_year": -99, + "postal": "EC", + "region_un": "Americas", + "region_wb": "Latin America & Caribbean", + "scalerank": 1, + "sov_a3": "ECU", + "sovereignt": "Ecuador", + "su_a3": "ECU", + "su_dif": 0, + "subregion": "South America", + "subunit": "Ecuador", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 218, + "wb_a2": "EC", + "wb_a3": "ECU", + "wikipedia": -99, + "woe_id": -99 + }, + { + "abbrev": "Egypt", + "abbrev_len": 5, + "adm0_a3": "EGY", + "adm0_a3_is": "EGY", + "adm0_a3_un": -99, + "adm0_a3_us": "EGY", + "adm0_a3_wb": -99, + "adm0_dif": 0, + "admin": "Egypt", + "brk_a3": "EGY", + "brk_diff": 0, + "brk_group": null, + "brk_name": "Egypt", + "continent": "Africa", + "economy": "5. Emerging region: G20", + "featurecla": "Admin-0 country", + "fips_10": null, + "formal_en": "Arab Republic of Egypt", + "formal_fr": null, + "gdp_md_est": 443700, + "gdp_year": -99, + "geou_dif": 0, + "geounit": "Egypt", + "gu_a3": "EGY", + "homepart": 1, + "income_grp": "4. Lower middle income", + "iso_a2": "EG", + "iso_a3": "EGY", + "iso_n3": 818, + "labelrank": 2, + "lastcensus": 2006, + "level": 2, + "long_len": 5, + "mapcolor13": 2, + "mapcolor7": 4, + "mapcolor8": 6, + "mapcolor9": 7, + "name": "Egypt", + "name_alt": null, + "name_len": 5, + "name_long": "Egypt", + "name_sort": "Egypt, Arab Rep.", + "note_adm0": null, + "note_brk": null, + "pop_est": 83082869, + "pop_year": -99, + "postal": "EG", + "region_un": "Africa", + "region_wb": "Middle East & North Africa", + "scalerank": 1, + "sov_a3": "EGY", + "sovereignt": "Egypt", + "su_a3": "EGY", + "su_dif": 0, + "subregion": "Northern Africa", + "subunit": "Egypt", + "tiny": -99, + "type": "Sovereign country", + "un_a3": 818, + "wb_a2": "EG", + "wb_a3": "EGY", + "wikipedia": -99, + "woe_id": -99 + } + ], + "schema": { + "fields": [ + { + "name": "scalerank", + "type": "integer" + }, + { + "name": "featurecla", + "type": "string" + }, + { + "name": "labelrank", + "type": "integer" + }, + { + "name": "sovereignt", + "type": "string" + }, + { + "name": "sov_a3", + "type": "string" + }, + { + "name": "adm0_dif", + "type": "integer" + }, + { + "name": "level", + "type": "integer" + }, + { + "name": "type", + "type": "string" + }, + { + "name": "admin", + "type": "string" + }, + { + "name": "adm0_a3", + "type": "string" + }, + { + "name": "geou_dif", + "type": "integer" + }, + { + "name": "geounit", + "type": "string" + }, + { + "name": "gu_a3", + "type": "string" + }, + { + "name": "su_dif", + "type": "integer" + }, + { + "name": "subunit", + "type": "string" + }, + { + "name": "su_a3", + "type": "string" + }, + { + "name": "brk_diff", + "type": "integer" + }, + { + "name": "name", + "type": "string" + }, + { + "name": "name_long", + "type": "string" + }, + { + "name": "brk_a3", + "type": "string" + }, + { + "name": "brk_name", + "type": "string" + }, + { + "name": "brk_group", + "type": "string" + }, + { + "name": "abbrev", + "type": "string" + }, + { + "name": "postal", + "type": "string" + }, + { + "name": "formal_en", + "type": "string" + }, + { + "name": "formal_fr", + "type": "string" + }, + { + "name": "note_adm0", + "type": "string" + }, + { + "name": "note_brk", + "type": "string" + }, + { + "name": "name_sort", + "type": "string" + }, + { + "name": "name_alt", + "type": "string" + }, + { + "name": "mapcolor7", + "type": "integer" + }, + { + "name": "mapcolor8", + "type": "integer" + }, + { + "name": "mapcolor9", + "type": "integer" + }, + { + "name": "mapcolor13", + "type": "integer" + }, + { + "name": "pop_est", + "type": "integer" + }, + { + "name": "gdp_md_est", + "type": "number" + }, + { + "name": "pop_year", + "type": "integer" + }, + { + "name": "lastcensus", + "type": "integer" + }, + { + "name": "gdp_year", + "type": "integer" + }, + { + "name": "economy", + "type": "string" + }, + { + "name": "income_grp", + "type": "string" + }, + { + "name": "wikipedia", + "type": "integer" + }, + { + "name": "fips_10", + "type": "string" + }, + { + "name": "iso_a2", + "type": "string" + }, + { + "name": "iso_a3", + "type": "string" + }, + { + "name": "iso_n3", + "type": "integer" + }, + { + "name": "un_a3", + "type": "integer" + }, + { + "name": "wb_a2", + "type": "string" + }, + { + "name": "wb_a3", + "type": "string" + }, + { + "name": "woe_id", + "type": "integer" + }, + { + "name": "adm0_a3_is", + "type": "string" + }, + { + "name": "adm0_a3_us", + "type": "string" + }, + { + "name": "adm0_a3_un", + "type": "integer" + }, + { + "name": "adm0_a3_wb", + "type": "integer" + }, + { + "name": "continent", + "type": "string" + }, + { + "name": "region_un", + "type": "string" + }, + { + "name": "subregion", + "type": "string" + }, + { + "name": "region_wb", + "type": "string" + }, + { + "name": "name_len", + "type": "integer" + }, + { + "name": "long_len", + "type": "integer" + }, + { + "name": "abbrev_len", + "type": "integer" + }, + { + "name": "tiny", + "type": "integer" + }, + { + "name": "homepart", + "type": "integer" + } + ] + } + }, + "text/html": [ + "
scalerankfeatureclalabelranksovereigntsov_a3adm0_difleveltypeadminadm0_a3geou_difgeounitgu_a3su_difsubunitsu_a3brk_diffnamename_longbrk_a3brk_namebrk_groupabbrevpostalformal_enformal_frnote_adm0note_brkname_sortname_altmapcolor7mapcolor8mapcolor9mapcolor13pop_estgdp_md_estpop_yearlastcensusgdp_yeareconomyincome_grpwikipediafips_10iso_a2iso_a3iso_n3un_a3wb_a2wb_a3woe_idadm0_a3_isadm0_a3_usadm0_a3_unadm0_a3_wbcontinentregion_unsubregionregion_wbname_lenlong_lenabbrev_lentinyhomepart
1Admin-0 country6KosovoKOS02Sovereign countryKosovoKOS0KosovoKOS0KosovoKOS1KosovoKosovoB57KosovonullKos.KORepublic of KosovonullnullSelf admin.; Claimed by SerbiaKosovonull2231118048385352-991981-996. Developing region4. Lower middle income-99null-99-99-99-99KVKSV-99SRBKOS-99-99EuropeEuropeSouthern EuropeEurope & Central Asia664-991
1Admin-0 country5SomalilandSOL02IndeterminateSomalilandSOL0SomalilandSOL0SomalilandSOL1SomalilandSomalilandB30SomalilandnullSolnd.SLRepublic of SomalilandnullSelf admin.Self admin.; Claimed by SomaliaSomalilandnull3652350000012250-99-99-996. Developing region4. Lower middle income-99null-99-99-99-99-99-99-99SOMSOM-99-99AfricaAfricaEastern AfricaSub-Saharan Africa10106-991
1Admin-0 country6Northern CyprusCYN02Sovereign countryNorthern CyprusCYN0Northern CyprusCYN0Northern CyprusCYN1N. CyprusNorthern CyprusB20N. CyprusnullN. Cy.CNTurkish Republic of Northern CyprusnullSelf admin.Self admin.; Claimed by CyprusCyprus, Northernnull31482651003600-99-99-996. Developing region3. Upper middle income-99null-99-99-99-99-99-99-99CYPCYP-99-99AsiaAsiaWestern AsiaEurope & Central Asia9156-991
1Admin-0 country3AfghanistanAFG02Sovereign countryAfghanistanAFG0AfghanistanAFG0AfghanistanAFG0AfghanistanAfghanistanAFGAfghanistannullAfg.AFIslamic State of AfghanistannullnullnullAfghanistannull56872840000022270-991979-997. Least developed region5. Low income-99nullAFAFG44AFAFG-99AFGAFG-99-99AsiaAsiaSouthern AsiaSouth Asia11114-991
1Admin-0 country3AngolaAGO02Sovereign countryAngolaAGO0AngolaAGO0AngolaAGO0AngolaAngolaAGOAngolanullAng.AOPeople's Republic of AngolanullnullnullAngolanull326112799293110300-991970-997. Least developed region3. Upper middle income-99nullAOAGO2424AOAGO-99AGOAGO-99-99AfricaAfricaMiddle AfricaSub-Saharan Africa664-991
1Admin-0 country6AlbaniaALB02Sovereign countryAlbaniaALB0AlbaniaALB0AlbaniaALB0AlbaniaAlbaniaALBAlbanianullAlb.ALRepublic of AlbanianullnullnullAlbanianull1416363945321810-992001-996. Developing region4. Lower middle income-99nullALALB88ALALB-99ALBALB-99-99EuropeEuropeSouthern EuropeEurope & Central Asia774-991
1Admin-0 country4United Arab EmiratesARE02Sovereign countryUnited Arab EmiratesARE0United Arab EmiratesARE0United Arab EmiratesARE0United Arab EmiratesUnited Arab EmiratesAREUnited Arab EmiratesnullU.A.E.AEUnited Arab EmiratesnullnullnullUnited Arab Emiratesnull21334798491184300-992010-996. Developing region2. High income: nonOECD-99nullAEARE784784AEARE-99AREARE-99-99AsiaAsiaWestern AsiaMiddle East & North Africa20206-991
1Admin-0 country2ArgentinaARG02Sovereign countryArgentinaARG0ArgentinaARG0ArgentinaARG0ArgentinaArgentinaARGArgentinanullArg.ARArgentine RepublicnullnullnullArgentinanull3131340913584573900-992010-995. Emerging region: G203. Upper middle income-99nullARARG3232ARARG-99ARGARG-99-99South AmericaAmericasSouth AmericaLatin America & Caribbean994-991
1Admin-0 country6ArmeniaARM02Sovereign countryArmeniaARM0ArmeniaARM0ArmeniaARM0ArmeniaArmeniaARMArmenianullArm.ARMRepublic of ArmenianullnullnullArmenianull31210296700418770-992001-996. Developing region4. Lower middle income-99nullAMARM5151AMARM-99ARMARM-99-99AsiaAsiaWestern AsiaEurope & Central Asia774-991
1Admin-0 country4AntarcticaATA02IndeterminateAntarcticaATA0AntarcticaATA0AntarcticaATA0AntarcticaAntarcticaATAAntarcticanullAnt.AQnullnullnullMultiple claims held in abeyanceAntarcticanull451-993802760.4-99-99-996. Developing region2. High income: nonOECD-99nullAQATA10-99-99-99-99ATAATA-99-99AntarcticaAntarcticaAntarcticaAntarctica10104-991
" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pl from \"npm:nodejs-polars\";\n", + "\n", + "let response = await fetch(\n", + " \"https://cdn.jsdelivr.net/npm/world-atlas@1/world/110m.tsv\",\n", + ");\n", + "let data = await response.text();\n", + "let df = pl.readCSV(data, { sep: \"\\t\" });\n", + "\n", + "df" + ] } ], "metadata": { diff --git a/cli/tests/unit/jupyter_test.ts b/cli/tests/unit/jupyter_test.ts index 40eaf4623d..f1529adeb7 100644 --- a/cli/tests/unit/jupyter_test.ts +++ b/cli/tests/unit/jupyter_test.ts @@ -1,5 +1,9 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -import { assertThrows } from "./test_util.ts"; + +import { assertEquals, assertThrows } from "./test_util.ts"; + +// @ts-expect-error TypeScript (as of 3.7) does not support indexing namespaces by symbol +const format = Deno[Deno.internal].jupyter.formatInner; Deno.test("Deno.jupyter is not available", () => { assertThrows( @@ -7,3 +11,69 @@ Deno.test("Deno.jupyter is not available", () => { "Deno.jupyter is only available in `deno jupyter` subcommand.", ); }); + +export async function assertFormattedAs(obj: unknown, result: object) { + const formatted = await format(obj); + assertEquals(formatted, result); +} + +Deno.test("display(canvas) creates a PNG", async () => { + // Let's make a fake Canvas with a fake Data URL + class FakeCanvas { + toDataURL() { + return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAAVSURBVAiZY/zPwPCfAQ0woQtQQRAAzqkCCB/D3o0AAAAASUVORK5CYII="; + } + } + const canvas = new FakeCanvas(); + + await assertFormattedAs(canvas, { + "image/png": + "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAAVSURBVAiZY/zPwPCfAQ0woQtQQRAAzqkCCB/D3o0AAAAASUVORK5CYII=", + }); +}); + +Deno.test( + "class with a Symbol.for('Jupyter.display') function gets displayed", + async () => { + class Example { + x: number; + + constructor(x: number) { + this.x = x; + } + + [Symbol.for("Jupyter.display")]() { + return { "application/json": { x: this.x } }; + } + } + + const example = new Example(5); + + // Now to check on the broadcast call being made + await assertFormattedAs(example, { "application/json": { x: 5 } }); + }, +); + +Deno.test( + "class with an async Symbol.for('Jupyter.display') function gets displayed", + async () => { + class Example { + x: number; + + constructor(x: number) { + this.x = x; + } + + async [Symbol.for("Jupyter.display")]() { + await new Promise((resolve) => setTimeout(resolve, 0)); + + return { "application/json": { x: this.x } }; + } + } + + const example = new Example(3); + + // Now to check on the broadcast call being made + await assertFormattedAs(example, { "application/json": { x: 3 } }); + }, +); diff --git a/cli/tools/jupyter/server.rs b/cli/tools/jupyter/server.rs index 2c7bea9d26..6175a33e9f 100644 --- a/cli/tools/jupyter/server.rs +++ b/cli/tools/jupyter/server.rs @@ -388,21 +388,9 @@ impl JupyterServer { } = evaluate_response.value; if exception_details.is_none() { - let output = - get_jupyter_display_or_eval_value(&mut self.repl_session, &result) - .await?; - // Don't bother sending `execute_result` reply if the MIME bundle is empty - if !output.is_empty() { - msg - .new_message("execute_result") - .with_content(json!({ - "execution_count": self.execution_count, - "data": output, - "metadata": {}, - })) - .send(&mut *self.iopub_socket.lock().await) - .await?; - } + publish_result(&mut self.repl_session, &result, self.execution_count) + .await?; + msg .new_reply() .with_content(json!({ @@ -543,32 +531,33 @@ fn kernel_info() -> serde_json::Value { }) } -async fn get_jupyter_display( +async fn publish_result( session: &mut repl::ReplSession, evaluate_result: &cdp::RemoteObject, + execution_count: usize, ) -> Result>, AnyError> { + let arg0 = cdp::CallArgument { + value: Some(serde_json::Value::Number(execution_count.into())), + unserializable_value: None, + object_id: None, + }; + + let arg1 = cdp::CallArgument::from(evaluate_result); + let response = session .post_message_with_event_loop( "Runtime.callFunctionOn", Some(json!({ - "functionDeclaration": r#"async function (object) { - if (typeof object[Symbol.for("Jupyter.display")] !== "function") { - return null; - } - - try { - const representation = await object[Symbol.for("Jupyter.display")](); - return JSON.stringify(representation); - } catch { - return null; - } + "functionDeclaration": r#"async function (execution_count, result) { + await Deno[Deno.internal].jupyter.broadcastResult(execution_count, result); }"#, - "arguments": [cdp::CallArgument::from(evaluate_result)], + "arguments": [arg0, arg1], "executionContextId": session.context_id, "awaitPromise": true, })), ) .await?; + let response: cdp::CallFunctionOnResponse = serde_json::from_value(response)?; if let Some(exception_details) = &response.exception_details { @@ -578,75 +567,9 @@ async fn get_jupyter_display( return Ok(None); } - match response.result.value { - Some(serde_json::Value::String(json_str)) => { - let Ok(data) = - serde_json::from_str::>(&json_str) - else { - eprintln!("Unexpected response from Jupyter.display: {json_str}"); - return Ok(None); - }; - - if !data.is_empty() { - return Ok(Some(data)); - } - } - Some(serde_json::Value::Null) => { - // Object did not have the Jupyter display spec - return Ok(None); - } - _ => { - eprintln!( - "Unexpected response from Jupyter.display: {:?}", - response.result - ) - } - } - Ok(None) } -async fn get_jupyter_display_or_eval_value( - session: &mut repl::ReplSession, - evaluate_result: &cdp::RemoteObject, -) -> Result, AnyError> { - // Printing "undefined" generates a lot of noise, so let's skip - // these. - if evaluate_result.kind == "undefined" { - return Ok(HashMap::default()); - } - - // If the response is a primitive value we don't need to try and format - // Jupyter response. - if evaluate_result.object_id.is_some() { - if let Some(data) = get_jupyter_display(session, evaluate_result).await? { - return Ok(data); - } - } - - let response = session - .call_function_on_args( - format!( - r#"function (object) {{ - try {{ - return {0}.inspectArgs(["%o", object], {{ colors: !{0}.noColor }}); - }} catch (err) {{ - return {0}.inspectArgs(["%o", err]); - }} - }}"#, - *repl::REPL_INTERNALS_NAME - ), - &[evaluate_result.clone()], - ) - .await?; - let mut data = HashMap::default(); - if let Some(value) = response.result.value { - data.insert("text/plain".to_string(), value); - } - - Ok(data) -} - // TODO(bartlomieju): dedup with repl::editor fn get_expr_from_line_at_pos(line: &str, cursor_pos: usize) -> &str { let start = line[..cursor_pos].rfind(is_word_boundary).unwrap_or(0); diff --git a/cli/tsc/dts/lib.deno.unstable.d.ts b/cli/tsc/dts/lib.deno.unstable.d.ts index 26bb78757f..76e8ef49bc 100644 --- a/cli/tsc/dts/lib.deno.unstable.d.ts +++ b/cli/tsc/dts/lib.deno.unstable.d.ts @@ -2076,6 +2076,130 @@ declare namespace Deno { * * @category Jupyter */ export namespace jupyter { + export interface DisplayOptions { + raw?: boolean; + update?: boolean; + display_id?: string; + } + + type VegaObject = { + $schema: string; + [key: string]: unknown; + }; + + /** + * A collection of supported media types and data for Jupyter frontends. + */ + export type MediaBundle = { + "text/plain"?: string; + "text/html"?: string; + "image/svg+xml"?: string; + "text/markdown"?: string; + "application/javascript"?: string; + + // Images (per Jupyter spec) must be base64 encoded. We could _allow_ + // accepting Uint8Array or ArrayBuffer within `display` calls, however we still + // must encode them for jupyter. + "image/png"?: string; // WISH: Uint8Array | ArrayBuffer + "image/jpeg"?: string; // WISH: Uint8Array | ArrayBuffer + "image/gif"?: string; // WISH: Uint8Array | ArrayBuffer + "application/pdf"?: string; // WISH: Uint8Array | ArrayBuffer + + // NOTE: all JSON types must be objects at the top level (no arrays, strings, or other primitives) + "application/json"?: object; + "application/geo+json"?: object; + "application/vdom.v1+json"?: object; + "application/vnd.plotly.v1+json"?: object; + "application/vnd.vega.v5+json"?: VegaObject; + "application/vnd.vegalite.v4+json"?: VegaObject; + "application/vnd.vegalite.v5+json"?: VegaObject; + + // Must support a catch all for custom media types / mimetypes + [key: string]: string | object | undefined; + }; + + export const $display: unique symbol; + + export type Displayable = { + [$display]: () => MediaBundle | Promise; + }; + + /** + * Display function for Jupyter Deno Kernel. + * Mimics the behavior of IPython's `display(obj, raw=True)` function to allow + * asynchronous displaying of objects in Jupyter. + * + * @param obj - The object to be displayed + * @param options - Display options with a default { raw: true } + */ + export function display(obj: unknown, options?: DisplayOptions): void; + + /** + * Show Markdown in Jupyter frontends with a tagged template function. + * + * Takes a template string and returns a displayable object for Jupyter frontends. + * + * @example + * Create a Markdown view. + * + * ```typescript + * const { md } = Deno.jupyter; + * md`# Notebooks in TypeScript via Deno ![Deno logo](https://github.com/denoland.png?size=32) + * + * * TypeScript ${Deno.version.typescript} + * * V8 ${Deno.version.v8} + * * Deno ${Deno.version.deno} + * + * Interactive compute with Jupyter _built into Deno_! + * ` + * ``` + */ + export function md( + strings: TemplateStringsArray, + ...values: unknown[] + ): Displayable; + + /** + * Show HTML in Jupyter frontends with a tagged template function. + * + * Takes a template string and returns a displayable object for Jupyter frontends. + * + * @example + * Create an HTML view. + * ```typescript + * const { html } = Deno.jupyter; + * html`

Hello, world!

` + * ``` + */ + export function html( + strings: TemplateStringsArray, + ...values: unknown[] + ): Displayable; + + /** + * SVG Tagged Template Function. + * + * Takes a template string and returns a displayable object for Jupyter frontends. + * + * Example usage: + * + * svg` + * + * ` + */ + export function svg( + strings: TemplateStringsArray, + ...values: unknown[] + ): Displayable; + + /** + * Format an object for displaying in Deno + * + * @param obj - The object to be displayed + * @returns MediaBundle + */ + export function format(obj: unknown): MediaBundle; + /** * Broadcast a message on IO pub channel. *