From 81f3ec385f837ddbc04e5a50e19c7b372c84e0fe Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 4 Oct 2021 00:19:22 +0200 Subject: [PATCH 01/26] Version bump --- Models/Constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Models/Constants.ts b/Models/Constants.ts index 88348d1c4..0daf78e2e 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.10.1-rc3"; + public static vNumber = "0.11.0-alpha"; public static ImgurApiKey = '7070e7167f0a25a' public static readonly mapillary_client_token_v3 = 'TXhLaWthQ1d4RUg0czVxaTVoRjFJZzowNDczNjUzNmIyNTQyYzI2' public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85" From 21fd148f384b0b5517c88f417da04b91c3eec1f7 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 4 Oct 2021 03:12:42 +0200 Subject: [PATCH 02/26] Add propagation of metadata in changedescriptions, aggregate metadata in changeset tags --- Logic/Osm/Actions/ChangeDescription.ts | 18 ++ Logic/Osm/Actions/ChangeTagAction.ts | 13 +- Logic/Osm/Actions/CreateNewNodeAction.ts | 21 +- Logic/Osm/Actions/DeleteAction.ts | 253 ++++---------------- Logic/Osm/Actions/RelationSplitHandler.ts | 16 +- Logic/Osm/Actions/SplitAction.ts | 19 +- Logic/Osm/Changes.ts | 109 ++++++--- Logic/Osm/ChangesetHandler.ts | 226 ++++++++++------- Logic/Osm/OsmConnection.ts | 7 - Logic/Osm/OsmObject.ts | 3 +- Models/Constants.ts | 2 +- Models/ThemeConfig/Json/LayoutConfigJson.ts | 5 +- Models/ThemeConfig/LayoutConfig.ts | 2 - UI/BigComponents/ImportButton.ts | 5 +- UI/BigComponents/SimpleAddUI.ts | 5 +- UI/Popup/DeleteWizard.ts | 227 +++++++++++++++--- UI/Popup/SplitRoadWizard.ts | 4 +- UI/Popup/TagRenderingQuestion.ts | 5 +- Utils.ts | 8 + 19 files changed, 545 insertions(+), 403 deletions(-) diff --git a/Logic/Osm/Actions/ChangeDescription.ts b/Logic/Osm/Actions/ChangeDescription.ts index 1787d1b1b..42b018cfe 100644 --- a/Logic/Osm/Actions/ChangeDescription.ts +++ b/Logic/Osm/Actions/ChangeDescription.ts @@ -5,6 +5,24 @@ import {OsmNode, OsmRelation, OsmWay} from "../OsmObject"; */ export interface ChangeDescription { + /** + * Metadata to be included in the changeset + */ + meta: { + /* + * The theme with which this changeset was made + */ + theme: string, + /** + * The type of the change + */ + changeType: "answer" | "create" | "split" | "delete" | string + /** + * THe motivation for the change, e.g. 'deleted because does not exist anymore' + */ + specialMotivation?: string + }, + /** * Identifier of the object */ diff --git a/Logic/Osm/Actions/ChangeTagAction.ts b/Logic/Osm/Actions/ChangeTagAction.ts index 784f4d4dc..fd55953d1 100644 --- a/Logic/Osm/Actions/ChangeTagAction.ts +++ b/Logic/Osm/Actions/ChangeTagAction.ts @@ -7,12 +7,17 @@ export default class ChangeTagAction extends OsmChangeAction { private readonly _elementId: string; private readonly _tagsFilter: TagsFilter; private readonly _currentTags: any; + private readonly _meta: {theme: string, changeType: string}; - constructor(elementId: string, tagsFilter: TagsFilter, currentTags: any) { + constructor(elementId: string, tagsFilter: TagsFilter, currentTags: any, meta: { + theme: string, + changeType: "answer" | "soft-delete" + }) { super(); this._elementId = elementId; this._tagsFilter = tagsFilter; this._currentTags = currentTags; + this._meta = meta; } /** @@ -43,10 +48,10 @@ export default class ChangeTagAction extends OsmChangeAction { const type = typeId[0] const id = Number(typeId [1]) return [{ - // @ts-ignore - type: type, + type: <"node"|"way"|"relation"> type, id: id, - tags: changedTags + tags: changedTags, + meta: this._meta }] } } \ No newline at end of file diff --git a/Logic/Osm/Actions/CreateNewNodeAction.ts b/Logic/Osm/Actions/CreateNewNodeAction.ts index 4841180bd..e644eb2c6 100644 --- a/Logic/Osm/Actions/CreateNewNodeAction.ts +++ b/Logic/Osm/Actions/CreateNewNodeAction.ts @@ -14,8 +14,14 @@ export default class CreateNewNodeAction extends OsmChangeAction { private readonly _lon: number; private readonly _snapOnto: OsmWay; private readonly _reusePointDistance: number; + private meta: { changeType: "create" | "import"; theme: string }; - constructor(basicTags: Tag[], lat: number, lon: number, options?: { snapOnto: OsmWay, reusePointWithinMeters?: number }) { + constructor(basicTags: Tag[], + lat: number, lon: number, + options: { + snapOnto?: OsmWay, + reusePointWithinMeters?: number, + theme: string, changeType: "create" | "import" }) { super() this._basicTags = basicTags; this._lat = lat; @@ -25,6 +31,10 @@ export default class CreateNewNodeAction extends OsmChangeAction { } this._snapOnto = options?.snapOnto; this._reusePointDistance = options?.reusePointWithinMeters ?? 1 + this.meta = { + theme: options.theme, + changeType: options.changeType + } } async CreateChangeDescriptions(changes: Changes): Promise { @@ -47,7 +57,8 @@ export default class CreateNewNodeAction extends OsmChangeAction { changes: { lat: this._lat, lon: this._lon - } + }, + meta: this.meta } if (this._snapOnto === undefined) { return [newPointChange] @@ -78,7 +89,8 @@ export default class CreateNewNodeAction extends OsmChangeAction { return [{ tags: new And(this._basicTags).asChange(properties), type: "node", - id: reusedPointId + id: reusedPointId, + meta: this.meta }] } @@ -99,7 +111,8 @@ export default class CreateNewNodeAction extends OsmChangeAction { changes: { coordinates: locations, nodes: ids - } + }, + meta:this.meta } ] } diff --git a/Logic/Osm/Actions/DeleteAction.ts b/Logic/Osm/Actions/DeleteAction.ts index 68919bd12..34adc50e7 100644 --- a/Logic/Osm/Actions/DeleteAction.ts +++ b/Logic/Osm/Actions/DeleteAction.ts @@ -1,225 +1,62 @@ -import {UIEventSource} from "../../UIEventSource"; -import {Translation} from "../../../UI/i18n/Translation"; import State from "../../../State"; import {OsmObject} from "../OsmObject"; -import Translations from "../../../UI/i18n/Translations"; -import Constants from "../../../Models/Constants"; +import OsmChangeAction from "./OsmChangeAction"; +import {Changes} from "../Changes"; +import {ChangeDescription} from "./ChangeDescription"; +import ChangeTagAction from "./ChangeTagAction"; +import {TagsFilter} from "../../Tags/TagsFilter"; +import {And} from "../../Tags/And"; +import {Tag} from "../../Tags/Tag"; -export default class DeleteAction { +export default class DeleteAction extends OsmChangeAction { - public readonly canBeDeleted: UIEventSource<{ canBeDeleted?: boolean, reason: Translation }>; - public readonly isDeleted = new UIEventSource(false); + private readonly _softDeletionTags: TagsFilter; + private readonly meta: { + theme: string, + specialMotivation: string, + changeType: "deletion" + }; private readonly _id: string; - private readonly _allowDeletionAtChangesetCount: number; + private _hardDelete: boolean; - constructor(id: string, allowDeletionAtChangesetCount?: number) { + constructor(id: string, + softDeletionTags: TagsFilter, + meta: { + theme: string, + specialMotivation: string + }, + hardDelete: boolean) { + super() this._id = id; - this._allowDeletionAtChangesetCount = allowDeletionAtChangesetCount ?? Number.MAX_VALUE; + this._hardDelete = hardDelete; + this.meta = {...meta, changeType: "deletion"}; + this._softDeletionTags = new And([softDeletionTags, + new Tag("fixme", `A mapcomplete user marked this feature to be deleted (${meta.specialMotivation})`) + ]); - this.canBeDeleted = new UIEventSource<{ canBeDeleted?: boolean; reason: Translation }>({ - canBeDeleted: undefined, - reason: Translations.t.delete.loading - }) - - this.CheckDeleteability(false) } + protected async CreateChangeDescriptions(changes: Changes): Promise { - /** - * Does actually delete the feature; returns the event source 'this.isDeleted' - * If deletion is not allowed, triggers the callback instead - */ - public DoDelete(reason: string, onNotAllowed: () => void): void { - const isDeleted = this.isDeleted - const self = this; - let deletionStarted = false; - this.canBeDeleted.addCallbackAndRun( - canBeDeleted => { - if (isDeleted.data || deletionStarted) { - // Already deleted... - return; + const osmObject = await OsmObject.DownloadObjectAsync(this._id) + + if (this._hardDelete) { + return [{ + meta: this.meta, + doDelete: true, + type: osmObject.type, + id: osmObject.id, + }] + } else { + return await new ChangeTagAction( + this._id, this._softDeletionTags, osmObject.tags, + { + theme: State.state?.layoutToUse?.id ?? "unkown", + changeType: "soft-delete" } - - if (canBeDeleted.canBeDeleted === false) { - // We aren't allowed to delete - deletionStarted = true; - onNotAllowed(); - isDeleted.setData(true); - return; - } - - if (!canBeDeleted) { - // We are not allowed to delete (yet), this might change in the future though - return; - } - - - deletionStarted = true; - OsmObject.DownloadObject(self._id).addCallbackAndRun(obj => { - if (obj === undefined) { - return; - } - State.state.osmConnection.changesetHandler.DeleteElement( - obj, - State.state.layoutToUse, - reason, - State.state.allElements, - () => { - isDeleted.setData(true) - } - ) - }) - - } - ) - } - - /** - * Checks if the currently logged in user can delete the current point. - * State is written into this._canBeDeleted - * @constructor - * @private - */ - public CheckDeleteability(useTheInternet: boolean): void { - const t = Translations.t.delete; - const id = this._id; - const state = this.canBeDeleted - if (!id.startsWith("node")) { - this.canBeDeleted.setData({ - canBeDeleted: false, - reason: t.isntAPoint - }) - return; + ).CreateChangeDescriptions(changes) } - - // Does the currently logged in user have enough experience to delete this point? - - const deletingPointsOfOtherAllowed = State.state.osmConnection.userDetails.map(ud => { - if (ud === undefined) { - return undefined; - } - if (!ud.loggedIn) { - return false; - } - return ud.csCount >= Math.min(Constants.userJourney.deletePointsOfOthersUnlock, this._allowDeletionAtChangesetCount); - }) - - const previousEditors = new UIEventSource(undefined) - - const allByMyself = previousEditors.map(previous => { - if (previous === null || previous === undefined) { - // Not yet downloaded - return null; - } - const userId = State.state.osmConnection.userDetails.data.uid; - return !previous.some(editor => editor !== userId) - }, [State.state.osmConnection.userDetails]) - - - // User allowed OR only edited by self? - const deletetionAllowed = deletingPointsOfOtherAllowed.map(isAllowed => { - if (isAllowed === undefined) { - // No logged in user => definitively not allowed to delete! - return false; - } - if (isAllowed === true) { - return true; - } - - // At this point, the logged in user is not allowed to delete points created/edited by _others_ - // however, we query OSM and if it turns out the current point has only be edited by the current user, deletion is allowed after all! - - if (allByMyself.data === null && useTheInternet) { - // We kickoff the download here as it hasn't yet been downloaded. Note that this is mapped onto 'all by myself' above - OsmObject.DownloadHistory(id).map(versions => versions.map(version => version.tags["_last_edit:contributor:uid"])).syncWith(previousEditors) - } - if (allByMyself.data === true) { - // Yay! We can download! - return true; - } - if (allByMyself.data === false) { - // Nope, downloading not allowed... - return false; - } - - - // At this point, we don't have enough information yet to decide if the user is allowed to delete the current point... - return undefined; - }, [allByMyself]) - - - const hasRelations: UIEventSource = new UIEventSource(null) - const hasWays: UIEventSource = new UIEventSource(null) - deletetionAllowed.addCallbackAndRunD(deletetionAllowed => { - - if (deletetionAllowed === false) { - // Nope, we are not allowed to delete - state.setData({ - canBeDeleted: false, - reason: t.notEnoughExperience - }) - return true; // unregister this caller! - } - - if (!useTheInternet) { - return; - } - - // All right! We have arrived at a point that we should query OSM again to check that the point isn't a part of ways or relations - OsmObject.DownloadReferencingRelations(id).then(rels => { - hasRelations.setData(rels.length > 0) - }) - - OsmObject.DownloadReferencingWays(id).then(ways => { - hasWays.setData(ways.length > 0) - }) - return true; // unregister to only run once - }) - - - const hasWaysOrRelations = hasRelations.map(hasRelationsData => { - if (hasRelationsData === true) { - return true; - } - if (hasWays.data === true) { - return true; - } - if (hasWays.data === null || hasRelationsData === null) { - return null; - } - if (hasWays.data === false && hasRelationsData === false) { - return false; - } - return null; - }, [hasWays]) - - hasWaysOrRelations.addCallbackAndRun( - waysOrRelations => { - if (waysOrRelations == null) { - // Not yet loaded - we still wait a little bit - return; - } - if (waysOrRelations) { - // not deleteble by mapcomplete - state.setData({ - canBeDeleted: false, - reason: t.partOfOthers - }) - } else { - // alright, this point can be safely deleted! - state.setData({ - canBeDeleted: true, - reason: allByMyself.data === true ? t.onlyEditedByLoggedInUser : t.safeDelete - }) - } - - - } - ) - - } - } \ No newline at end of file diff --git a/Logic/Osm/Actions/RelationSplitHandler.ts b/Logic/Osm/Actions/RelationSplitHandler.ts index 42562c035..00c5a6706 100644 --- a/Logic/Osm/Actions/RelationSplitHandler.ts +++ b/Logic/Osm/Actions/RelationSplitHandler.ts @@ -16,14 +16,16 @@ export interface RelationSplitInput { */ export default class RelationSplitHandler extends OsmChangeAction { private readonly _input: RelationSplitInput; + private readonly _theme: string; - constructor(input: RelationSplitInput) { + constructor(input: RelationSplitInput, theme: string) { super() this._input = input; + this._theme = theme; } async CreateChangeDescriptions(changes: Changes): Promise { - return new InPlaceReplacedmentRTSH(this._input).CreateChangeDescriptions(changes) + return new InPlaceReplacedmentRTSH(this._input, this._theme).CreateChangeDescriptions(changes) } @@ -39,10 +41,12 @@ export default class RelationSplitHandler extends OsmChangeAction { */ export class InPlaceReplacedmentRTSH extends OsmChangeAction { private readonly _input: RelationSplitInput; + private readonly _theme: string; - constructor(input: RelationSplitInput) { + constructor(input: RelationSplitInput, theme: string) { super(); this._input = input; + this._theme = theme; } /** @@ -137,7 +141,11 @@ export class InPlaceReplacedmentRTSH extends OsmChangeAction { return [{ id: relation.id, type: "relation", - changes: {members: newMembers} + changes: {members: newMembers}, + meta:{ + changeType: "relation-fix", + theme: this._theme + } }]; } diff --git a/Logic/Osm/Actions/SplitAction.ts b/Logic/Osm/Actions/SplitAction.ts index 085aab413..740bc13f2 100644 --- a/Logic/Osm/Actions/SplitAction.ts +++ b/Logic/Osm/Actions/SplitAction.ts @@ -14,16 +14,19 @@ interface SplitInfo { export default class SplitAction extends OsmChangeAction { private readonly wayId: string; private readonly _splitPointsCoordinates: [number, number] []// lon, lat + private _meta: { theme: string, changeType: "split" }; /** * * @param wayId * @param splitPointCoordinates: lon, lat + * @param meta */ - constructor(wayId: string, splitPointCoordinates: [number, number][]) { + constructor(wayId: string, splitPointCoordinates: [number, number][], meta: {theme: string}) { super() this.wayId = wayId; this._splitPointsCoordinates = splitPointCoordinates + this._meta = {...meta, changeType: "split"}; } private static SegmentSplitInfo(splitInfo: SplitInfo[]): SplitInfo[][] { @@ -89,7 +92,8 @@ export default class SplitAction extends OsmChangeAction { changes: { lon: element.lngLat[0], lat: element.lngLat[1] - } + }, + meta: this._meta }) } @@ -110,7 +114,8 @@ export default class SplitAction extends OsmChangeAction { changes: { coordinates: wayPart.map(p => p.lngLat), nodes: nodeIds - } + }, + meta: this._meta }) allWayIdsInOrder.push(originalElement.id) allWaysNodesInOrder.push(nodeIds) @@ -135,7 +140,8 @@ export default class SplitAction extends OsmChangeAction { changes: { coordinates: wayPart.map(p => p.lngLat), nodes: nodeIds - } + }, + meta: this._meta }) allWayIdsInOrder.push(id) @@ -152,8 +158,8 @@ export default class SplitAction extends OsmChangeAction { allWayIdsInOrder: allWayIdsInOrder, originalNodes: originalNodes, allWaysNodesInOrder: allWaysNodesInOrder, - originalWayId: originalElement.id - }).CreateChangeDescriptions(changes) + originalWayId: originalElement.id, + }, this._meta.theme).CreateChangeDescriptions(changes) changeDescription.push(...changDescrs) } @@ -240,7 +246,6 @@ export default class SplitAction extends OsmChangeAction { closest = prevPoint } // Ok, we have a closest point! - if(closest.originalIndex === 0 || closest.originalIndex === originalPoints.length){ // We can not split on the first or last points... continue diff --git a/Logic/Osm/Changes.ts b/Logic/Osm/Changes.ts index 866c78c7a..6c90cccbb 100644 --- a/Logic/Osm/Changes.ts +++ b/Logic/Osm/Changes.ts @@ -64,9 +64,9 @@ export class Changes { if (deletedElements.length > 0) { changes += - "\n\n" + + "\n\n" + deletedElements.map(e => e.ChangesetXML(csId)).join("\n") + - "\n" + "\n" } changes += ""; @@ -99,7 +99,7 @@ export class Changes { } this.isUploading.setData(true) - this.flushChangesAsync(flushreason) + this.flushChangesAsync() .then(_ => { this.isUploading.setData(false) console.log("Changes flushed!"); @@ -110,39 +110,94 @@ export class Changes { }) } - private async flushChangesAsync(flushreason: string = undefined): Promise { + /** + * UPload the selected changes to OSM. + * Returns 'true' if successfull and if they can be removed + * @param pending + * @private + */ + private async flushSelectChanges(pending: ChangeDescription[]): Promise{ + const self = this; + const neededIds = Changes.GetNeededIds(pending) + const osmObjects = await Promise.all(neededIds.map(id => OsmObject.DownloadObjectAsync(id))); + console.log("Got the fresh objects!", osmObjects, "pending: ", pending) + const changes: { + newObjects: OsmObject[], + modifiedObjects: OsmObject[] + deletedObjects: OsmObject[] + } = self.CreateChangesetObjects(pending, osmObjects) + if (changes.newObjects.length + changes.deletedObjects.length + changes.modifiedObjects.length === 0) { + console.log("No changes to be made") + return true + } + + const meta = pending[0].meta + + const perType = Array.from(Utils.Hist(pending.map(descr => descr.meta.changeType)), ([key, count]) => ({ + key: key, + value: count, + aggregate: true + })) + const motivations = pending.filter(descr => descr.meta.specialMotivation !== undefined) + .map(descr => ({ + key: descr.meta.changeType+":"+descr.type+"/"+descr.id, + value: descr.meta.specialMotivation + })) + const metatags = [{ + key: "comment", + value: "Adding data with #MapComplete for theme #"+meta.theme + }, + { + key:"theme", + value:meta.theme + }, + ...perType, + ...motivations + ] + + await State.state.osmConnection.changesetHandler.UploadChangeset( + (csId) => Changes.createChangesetFor(""+csId, changes), + metatags + ) + + console.log("Upload successfull!") + return true; + } + + private async flushChangesAsync(): Promise { const self = this; try { - console.log("Beginning upload... " + flushreason ?? ""); // At last, we build the changeset and upload const pending = self.pendingChanges.data; - const neededIds = Changes.GetNeededIds(pending) - const osmObjects = await Promise.all(neededIds.map(id => OsmObject.DownloadObjectAsync(id))); - console.log("Got the fresh objects!", osmObjects, "pending: ", pending) - const changes: { - newObjects: OsmObject[], - modifiedObjects: OsmObject[] - deletedObjects: OsmObject[] - } = self.CreateChangesetObjects(pending, osmObjects) - if (changes.newObjects.length + changes.deletedObjects.length + changes.modifiedObjects.length === 0) { - console.log("No changes to be made") - self.pendingChanges.setData([]) - self.isUploading.setData(false) + + const pendingPerTheme = new Map() + for (const changeDescription of pending) { + const theme = changeDescription.meta.theme + if(!pendingPerTheme.has(theme)){ + pendingPerTheme.set(theme, []) + } + pendingPerTheme.get(theme).push(changeDescription) + } + + const successes = await Promise.all(Array.from(pendingPerTheme, ([key , value]) => value) + .map(async pendingChanges => { + try{ + return await self.flushSelectChanges(pendingChanges); + }catch(e){ + console.error("Could not upload some changes:",e) + return false + } + })) + + if(!successes.some(s => s == false)){ + // All changes successfull, we clear the data! + this.pendingChanges.setData([]); } - - await State.state.osmConnection.UploadChangeset( - State.state.layoutToUse, - State.state.allElements, - (csId) => Changes.createChangesetFor(csId, changes), - ) - - console.log("Upload successfull!") - this.pendingChanges.setData([]); - this.isUploading.setData(false) } catch (e) { console.error("Could not handle changes - probably an old, pending changeset in localstorage with an invalid format; erasing those", e) self.pendingChanges.setData([]) + }finally { self.isUploading.setData(false) } diff --git a/Logic/Osm/ChangesetHandler.ts b/Logic/Osm/ChangesetHandler.ts index aae51d4ee..4357fa054 100644 --- a/Logic/Osm/ChangesetHandler.ts +++ b/Logic/Osm/ChangesetHandler.ts @@ -6,29 +6,47 @@ import {ElementStorage} from "../ElementStorage"; import State from "../../State"; import Locale from "../../UI/i18n/Locale"; import Constants from "../../Models/Constants"; -import {OsmObject} from "./OsmObject"; -import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; import {Changes} from "./Changes"; +import {Utils} from "../../Utils"; + +export interface ChangesetTag { + key: string, + value: string | number, + aggregate?: boolean +} export class ChangesetHandler { - public readonly currentChangeset: UIEventSource; + public readonly currentChangeset: UIEventSource; private readonly allElements: ElementStorage; + private osmConnection: OsmConnection; private readonly changes: Changes; private readonly _dryRun: boolean; private readonly userDetails: UIEventSource; private readonly auth: any; + private readonly backend: string; - constructor(layoutName: string, dryRun: boolean, osmConnection: OsmConnection, + constructor(layoutName: string, dryRun: boolean, + osmConnection: OsmConnection, allElements: ElementStorage, changes: Changes, auth) { + this.osmConnection = osmConnection; this.allElements = allElements; this.changes = changes; this._dryRun = dryRun; this.userDetails = osmConnection.userDetails; + this.backend = osmConnection._oauth_config.url this.auth = auth; - this.currentChangeset = osmConnection.GetPreference("current-open-changeset-" + layoutName); + this.currentChangeset = osmConnection.GetPreference("current-open-changeset-" + layoutName).map( + str => { + const n = Number(str); + if (isNaN(n)) { + return undefined + } + return n + }, [], n => "" + n + ); if (dryRun) { console.log("DRYRUN ENABLED"); @@ -39,7 +57,7 @@ export class ChangesetHandler { const oldId = parseInt(node.attributes.old_id.value); if (node.attributes.new_id === undefined) { // We just removed this point! - const element =this. allElements.getEventSourceById("node/" + oldId); + const element = this.allElements.getEventSourceById("node/" + oldId); element.data._deleted = "yes" element.ping(); return; @@ -56,6 +74,10 @@ export class ChangesetHandler { } console.log("Rewriting id: ", type + "/" + oldId, "-->", type + "/" + newId); const element = this.allElements.getEventSourceById("node/" + oldId); + if(element === undefined){ + // Element to rewrite not found, probably a node or relation that is not rendered + return undefined + } element.data.id = type + "/" + newId; this.allElements.addElementById(type + "/" + newId, element); this.allElements.ContainingFeatures.set(type + "/" + newId, this.allElements.ContainingFeatures.get(type + "/" + oldId)) @@ -83,7 +105,7 @@ export class ChangesetHandler { } } this.changes.registerIdRewrites(mappings) - + } /** @@ -97,102 +119,96 @@ export class ChangesetHandler { * */ public async UploadChangeset( - layout: LayoutConfig, - generateChangeXML: (csid: string) => string): Promise { + generateChangeXML: (csid: number) => string, + extraMetaTags: ChangesetTag[]): Promise { + + if (!extraMetaTags.some(tag => tag.key === "comment") || !extraMetaTags.some(tag => tag.key === "theme")) { + throw "The meta tags should at least contain a `comment` and a `theme`" + } + if (this.userDetails.data.csCount == 0) { // The user became a contributor! this.userDetails.data.csCount = 1; this.userDetails.ping(); } - if (this._dryRun) { - const changesetXML = generateChangeXML("123456"); + const changesetXML = generateChangeXML(123456); console.log(changesetXML); return; } - if (this.currentChangeset.data === undefined || this.currentChangeset.data === "") { + if (this.currentChangeset.data === undefined) { // We have to open a new changeset try { - const csId = await this.OpenChangeset(layout) + const csId = await this.OpenChangeset(extraMetaTags) this.currentChangeset.setData(csId); const changeset = generateChangeXML(csId); console.log("Current changeset is:", changeset); await this.AddChange(csId, changeset) } catch (e) { console.error("Could not open/upload changeset due to ", e) - this.currentChangeset.setData("") + this.currentChangeset.setData(undefined) } } else { // There still exists an open changeset (or at least we hope so) + // Let's check! const csId = this.currentChangeset.data; try { + const oldChangesetMeta = await this.GetChangesetMeta(csId) + if (!oldChangesetMeta.open) { + // Mark the CS as closed... + this.currentChangeset.setData(undefined); + // ... and try again. As the cs is closed, no recursive loop can exist + await this.UploadChangeset(generateChangeXML, extraMetaTags) + return; + } + + const extraTagsById = new Map() + for (const extraMetaTag of extraMetaTags) { + extraTagsById.set(extraMetaTag.key, extraMetaTag) + } + const oldCsTags = oldChangesetMeta.tags + for (const key in oldCsTags) { + const newMetaTag = extraTagsById.get(key) + if (newMetaTag === undefined) { + extraMetaTags.push({ + key: key, + value: oldCsTags[key] + }) + } else if (newMetaTag.aggregate) { + let n = Number(newMetaTag.value) + if (isNaN(n)) { + n = 0 + } + let o = Number(oldCsTags[key]) + if (isNaN(o)) { + o = 0 + } + // We _update_ the tag itself, as it'll be updated in 'extraMetaTags' straight away + newMetaTag.value = "" + (n + o) + } else { + // The old value is overwritten, thus we drop + } + } + + await this.UpdateTags(csId, extraMetaTags.map(csTag => <[string, string]>[csTag.key, csTag.value])) + + await this.AddChange( csId, generateChangeXML(csId)) + + } catch (e) { console.warn("Could not upload, changeset is probably closed: ", e); - // Mark the CS as closed... - this.currentChangeset.setData(""); - // ... and try again. As the cs is closed, no recursive loop can exist - await this.UploadChangeset(layout, generateChangeXML) + this.currentChangeset.setData(undefined); } } } - /** - * Deletes the element with the given ID from the OSM database. - * DOES NOT PERFORM ANY SAFETY CHECKS! - * - * For the deletion of an element, a new, separate changeset is created with a slightly changed comment and some extra flags set. - * The CS will be closed afterwards. - * - * If dryrun is specified, will not actually delete the point but print the CS-XML to console instead - * - */ - public DeleteElement(object: OsmObject, - layout: LayoutConfig, - reason: string, - allElements: ElementStorage, - continuation: () => void) { - return this.DeleteElementAsync(object, layout, reason, allElements).then(continuation) - } - - public async DeleteElementAsync(object: OsmObject, - layout: LayoutConfig, - reason: string, - allElements: ElementStorage): Promise { - - function generateChangeXML(csId: string) { - let [lat, lon] = object.centerpoint(); - - let changes = ``; - changes += - `<${object.type} id="${object.id}" version="${object.version}" changeset="${csId}" lat="${lat}" lon="${lon}" />`; - changes += ""; - return changes; - } - - - if (this._dryRun) { - const changesetXML = generateChangeXML("123456"); - console.log(changesetXML); - return; - } - - const csId = await this.OpenChangeset(layout, { - isDeletionCS: true, - deletionReason: reason - }) - // The cs is open - let us actually upload! - const changes = generateChangeXML(csId) - await this.AddChange(csId, changes) - await this.CloseChangeset(csId) - } - - private async CloseChangeset(changesetId: string = undefined): Promise { + private async CloseChangeset(changesetId: number = undefined): Promise { const self = this return new Promise(function (resolve, reject) { if (changesetId === undefined) { @@ -202,7 +218,7 @@ export class ChangesetHandler { return; } console.log("closing changeset", changesetId); - self.currentChangeset.setData(""); + self.currentChangeset.setData(undefined); self.auth.xhr({ method: 'PUT', path: '/api/0.6/changeset/' + changesetId + '/close', @@ -217,39 +233,63 @@ export class ChangesetHandler { }) } - private OpenChangeset( - layout: LayoutConfig, - options?: { - isDeletionCS?: boolean, - deletionReason?: string, - } - ): Promise { + private async GetChangesetMeta(csId: number): Promise<{ + id: number, + open: boolean, + uid: number, + changes_count: number, + tags: any + }> { + const url = `${this.backend}/api/0.6/changeset/${csId}` + const csData = await Utils.downloadJson(url) + return csData.elements[0] + } + + private async UpdateTags( + csId: number, + tags: [string, string][]) { + const self = this; return new Promise(function (resolve, reject) { - options = options ?? {} - options.isDeletionCS = options.isDeletionCS ?? false - const commentExtra = layout.changesetmessage !== undefined ? " - " + layout.changesetmessage : ""; - let comment = `Adding data with #MapComplete for theme #${layout.id}${commentExtra}` - if (options.isDeletionCS) { - comment = `Deleting a point with #MapComplete for theme #${layout.id}${commentExtra}` - if (options.deletionReason) { - comment += ": " + options.deletionReason; + + tags = Utils.NoNull(tags).filter(([k, v]) => k !== undefined && v !== undefined && k !== "" && v !== "") + const metadata = tags.map(kv => ``) + + self.auth.xhr({ + method: 'PUT', + path: '/api/0.6/changeset/' + csId, + options: {header: {'Content-Type': 'text/xml'}}, + content: [``, + metadata, + ``].join("") + }, function (err, response) { + if (response === undefined) { + console.log("err", err); + reject(err) + } else { + resolve(response); } - } + }); + }) + + } + + private OpenChangeset( + changesetTags: ChangesetTag[] + ): Promise { + const self = this; + return new Promise(function (resolve, reject) { let path = window.location.pathname; path = path.substr(1, path.lastIndexOf("/")); const metadata = [ ["created_by", `MapComplete ${Constants.vNumber}`], - ["comment", comment], - ["deletion", options.isDeletionCS ? "yes" : undefined], - ["theme", layout.id], ["language", Locale.language.data], ["host", window.location.host], ["path", path], ["source", State.state.currentGPSLocation.data !== undefined ? "survey" : undefined], ["imagery", State.state.backgroundLayer.data.id], - ["theme-creator", layout.maintainer] + ...changesetTags.map(cstag => [cstag.key, cstag.value]) ] .filter(kv => (kv[1] ?? "") !== "") .map(kv => ``) @@ -268,7 +308,7 @@ export class ChangesetHandler { console.log("err", err); reject(err) } else { - resolve(response); + resolve(Number(response)); } }); }) @@ -278,8 +318,8 @@ export class ChangesetHandler { /** * Upload a changesetXML */ - private AddChange(changesetId: string, - changesetXML: string): Promise { + private AddChange(changesetId: number, + changesetXML: string): Promise { const self = this; return new Promise(function (resolve, reject) { self.auth.xhr({ diff --git a/Logic/Osm/OsmConnection.ts b/Logic/Osm/OsmConnection.ts index 4e1a9297a..c0795aad0 100644 --- a/Logic/Osm/OsmConnection.ts +++ b/Logic/Osm/OsmConnection.ts @@ -124,13 +124,6 @@ export class OsmConnection { } } - public UploadChangeset( - layout: LayoutConfig, - allElements: ElementStorage, - generateChangeXML: (csid: string) => string): Promise { - return this.changesetHandler.UploadChangeset(layout, generateChangeXML); - } - public GetPreference(key: string, prefix: string = "mapcomplete-"): UIEventSource { return this.preferencesHandler.GetPreference(key, prefix); } diff --git a/Logic/Osm/OsmObject.ts b/Logic/Osm/OsmObject.ts index 9c1efbae9..2c88b01c5 100644 --- a/Logic/Osm/OsmObject.ts +++ b/Logic/Osm/OsmObject.ts @@ -11,7 +11,7 @@ export abstract class OsmObject { private static polygonFeatures = OsmObject.constructPolygonFeatures() private static objectCache = new Map>(); private static historyCache = new Map>(); - type: string; + type: "node" | "way" | "relation"; id: number; /** * The OSM tags as simple object @@ -23,6 +23,7 @@ export abstract class OsmObject { protected constructor(type: string, id: number) { this.id = id; + // @ts-ignore this.type = type; this.tags = { id: `${this.type}/${id}` diff --git a/Models/Constants.ts b/Models/Constants.ts index 0daf78e2e..50ee3543a 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -14,7 +14,7 @@ export default class Constants { "https://overpass.kumi.systems/api/interpreter", // Offline: "https://overpass.nchc.org.tw/api/interpreter", "https://overpass.openstreetmap.ru/cgi/interpreter", - // Doesn't support nwr "https://overpass.openstreetmap.fr/api/interpreter" + // Doesn't support nwr: "https://overpass.openstreetmap.fr/api/interpreter" ] diff --git a/Models/ThemeConfig/Json/LayoutConfigJson.ts b/Models/ThemeConfig/Json/LayoutConfigJson.ts index 89439f529..40621bcd1 100644 --- a/Models/ThemeConfig/Json/LayoutConfigJson.ts +++ b/Models/ThemeConfig/Json/LayoutConfigJson.ts @@ -36,10 +36,7 @@ export interface LayoutConfigJson { * Who does maintian this preset? */ maintainer: string; - /** - * Extra piece of text that can be added to the changeset - */ - changesetmessage?: string; + /** * A version number, either semantically or by date. * Should be sortable, where the higher value is the later version diff --git a/Models/ThemeConfig/LayoutConfig.ts b/Models/ThemeConfig/LayoutConfig.ts index 8b10f6c54..06d3af4ad 100644 --- a/Models/ThemeConfig/LayoutConfig.ts +++ b/Models/ThemeConfig/LayoutConfig.ts @@ -12,7 +12,6 @@ export default class LayoutConfig { public readonly id: string; public readonly maintainer: string; public readonly credits?: string; - public readonly changesetmessage?: string; public readonly version: string; public readonly language: string[]; public readonly title: Translation; @@ -61,7 +60,6 @@ export default class LayoutConfig { context = (context ?? "") + "." + this.id; this.maintainer = json.maintainer; this.credits = json.credits; - this.changesetmessage = json.changesetmessage; this.version = json.version; this.language = []; if (typeof json.language === "string") { diff --git a/UI/BigComponents/ImportButton.ts b/UI/BigComponents/ImportButton.ts index 160405264..cf5210006 100644 --- a/UI/BigComponents/ImportButton.ts +++ b/UI/BigComponents/ImportButton.ts @@ -37,7 +37,10 @@ export default class ImportButton extends Toggle { } originalTags.data["_imported"] = "yes" originalTags.ping() // will set isImported as per its definition - const newElementAction = new CreateNewNodeAction(newTags.data, lat, lon) + const newElementAction = new CreateNewNodeAction(newTags.data, lat, lon, { + theme: State.state.layoutToUse.id, + changeType: "import" + }) await State.state.changes.applyAction(newElementAction) State.state.selectedElement.setData(State.state.allElements.ContainingFeatures.get( newElementAction.newElementId diff --git a/UI/BigComponents/SimpleAddUI.ts b/UI/BigComponents/SimpleAddUI.ts index ad6a73ec5..2ab3b75f3 100644 --- a/UI/BigComponents/SimpleAddUI.ts +++ b/UI/BigComponents/SimpleAddUI.ts @@ -56,7 +56,10 @@ export default class SimpleAddUI extends Toggle { async function createNewPoint(tags: any[], location: { lat: number, lon: number }, snapOntoWay?: OsmWay) { - const newElementAction = new CreateNewNodeAction(tags, location.lat, location.lon, {snapOnto: snapOntoWay}) + const newElementAction = new CreateNewNodeAction(tags, location.lat, location.lon, { + theme: State.state?.layoutToUse?.id ?? "unkown", + changeType: "create", + snapOnto: snapOntoWay}) await State.state.changes.applyAction(newElementAction) selectedPreset.setData(undefined) isShown.setData(false) diff --git a/UI/Popup/DeleteWizard.ts b/UI/Popup/DeleteWizard.ts index 6025ff890..fec675e84 100644 --- a/UI/Popup/DeleteWizard.ts +++ b/UI/Popup/DeleteWizard.ts @@ -4,7 +4,6 @@ import Toggle from "../Input/Toggle"; import Translations from "../i18n/Translations"; import Svg from "../../Svg"; import DeleteAction from "../../Logic/Osm/Actions/DeleteAction"; -import {Tag} from "../../Logic/Tags/Tag"; import {UIEventSource} from "../../Logic/UIEventSource"; import {TagsFilter} from "../../Logic/Tags/TagsFilter"; import TagRenderingQuestion from "./TagRenderingQuestion"; @@ -13,13 +12,11 @@ import {SubtleButton} from "../Base/SubtleButton"; import {FixedUiElement} from "../Base/FixedUiElement"; import {Translation} from "../i18n/Translation"; import BaseUIElement from "../BaseUIElement"; -import {Changes} from "../../Logic/Osm/Changes"; -import {And} from "../../Logic/Tags/And"; import Constants from "../../Models/Constants"; -import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction"; import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig"; import {AndOrTagConfigJson} from "../../Models/ThemeConfig/Json/TagConfigJson"; import DeleteConfig from "../../Models/ThemeConfig/DeleteConfig"; +import {OsmObject} from "../../Logic/Osm/OsmObject"; export default class DeleteWizard extends Toggle { /** @@ -43,44 +40,32 @@ export default class DeleteWizard extends Toggle { constructor(id: string, options: DeleteConfig) { - const deleteAction = new DeleteAction(id, options.neededChangesets); + const deleteAbility = new DeleteabilityChecker(id, options.neededChangesets) const tagsSource = State.state.allElements.getEventSourceById(id) + const isDeleted = new UIEventSource(false) const allowSoftDeletion = !!options.softDeletionTags const confirm = new UIEventSource(false) - async function softDelete(reason: string, tagsToApply: { k: string, v: string }[]) { - if (reason !== undefined) { - tagsToApply.splice(0, 0, { - k: "fixme", - v: `A mapcomplete user marked this feature to be deleted (${reason})` - }) - } - await (State.state?.changes ?? new Changes()) - .applyAction(new ChangeTagAction( - id, new And(tagsToApply.map(kv => new Tag(kv.k, kv.v))), tagsSource.data - )) - } - function doDelete(selected: TagsFilter) { + // Selected == the reasons, not the tags of the object const tgs = selected.asChange(tagsSource.data) const deleteReasonMatch = tgs.filter(kv => kv.k === "_delete_reason") - if (deleteReasonMatch.length > 0) { - // We should actually delete! - const deleteReason = deleteReasonMatch[0].v - deleteAction.DoDelete(deleteReason, () => { - // The user doesn't have sufficient permissions to _actually_ delete the feature - // We 'soft delete' instead (and add a fixme) - softDelete(deleteReason, tgs.filter(kv => kv.k !== "_delete_reason")) - - }); - return - } else { - // This is a 'non-delete'-option that was selected - softDelete(undefined, tgs) + if (deleteReasonMatch.length === 0) { + return; } + const deleteAction = new DeleteAction(id, + options.softDeletionTags, + { + theme: State.state?.layoutToUse?.id ?? "unkown", + specialMotivation: deleteReasonMatch[0]?.v + }, + deleteAbility.canBeDeleted.data.canBeDeleted + ) + State.state.changes.applyAction(deleteAction) + isDeleted.setData(true) } @@ -98,7 +83,7 @@ export default class DeleteWizard extends Toggle { saveButtonConstr: (v) => DeleteWizard.constructConfirmButton(v).onClick(() => { doDelete(v.data) }), - bottomText: (v) => DeleteWizard.constructExplanation(v, deleteAction) + bottomText: (v) => DeleteWizard.constructExplanation(v, deleteAbility) } ) })) @@ -110,7 +95,7 @@ export default class DeleteWizard extends Toggle { const deleteButton = new SubtleButton( Svg.delete_icon_ui().SetStyle("width: 2rem; height: 2rem;"), t.delete.Clone()).onClick( () => { - deleteAction.CheckDeleteability(true) + deleteAbility.CheckDeleteability(true) confirm.setData(true); } ).SetClass("w-1/2 float-right"); @@ -132,13 +117,13 @@ export default class DeleteWizard extends Toggle { deleteButton, confirm), - new VariableUiElement(deleteAction.canBeDeleted.map(cbd => new Combine([cbd.reason.Clone(), t.useSomethingElse.Clone()]))), - deleteAction.canBeDeleted.map(cbd => allowSoftDeletion || cbd.canBeDeleted !== false)), + new VariableUiElement(deleteAbility.canBeDeleted.map(cbd => new Combine([cbd.reason.Clone(), t.useSomethingElse.Clone()]))), + deleteAbility.canBeDeleted.map(cbd => allowSoftDeletion || cbd.canBeDeleted !== false)), t.loginToDelete.Clone().onClick(State.state.osmConnection.AttemptLogin), State.state.osmConnection.isLoggedIn ), - deleteAction.isDeleted), + isDeleted), undefined, isShown) @@ -167,7 +152,7 @@ export default class DeleteWizard extends Toggle { } - private static constructExplanation(tags: UIEventSource, deleteAction: DeleteAction) { + private static constructExplanation(tags: UIEventSource, deleteAction: DeleteabilityChecker) { const t = Translations.t.delete; return new VariableUiElement(tags.map( currentTags => { @@ -263,4 +248,172 @@ export default class DeleteWizard extends Toggle { ) } +} + +class DeleteabilityChecker { + + public readonly canBeDeleted: UIEventSource<{ canBeDeleted?: boolean, reason: Translation }>; + private readonly _id: string; + private readonly _allowDeletionAtChangesetCount: number; + + + constructor(id: string, + allowDeletionAtChangesetCount?: number) { + this._id = id; + this._allowDeletionAtChangesetCount = allowDeletionAtChangesetCount ?? Number.MAX_VALUE; + + this.canBeDeleted = new UIEventSource<{ canBeDeleted?: boolean; reason: Translation }>({ + canBeDeleted: undefined, + reason: Translations.t.delete.loading + }) + this.CheckDeleteability(false) + } + + /** + * Checks if the currently logged in user can delete the current point. + * State is written into this._canBeDeleted + * @constructor + * @private + */ + public CheckDeleteability(useTheInternet: boolean): void { + const t = Translations.t.delete; + const id = this._id; + const state = this.canBeDeleted + if (!id.startsWith("node")) { + this.canBeDeleted.setData({ + canBeDeleted: false, + reason: t.isntAPoint + }) + return; + } + + // Does the currently logged in user have enough experience to delete this point? + + const deletingPointsOfOtherAllowed = State.state.osmConnection.userDetails.map(ud => { + if (ud === undefined) { + return undefined; + } + if (!ud.loggedIn) { + return false; + } + return ud.csCount >= Math.min(Constants.userJourney.deletePointsOfOthersUnlock, this._allowDeletionAtChangesetCount); + }) + + const previousEditors = new UIEventSource(undefined) + + const allByMyself = previousEditors.map(previous => { + if (previous === null || previous === undefined) { + // Not yet downloaded + return null; + } + const userId = State.state.osmConnection.userDetails.data.uid; + return !previous.some(editor => editor !== userId) + }, [State.state.osmConnection.userDetails]) + + + // User allowed OR only edited by self? + const deletetionAllowed = deletingPointsOfOtherAllowed.map(isAllowed => { + if (isAllowed === undefined) { + // No logged in user => definitively not allowed to delete! + return false; + } + if (isAllowed === true) { + return true; + } + + // At this point, the logged in user is not allowed to delete points created/edited by _others_ + // however, we query OSM and if it turns out the current point has only be edited by the current user, deletion is allowed after all! + + if (allByMyself.data === null && useTheInternet) { + // We kickoff the download here as it hasn't yet been downloaded. Note that this is mapped onto 'all by myself' above + OsmObject.DownloadHistory(id).map(versions => versions.map(version => version.tags["_last_edit:contributor:uid"])).syncWith(previousEditors) + } + if (allByMyself.data === true) { + // Yay! We can download! + return true; + } + if (allByMyself.data === false) { + // Nope, downloading not allowed... + return false; + } + + + // At this point, we don't have enough information yet to decide if the user is allowed to delete the current point... + return undefined; + }, [allByMyself]) + + + const hasRelations: UIEventSource = new UIEventSource(null) + const hasWays: UIEventSource = new UIEventSource(null) + deletetionAllowed.addCallbackAndRunD(deletetionAllowed => { + + if (deletetionAllowed === false) { + // Nope, we are not allowed to delete + state.setData({ + canBeDeleted: false, + reason: t.notEnoughExperience + }) + return true; // unregister this caller! + } + + if (!useTheInternet) { + return; + } + + // All right! We have arrived at a point that we should query OSM again to check that the point isn't a part of ways or relations + OsmObject.DownloadReferencingRelations(id).then(rels => { + hasRelations.setData(rels.length > 0) + }) + + OsmObject.DownloadReferencingWays(id).then(ways => { + hasWays.setData(ways.length > 0) + }) + return true; // unregister to only run once + }) + + + const hasWaysOrRelations = hasRelations.map(hasRelationsData => { + if (hasRelationsData === true) { + return true; + } + if (hasWays.data === true) { + return true; + } + if (hasWays.data === null || hasRelationsData === null) { + return null; + } + if (hasWays.data === false && hasRelationsData === false) { + return false; + } + return null; + }, [hasWays]) + + hasWaysOrRelations.addCallbackAndRun( + waysOrRelations => { + if (waysOrRelations == null) { + // Not yet loaded - we still wait a little bit + return; + } + if (waysOrRelations) { + // not deleteble by mapcomplete + state.setData({ + canBeDeleted: false, + reason: t.partOfOthers + }) + } else { + // alright, this point can be safely deleted! + state.setData({ + canBeDeleted: true, + reason: allByMyself.data === true ? t.onlyEditedByLoggedInUser : t.safeDelete + }) + } + + + } + ) + + + } + + } \ No newline at end of file diff --git a/UI/Popup/SplitRoadWizard.ts b/UI/Popup/SplitRoadWizard.ts index 17e1bd013..86e137fa3 100644 --- a/UI/Popup/SplitRoadWizard.ts +++ b/UI/Popup/SplitRoadWizard.ts @@ -136,7 +136,9 @@ export default class SplitRoadWizard extends Toggle { // Save button const saveButton = new Button(t.split.Clone(), () => { hasBeenSplit.setData(true) - State.state.changes.applyAction(new SplitAction(id, splitPoints.data.map(ff => ff.feature.geometry.coordinates))) + State.state.changes.applyAction(new SplitAction(id, splitPoints.data.map(ff => ff.feature.geometry.coordinates), { + theme: State.state?.layoutToUse?.id + })) }) saveButton.SetClass("btn btn-primary mr-3"); diff --git a/UI/Popup/TagRenderingQuestion.ts b/UI/Popup/TagRenderingQuestion.ts index a4eb83b0f..16811a3b1 100644 --- a/UI/Popup/TagRenderingQuestion.ts +++ b/UI/Popup/TagRenderingQuestion.ts @@ -86,7 +86,10 @@ export default class TagRenderingQuestion extends Combine { if (selection) { (State.state?.changes ?? new Changes()) .applyAction(new ChangeTagAction( - tags.data.id, selection, tags.data + tags.data.id, selection, tags.data, { + theme: State.state?.layoutToUse?.id ?? "unkown", + changeType: "answer", + } )).then(_ => { console.log("Tagchanges applied") }) diff --git a/Utils.ts b/Utils.ts index 5c04c9547..7763bc884 100644 --- a/Utils.ts +++ b/Utils.ts @@ -101,6 +101,14 @@ export class Utils { return ls; } + public static Hist(array: string[]): Map{ + const hist = new Map(); + for (const s of array) { + hist.set(s, 1 + (hist.get(s) ?? 0)) + } + return hist; + } + public static NoEmpty(array: string[]): string[] { const ls: string[] = []; for (const t of array) { From ff11f96e912f482f990026d7271fe565d4168fb7 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 6 Oct 2021 02:30:23 +0200 Subject: [PATCH 03/26] Add wikidata-images to etymology theme, various fixes for custom image carousels and gracious handling of wikidata/wikimedia --- Logic/ImageProviders/AllImageProviders.ts | 10 +- Logic/ImageProviders/GenericImageProvider.ts | 9 +- Logic/ImageProviders/ImageProvider.ts | 3 +- Logic/ImageProviders/WikidataImageProvider.ts | 11 +- .../ImageProviders/WikimediaImageProvider.ts | 51 +-------- Logic/Web/Wikidata.ts | 2 +- Logic/Web/Wikimedia.ts | 47 ++++++++ UI/SpecialVisualizations.ts | 9 +- UI/WikipediaBox.ts | 104 +++++++++++------- assets/themes/etymology.json | 8 +- 10 files changed, 155 insertions(+), 99 deletions(-) create mode 100644 Logic/Web/Wikimedia.ts diff --git a/Logic/ImageProviders/AllImageProviders.ts b/Logic/ImageProviders/AllImageProviders.ts index 92818379f..2f27539a1 100644 --- a/Logic/ImageProviders/AllImageProviders.ts +++ b/Logic/ImageProviders/AllImageProviders.ts @@ -21,7 +21,7 @@ export default class AllImageProviders { private static _cache: Map> = new Map>() - public static LoadImagesFor(tags: UIEventSource, imagePrefix?: string): UIEventSource { + public static LoadImagesFor(tags: UIEventSource, tagKey?: string): UIEventSource { const id = tags.data.id if (id === undefined) { return undefined; @@ -39,12 +39,8 @@ export default class AllImageProviders { for (const imageProvider of AllImageProviders.ImageAttributionSource) { let prefixes = imageProvider.defaultKeyPrefixes - if(imagePrefix !== undefined){ - prefixes = [...prefixes] - if(prefixes.indexOf("image") >= 0){ - prefixes.splice(prefixes.indexOf("image"), 1) - } - prefixes.push(imagePrefix) + if(tagKey !== undefined){ + prefixes = [tagKey] } const singleSource = imageProvider.GetRelevantUrls(tags, { diff --git a/Logic/ImageProviders/GenericImageProvider.ts b/Logic/ImageProviders/GenericImageProvider.ts index 170829fe0..2f2dab322 100644 --- a/Logic/ImageProviders/GenericImageProvider.ts +++ b/Logic/ImageProviders/GenericImageProvider.ts @@ -20,7 +20,14 @@ export default class GenericImageProvider extends ImageProvider { if (this._valuePrefixBlacklist.some(prefix => value.startsWith(prefix))) { return [] } - + + try{ + new URL(value) + }catch (_){ + // Not a valid URL + return [] + } + return [Promise.resolve({ key: key, url: value, diff --git a/Logic/ImageProviders/ImageProvider.ts b/Logic/ImageProviders/ImageProvider.ts index efce6aa92..be3d58ce5 100644 --- a/Logic/ImageProviders/ImageProvider.ts +++ b/Logic/ImageProviders/ImageProvider.ts @@ -17,7 +17,7 @@ export default abstract class ImageProvider { if (cached !== undefined) { return cached; } - const src =UIEventSource.FromPromise(this.DownloadAttribution(url)) + const src = UIEventSource.FromPromise(this.DownloadAttribution(url)) this._cache.set(url, src) return src; } @@ -38,6 +38,7 @@ export default abstract class ImageProvider { } const relevantUrls = new UIEventSource<{ url: string; key: string; provider: ImageProvider }[]>([]) const seenValues = new Set() + const self = this allTags.addCallbackAndRunD(tags => { for (const key in tags) { if(!prefixes.some(prefix => key.startsWith(prefix))){ diff --git a/Logic/ImageProviders/WikidataImageProvider.ts b/Logic/ImageProviders/WikidataImageProvider.ts index f24f58aca..9c3d6af3e 100644 --- a/Logic/ImageProviders/WikidataImageProvider.ts +++ b/Logic/ImageProviders/WikidataImageProvider.ts @@ -27,6 +27,7 @@ export class WikidataImageProvider extends ImageProvider { if(entity === undefined){ return [] } + console.log("Entity:", entity) const allImages : Promise[] = [] // P18 is the claim 'depicted in this image' @@ -34,9 +35,17 @@ export class WikidataImageProvider extends ImageProvider { const promises = await WikimediaImageProvider.singleton.ExtractUrls(undefined, img) allImages.push(...promises) } + // P373 is 'commons category' + for (let cat of Array.from(entity.claims.get("P373") ?? [])) { + if(!cat.startsWith("Category:")){ + cat = "Category:"+cat + } + const promises = await WikimediaImageProvider.singleton.ExtractUrls(undefined, cat) + allImages.push(...promises) + } const commons = entity.commons - if (commons !== undefined) { + if (commons !== undefined && (commons.startsWith("Category:") || commons.startsWith("File:"))) { const promises = await WikimediaImageProvider.singleton.ExtractUrls(undefined , commons) allImages.push(...promises) } diff --git a/Logic/ImageProviders/WikimediaImageProvider.ts b/Logic/ImageProviders/WikimediaImageProvider.ts index 0d2f6c1d0..ae922c99a 100644 --- a/Logic/ImageProviders/WikimediaImageProvider.ts +++ b/Logic/ImageProviders/WikimediaImageProvider.ts @@ -4,6 +4,7 @@ import Svg from "../../Svg"; import Link from "../../UI/Base/Link"; import {Utils} from "../../Utils"; import {LicenseInfo} from "./LicenseInfo"; +import Wikimedia from "../Web/Wikimedia"; /** * This module provides endpoints for wikimedia and others @@ -20,50 +21,6 @@ export class WikimediaImageProvider extends ImageProvider { super(); } - /** - * Recursively walks a wikimedia commons category in order to search for (image) files - * Returns (a promise of) a list of URLS - * @param categoryName The name of the wikimedia category - * @param maxLoad: the maximum amount of images to return - * @param continueParameter: if the page indicates that more pages should be loaded, this uses a token to continue. Provided by wikimedia - */ - private static async GetImagesInCategory(categoryName: string, - maxLoad = 10, - continueParameter: string = undefined): Promise { - if (categoryName === undefined || categoryName === null || categoryName === "") { - return []; - } - if (!categoryName.startsWith("Category:")) { - categoryName = "Category:" + categoryName; - } - - let url = "https://commons.wikimedia.org/w/api.php?" + - "action=query&list=categorymembers&format=json&" + - "&origin=*" + - "&cmtitle=" + encodeURIComponent(categoryName); - if (continueParameter !== undefined) { - url = `${url}&cmcontinue=${continueParameter}`; - } - const response = await Utils.downloadJson(url) - const members = response.query?.categorymembers ?? []; - const imageOverview: string[] = members.map(member => member.title); - - if (response.continue === undefined) { - // We are done crawling through the category - no continuation in sight - return imageOverview; - } - - if (maxLoad - imageOverview.length <= 0) { - console.debug(`Recursive wikimedia category load stopped for ${categoryName}`) - return imageOverview; - } - - // We do have a continue token - let's load the next page - const recursive = await this.GetImagesInCategory(categoryName, maxLoad - imageOverview.length, response.continue.cmcontinue) - imageOverview.push(...recursive) - return imageOverview - } - private static ExtractFileName(url: string) { if (!url.startsWith("http")) { return url; @@ -110,7 +67,7 @@ export class WikimediaImageProvider extends ImageProvider { const licenseInfo = new LicenseInfo(); const license = (data.query.pages[-1].imageinfo ?? [])[0]?.extmetadata; if (license === undefined) { - console.error("This file has no usable metedata or license attached... Please fix the license info file yourself!") + console.warn("The file", filename ,"has no usable metedata or license attached... Please fix the license info file yourself!") return undefined; } @@ -149,8 +106,8 @@ export class WikimediaImageProvider extends ImageProvider { return [Promise.resolve(result)] } if (value.startsWith("Category:")) { - const urls = await WikimediaImageProvider.GetImagesInCategory(value) - return urls.map(image => this.UrlForImage(image)) + const urls = await Wikimedia.GetCategoryContents(value) + return urls.filter(url => url.startsWith("File:")).map(image => this.UrlForImage(image)) } if (value.startsWith("File:")) { return [this.UrlForImage(value)] diff --git a/Logic/Web/Wikidata.ts b/Logic/Web/Wikidata.ts index ae981ee82..f92b419bf 100644 --- a/Logic/Web/Wikidata.ts +++ b/Logic/Web/Wikidata.ts @@ -42,7 +42,7 @@ export default class Wikidata { sitelinks.delete("commons") const claims = new Map>(); - for (const claimId of entity.claims) { + for (const claimId in entity.claims) { const claimsList: any[] = entity.claims[claimId] const values = new Set() diff --git a/Logic/Web/Wikimedia.ts b/Logic/Web/Wikimedia.ts new file mode 100644 index 000000000..8aa34068e --- /dev/null +++ b/Logic/Web/Wikimedia.ts @@ -0,0 +1,47 @@ +import {Utils} from "../../Utils"; + +export default class Wikimedia { + /** + * Recursively walks a wikimedia commons category in order to search for entries, which can be File: or Category: entries + * Returns (a promise of) a list of URLS + * @param categoryName The name of the wikimedia category + * @param maxLoad: the maximum amount of images to return + * @param continueParameter: if the page indicates that more pages should be loaded, this uses a token to continue. Provided by wikimedia + */ + public static async GetCategoryContents(categoryName: string, + maxLoad = 10, + continueParameter: string = undefined): Promise { + if (categoryName === undefined || categoryName === null || categoryName === "") { + return []; + } + if (!categoryName.startsWith("Category:")) { + categoryName = "Category:" + categoryName; + } + + let url = "https://commons.wikimedia.org/w/api.php?" + + "action=query&list=categorymembers&format=json&" + + "&origin=*" + + "&cmtitle=" + encodeURIComponent(categoryName); + if (continueParameter !== undefined) { + url = `${url}&cmcontinue=${continueParameter}`; + } + const response = await Utils.downloadJson(url) + const members = response.query?.categorymembers ?? []; + const imageOverview: string[] = members.map(member => member.title); + + if (response.continue === undefined) { + // We are done crawling through the category - no continuation in sight + return imageOverview; + } + + if (maxLoad - imageOverview.length <= 0) { + console.debug(`Recursive wikimedia category load stopped for ${categoryName}`) + return imageOverview; + } + + // We do have a continue token - let's load the next page + const recursive = await Wikimedia.GetCategoryContents(categoryName, maxLoad - imageOverview.length, response.continue.cmcontinue) + imageOverview.push(...recursive) + return imageOverview + } +} \ No newline at end of file diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index de45911db..d4c4ea2cc 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -64,13 +64,16 @@ export default class SpecialVisualizations { funcName: "image_carousel", docs: "Creates an image carousel for the given sources. An attempt will be made to guess what source is used. Supported: Wikidata identifiers, Wikipedia pages, Wikimedia categories, IMGUR (with attribution, direct links)", args: [{ - name: "image key/prefix", + name: "image key/prefix (multiple values allowed if comma-seperated)", defaultValue: "image", doc: "The keys given to the images, e.g. if image is given, the first picture URL will be added as image, the second as image:0, the third as image:1, etc... " }], constr: (state: State, tags, args) => { - const imagePrefix = args[0]; - return new ImageCarousel(AllImageProviders.LoadImagesFor(tags, imagePrefix), tags); + let imagePrefixes = undefined; + if(args.length > 0){ + imagePrefixes = args; + } + return new ImageCarousel(AllImageProviders.LoadImagesFor(tags, imagePrefixes), tags); } }, { diff --git a/UI/WikipediaBox.ts b/UI/WikipediaBox.ts index 7f0d392a6..4b0f08d4f 100644 --- a/UI/WikipediaBox.ts +++ b/UI/WikipediaBox.ts @@ -11,6 +11,7 @@ import Svg from "../Svg"; import Wikidata, {WikidataResponse} from "../Logic/Web/Wikidata"; import Locale from "./i18n/Locale"; import Toggle from "./Input/Toggle"; +import Link from "./Base/Link"; export default class WikipediaBox extends Toggle { @@ -22,49 +23,78 @@ export default class WikipediaBox extends Toggle { } - const wikibox = wikidataId - .bind(id => { - console.log("Wikidata is", id) - if(id === undefined){ - return undefined - } - console.log("Initing load WIkidataentry with id", id) - return Wikidata.LoadWikidataEntry(id); - }) - .map(maybewikidata => { - if (maybewikidata === undefined) { - return new Loading(wp.loading.Clone()) - } - if (maybewikidata["error"] !== undefined) { - return wp.failed.Clone().SetClass("alert p-4") - } - const wikidata = maybewikidata["success"] - console.log("Got wikidata response", wikidata) - if (wikidata.wikisites.size === 0) { - return wp.noWikipediaPage.Clone() - } + const wikiLink: UIEventSource<[string, string] | "loading" | "failed" | "no page"> = + wikidataId + .bind(id => { + if (id === undefined) { + return undefined + } + return Wikidata.LoadWikidataEntry(id); + }) + .map(maybewikidata => { + if (maybewikidata === undefined) { + return "loading" + } + if (maybewikidata["error"] !== undefined) { + return "failed" - const preferredLanguage = [Locale.language.data, "en", Array.from(wikidata.wikisites.keys())[0]] - let language - let pagetitle; - let i = 0 - do { - language = preferredLanguage[i] - pagetitle = wikidata.wikisites.get(language) - i++; - } while (pagetitle === undefined) - return WikipediaBox.createContents(pagetitle, language) - }, [Locale.language]) + } + const wikidata = maybewikidata["success"] + if (wikidata.wikisites.size === 0) { + return "no page" + } + + const preferredLanguage = [Locale.language.data, "en", Array.from(wikidata.wikisites.keys())[0]] + let language + let pagetitle; + let i = 0 + do { + language = preferredLanguage[i] + pagetitle = wikidata.wikisites.get(language) + i++; + } while (pagetitle === undefined) + return [pagetitle, language] + }, [Locale.language]) const contents = new VariableUiElement( - wikibox + wikiLink.map(status => { + if (status === "loading") { + return new Loading(wp.loading.Clone()).SetClass("pl-6 pt-2") + } + + if (status === "failed") { + return wp.failed.Clone().SetClass("alert p-4") + } + if (status == "no page") { + return wp.noWikipediaPage.Clone() + } + + const [pagetitle, language] = status + return WikipediaBox.createContents(pagetitle, language) + + }) ).SetClass("overflow-auto normal-background rounded-lg") + const linkElement = new VariableUiElement(wikiLink.map(state => { + if (typeof state !== "string") { + const [pagetitle, language] = state + const url= `https://${language}.wikipedia.org/wiki/${pagetitle}` + return new Link(Svg.pop_out_ui().SetStyle("width: 1.2rem").SetClass("block "), url, true) + } + return undefined})) + .SetClass("flex items-center") + const mainContent = new Combine([ - new Combine([Svg.wikipedia_ui().SetStyle("width: 1.5rem").SetClass("mr-3"), - new Title(Translations.t.general.wikipedia.wikipediaboxTitle.Clone(), 2)]).SetClass("flex"), + new Combine([ + new Combine([ + Svg.wikipedia_ui().SetStyle("width: 1.5rem").SetClass("mr-3"), + new Title(Translations.t.general.wikipedia.wikipediaboxTitle.Clone(), 2), + ]).SetClass("flex"), + + linkElement + ]).SetClass("flex justify-between"), contents]).SetClass("block rounded-xl subtle-background m-1 p-2 flex flex-col") .SetStyle("max-height: inherit") super( @@ -102,8 +132,8 @@ export default class WikipediaBox extends Toggle { return undefined }) - return new Combine([new VariableUiElement(contents).SetClass("block pl-6 pt-2")]) - .SetClass("block") + return new Combine([new VariableUiElement(contents) + .SetClass("block pl-6 pt-2")]) } } \ No newline at end of file diff --git a/assets/themes/etymology.json b/assets/themes/etymology.json index a8ca9dfc9..ec170496a 100644 --- a/assets/themes/etymology.json +++ b/assets/themes/etymology.json @@ -50,6 +50,12 @@ "nl": "Alle lagen met een gelinkt etymology" }, "tagRenderings": [ + { + "id": "etymology_wikidata_image", + "render": { + "*": "{image_carousel(name:etymology:wikidata)}" + } + }, { "id": "simple etymology", "render": { @@ -63,7 +69,7 @@ { "id": "wikipedia-etymology", "render": { - "*": "{wikipedia(name:etymology:wikidata):max-height:20rem}" + "*": "{wikipedia(name:etymology:wikidata):max-height:30rem}" } } ], From f05a7d239e8407d350cb997c0d66e304ee777423 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 6 Oct 2021 02:33:40 +0200 Subject: [PATCH 04/26] Fix tests --- test/RelationSplitHandler.spec.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/RelationSplitHandler.spec.ts b/test/RelationSplitHandler.spec.ts index 0b5261f13..43d57de87 100644 --- a/test/RelationSplitHandler.spec.ts +++ b/test/RelationSplitHandler.spec.ts @@ -2,7 +2,6 @@ import T from "./TestHelper"; import {InPlaceReplacedmentRTSH} from "../Logic/Osm/Actions/RelationSplitHandler"; import {OsmObject, OsmRelation} from "../Logic/Osm/OsmObject"; import {Changes} from "../Logic/Osm/Changes"; -import {equal} from "assert"; import {Utils} from "../Utils"; export default class RelationSplitHandlerSpec extends T { @@ -49,7 +48,7 @@ export default class RelationSplitHandlerSpec extends T { allWayIdsInOrder: [295132739, -1], originalNodes: originalNodeIds, allWaysNodesInOrder: withSplit - }) + },"no-theme") const changeDescription = await splitter.CreateChangeDescriptions(new Changes()) const allIds = changeDescription[0].changes["members"].map(m => m.ref).join(",") const expected = "687866206,295132739,-1,690497698" From 5628be36327906e1d0f44004f8f8ad41b3b2ea5b Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 6 Oct 2021 02:36:58 +0200 Subject: [PATCH 05/26] Fix tests --- Logic/Osm/Actions/ChangeTagAction.ts | 2 +- UI/Image/DeleteImage.ts | 10 ++++++++-- UI/Image/ImageUploadFlow.ts | 6 +++++- test/SplitAction.spec.ts | 12 +++++++++--- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Logic/Osm/Actions/ChangeTagAction.ts b/Logic/Osm/Actions/ChangeTagAction.ts index fd55953d1..00e9b001e 100644 --- a/Logic/Osm/Actions/ChangeTagAction.ts +++ b/Logic/Osm/Actions/ChangeTagAction.ts @@ -11,7 +11,7 @@ export default class ChangeTagAction extends OsmChangeAction { constructor(elementId: string, tagsFilter: TagsFilter, currentTags: any, meta: { theme: string, - changeType: "answer" | "soft-delete" + changeType: "answer" | "soft-delete" | "add-image" }) { super(); this._elementId = elementId; diff --git a/UI/Image/DeleteImage.ts b/UI/Image/DeleteImage.ts index 800eec53c..68afbb3fc 100644 --- a/UI/Image/DeleteImage.ts +++ b/UI/Image/DeleteImage.ts @@ -16,7 +16,10 @@ export default class DeleteImage extends Toggle { .SetClass("rounded-full p-1") .SetStyle("color:white;background:#ff8c8c") .onClick(async() => { - await State.state?.changes?.applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data)) + await State.state?.changes?.applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data, { + changeType: "answer", + theme: "test" + })) }); const deleteButton = Translations.t.image.doDelete.Clone() @@ -24,7 +27,10 @@ export default class DeleteImage extends Toggle { .SetStyle("color:white;background:#ff8c8c; border-top-left-radius:30rem; border-top-right-radius: 30rem;") .onClick( async() => { await State.state?.changes?.applyAction( - new ChangeTagAction(tags.data.id, new Tag(key, ""), tags.data) + new ChangeTagAction(tags.data.id, new Tag(key, ""), tags.data,{ + changeType: "answer", + theme: "test" + }) ) }); diff --git a/UI/Image/ImageUploadFlow.ts b/UI/Image/ImageUploadFlow.ts index 4eec0b85c..2a79417bc 100644 --- a/UI/Image/ImageUploadFlow.ts +++ b/UI/Image/ImageUploadFlow.ts @@ -31,7 +31,11 @@ export class ImageUploadFlow extends Toggle { console.log("Adding image:" + key, url); Promise.resolve(State.state.changes .applyAction(new ChangeTagAction( - tags.id, new Tag(key, url), tagsSource.data + tags.id, new Tag(key, url), tagsSource.data, + { + changeType: "add-image", + theme: State.state.layoutToUse.id + } ))) }) diff --git a/test/SplitAction.spec.ts b/test/SplitAction.spec.ts index 6e4ed77a9..cf9eb5f03 100644 --- a/test/SplitAction.spec.ts +++ b/test/SplitAction.spec.ts @@ -191,7 +191,9 @@ export default class SplitActionSpec extends T { // Lets split road https://www.openstreetmap.org/way/295132739 const id = "way/295132739" const splitPoint: [number, number] = [3.246733546257019, 51.181710380278176] - const splitter = new SplitAction(id, [splitPoint]) + const splitter = new SplitAction(id, [splitPoint], { + theme: "test" + }) const changeDescription = await splitter.CreateChangeDescriptions(new Changes()) equal(changeDescription[0].type, "node") @@ -235,7 +237,9 @@ export default class SplitActionSpec extends T { const id = "way/61435323" const splitPoint: [number, number] = [ 3.2021324336528774, 51.2170001600597] - const splitter = new SplitAction(id, [splitPoint]) + const splitter = new SplitAction(id, [splitPoint], { + theme: "test" + }) const changeDescription = await splitter.CreateChangeDescriptions(new Changes()) // Should be a new node @@ -247,7 +251,9 @@ export default class SplitActionSpec extends T { // Lets split road near an already existing point https://www.openstreetmap.org/way/295132739 const id = "way/295132739" const splitPoint: [number, number] = [3.2451081275939937, 51.18116898253599] - const splitter = new SplitAction(id, [splitPoint]) + const splitter = new SplitAction(id, [splitPoint], { + theme: "test" + }) const changeDescription = await splitter.CreateChangeDescriptions(new Changes()) equal(2, changeDescription.length) From b5d2b99ced62a900f8aacc83ddfe3b5b746c6990 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 6 Oct 2021 17:48:07 +0200 Subject: [PATCH 06/26] Add tests for wikimedia comons edge cases --- Logic/ImageProviders/AllImageProviders.ts | 6 +- .../ImageProviders/WikimediaImageProvider.ts | 42 ++++++++---- test/ImageProvider.spec.ts | 68 +++++++++++++++++++ test/TestAll.ts | 11 +-- test/TestHelper.ts | 8 +++ 5 files changed, 118 insertions(+), 17 deletions(-) create mode 100644 test/ImageProvider.spec.ts diff --git a/Logic/ImageProviders/AllImageProviders.ts b/Logic/ImageProviders/AllImageProviders.ts index 2f27539a1..b56fae6f3 100644 --- a/Logic/ImageProviders/AllImageProviders.ts +++ b/Logic/ImageProviders/AllImageProviders.ts @@ -16,7 +16,11 @@ export default class AllImageProviders { Mapillary.singleton, WikidataImageProvider.singleton, WikimediaImageProvider.singleton, - new GenericImageProvider([].concat(...Imgur.defaultValuePrefix, WikimediaImageProvider.commonsPrefix, ...Mapillary.valuePrefixes))] + new GenericImageProvider( + [].concat(...Imgur.defaultValuePrefix, ...WikimediaImageProvider.commonsPrefixes, ...Mapillary.valuePrefixes) + ) + + ] private static _cache: Map> = new Map>() diff --git a/Logic/ImageProviders/WikimediaImageProvider.ts b/Logic/ImageProviders/WikimediaImageProvider.ts index ae922c99a..a00df6719 100644 --- a/Logic/ImageProviders/WikimediaImageProvider.ts +++ b/Logic/ImageProviders/WikimediaImageProvider.ts @@ -15,7 +15,7 @@ export class WikimediaImageProvider extends ImageProvider { private readonly commons_key = "wikimedia_commons" public readonly defaultKeyPrefixes = [this.commons_key,"image"] public static readonly singleton = new WikimediaImageProvider(); - public static readonly commonsPrefix = "https://commons.wikimedia.org/wiki/" + public static readonly commonsPrefixes = ["https://commons.wikimedia.org/wiki/", "https://upload.wikimedia.org", "File:"] private constructor() { super(); @@ -89,22 +89,40 @@ export class WikimediaImageProvider extends ImageProvider { } return {url: this.PrepareUrl(image), key: undefined, provider: this} } + + private startsWithCommonsPrefix(value: string){ + return WikimediaImageProvider.commonsPrefixes.some(prefix => value.startsWith(prefix)) + } + + private removeCommonsPrefix(value: string){ + if(value.startsWith("https://upload.wikimedia.org/")){ + value = value.substring(value.lastIndexOf("/") + 1) + value = decodeURIComponent(value) + if(!value.startsWith("File:")){ + value = "File:"+value + } + return value; + } + + for (const prefix of WikimediaImageProvider.commonsPrefixes) { + if(value.startsWith(prefix)){ + let part = value.substr(prefix.length) + if(prefix.startsWith("http")){ + part = decodeURIComponent(part) + } + return part + } + } + return value; + } public async ExtractUrls(key: string, value: string): Promise[]> { - if(key !== undefined && key !== this.commons_key && !value.startsWith(WikimediaImageProvider.commonsPrefix)){ + const hasCommonsPrefix = this.startsWithCommonsPrefix(value) + if(key !== undefined && key !== this.commons_key && !hasCommonsPrefix){ return [] } - if (value.startsWith(WikimediaImageProvider.commonsPrefix)) { - value = value.substring(WikimediaImageProvider.commonsPrefix.length) - } else if (value.startsWith("https://upload.wikimedia.org")) { - const result: ProvidedImage = { - key: undefined, - url: value, - provider: this - } - return [Promise.resolve(result)] - } + value = this.removeCommonsPrefix(value) if (value.startsWith("Category:")) { const urls = await Wikimedia.GetCategoryContents(value) return urls.filter(url => url.startsWith("File:")).map(image => this.UrlForImage(image)) diff --git a/test/ImageProvider.spec.ts b/test/ImageProvider.spec.ts new file mode 100644 index 000000000..76e73fc33 --- /dev/null +++ b/test/ImageProvider.spec.ts @@ -0,0 +1,68 @@ +import T from "./TestHelper"; +import AllImageProviders from "../Logic/ImageProviders/AllImageProviders"; +import {UIEventSource} from "../Logic/UIEventSource"; + +export default class ImageProviderSpec extends T { + + constructor() { + super("ImageProvider", [ + ["Search images", () => { + + let i = 0 + function expects(url, tags, providerName = undefined) { + tags.id = "test/"+i + i++ + AllImageProviders.LoadImagesFor(new UIEventSource(tags)).addCallbackD(images => { + console.log("ImageProvider test", tags.id, "for", tags) + const img = images[0] + if(img === undefined){ + throw "No image found" + } + T.equals(url, img.url, tags.id) + if(providerName){ + T.equals(img.provider.constructor.name, providerName) + } + console.log("OK") + }) + } + + const muntpoort_expected = "https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABr%C3%BCgge-Muntpoort_6-29510-58192.jpg?width=500&height=400" + expects( + muntpoort_expected, + { "wikimedia_commons":"File:Brügge-Muntpoort_6-29510-58192.jpg" + } , "WikimediaImageProvider") + + + + expects(muntpoort_expected, + { "wikimedia_commons":"https://upload.wikimedia.org/wikipedia/commons/c/cd/Br%C3%BCgge-Muntpoort_6-29510-58192.jpg" + } , "WikimediaImageProvider") + + expects(muntpoort_expected , { + "image":"https://upload.wikimedia.org/wikipedia/commons/c/cd/Br%C3%BCgge-Muntpoort_6-29510-58192.jpg" + } , "WikimediaImageProvider") + + + expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABelgium-5955_-_Simon_Stevin_(13746657193).jpg?width=500&height=400" , { + "image":"File:Belgium-5955_-_Simon_Stevin_(13746657193).jpg" + } , "WikimediaImageProvider") + + expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABelgium-5955_-_Simon_Stevin_(13746657193).jpg?width=500&height=400" , { + "wikimedia_commons":"File:Belgium-5955_-_Simon_Stevin_(13746657193).jpg" + } , "WikimediaImageProvider") + + + + + expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABrugge_Leeuwstraat_zonder_nummer_Leeuwbrug_-_119334_-_onroerenderfgoed.jpg?width=500&height=400",{ + image:"File:Brugge_Leeuwstraat_zonder_nummer_Leeuwbrug_-_119334_-_onroerenderfgoed.jpg" + }, "WikimediaImageProvider") + + + }] + + + ]); + } + +} \ No newline at end of file diff --git a/test/TestAll.ts b/test/TestAll.ts index bdb92afdb..cf1d4d174 100644 --- a/test/TestAll.ts +++ b/test/TestAll.ts @@ -11,6 +11,7 @@ import SplitActionSpec from "./SplitAction.spec"; import {Utils} from "../Utils"; import TileFreshnessCalculatorSpec from "./TileFreshnessCalculator.spec"; import WikidataSpecTest from "./Wikidata.spec.test"; +import ImageProviderSpec from "./ImageProvider.spec"; ScriptUtils.fixUtils() @@ -25,7 +26,8 @@ const allTests = [ new RelationSplitHandlerSpec(), new SplitActionSpec(), new TileFreshnessCalculatorSpec(), - new WikidataSpecTest() + new WikidataSpecTest(), + new ImageProviderSpec() ] Utils.externalDownloadFunction = async (url) => { @@ -44,16 +46,17 @@ args = args.map(a => a.toLowerCase()) const allFailures: { testsuite: string, name: string, msg: string } [] = [] let testsToRun = allTests if (args.length > 0) { - testsToRun = allTests.filter(t => args.indexOf(t.name) >= 0) + args = args.map(a => a.toLowerCase()) + testsToRun = allTests.filter(t => args.indexOf(t.name.toLowerCase()) >= 0) } if (testsToRun.length == 0) { - throw "No tests found" + throw "No tests found. Try one of "+allTests.map(t => t.name).join(", ") } for (let i = 0; i < testsToRun.length; i++) { const test = testsToRun[i]; - console.log(" Running test", i, "/", allTests.length, test.name) + console.log(" Running test", i, "/", testsToRun.length, test.name) allFailures.push(...(test.Run() ?? [])) console.log("OK!") } diff --git a/test/TestHelper.ts b/test/TestHelper.ts index 971b64396..95ea119c4 100644 --- a/test/TestHelper.ts +++ b/test/TestHelper.ts @@ -40,6 +40,14 @@ export default class T { throw "Expected true, but got false: " + msg } } + + static equals(a, b, msg?){ + if(a !== b){ + throw "Not the same: "+(msg??"")+"\n" + + "Expcected: "+a+"\n" + + "Got : "+b + } + } static isFalse(b: boolean, msg: string) { if (b) { From 8d52ef11067bc46f236d1f801fb58c553c715bd9 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 6 Oct 2021 19:19:35 +0200 Subject: [PATCH 07/26] Ignore wikidata claims without datavalue --- Logic/Web/Wikidata.ts | 6 +- test/ImageProvider.spec.ts | 4 + test/Wikidata.spec.test.ts | 1858 +++++++++++++++++++++++++++++++++++- 3 files changed, 1860 insertions(+), 8 deletions(-) diff --git a/Logic/Web/Wikidata.ts b/Logic/Web/Wikidata.ts index f92b419bf..725e8e8ed 100644 --- a/Logic/Web/Wikidata.ts +++ b/Logic/Web/Wikidata.ts @@ -47,8 +47,10 @@ export default class Wikidata { const claimsList: any[] = entity.claims[claimId] const values = new Set() for (const claim of claimsList) { - const value = claim.mainsnak.datavalue.value; - values.add(value) + const value = claim.mainsnak?.datavalueq?.value; + if(value !== undefined){ + values.add(value) + } } claims.set(claimId, values); } diff --git a/test/ImageProvider.spec.ts b/test/ImageProvider.spec.ts index 76e73fc33..97a12d5d1 100644 --- a/test/ImageProvider.spec.ts +++ b/test/ImageProvider.spec.ts @@ -57,6 +57,10 @@ export default class ImageProviderSpec extends T { expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3ABrugge_Leeuwstraat_zonder_nummer_Leeuwbrug_-_119334_-_onroerenderfgoed.jpg?width=500&height=400",{ image:"File:Brugge_Leeuwstraat_zonder_nummer_Leeuwbrug_-_119334_-_onroerenderfgoed.jpg" }, "WikimediaImageProvider") + + expects("https://commons.wikimedia.org/wiki/Special:FilePath/File%3APapageno_Jef_Claerhout.jpg?width=500&height=400",{ + "wikimedia_commons": "File:Papageno_Jef_Claerhout.jpg" + }, "WikimediaImageProvider") }] diff --git a/test/Wikidata.spec.test.ts b/test/Wikidata.spec.test.ts index 000a77217..c6b3e0ac0 100644 --- a/test/Wikidata.spec.test.ts +++ b/test/Wikidata.spec.test.ts @@ -4,7 +4,7 @@ import {equal} from "assert"; import T from "./TestHelper"; import {Utils} from "../Utils"; -export default class WikidataSpecTest extends T { +export default class WikidataSpecTest extends T { constructor() { super("Wikidata", [ @@ -12,8 +12,190 @@ export default class WikidataSpecTest extends T { async () => { Utils.injectJsonDownloadForTests( - "https://www.wikidata.org/wiki/Special:EntityData/Q14517013.json" , - {"entities":{"Q14517013":{"pageid":16187848,"ns":0,"title":"Q14517013","lastrevid":1408823680,"modified":"2021-04-26T07:35:01Z","type":"item","id":"Q14517013","labels":{"nl":{"language":"nl","value":"Vredesmolen"},"en":{"language":"en","value":"Peace Mill"}},"descriptions":{"nl":{"language":"nl","value":"molen in West-Vlaanderen"}},"aliases":{},"claims":{"P625":[{"mainsnak":{"snaktype":"value","property":"P625","hash":"d86538f14e8cca00bbf30fb029829aacbc6903a0","datavalue":{"value":{"latitude":50.99444,"longitude":2.92528,"altitude":null,"precision":0.0001,"globe":"http://www.wikidata.org/entity/Q2"},"type":"globecoordinate"},"datatype":"globe-coordinate"},"type":"statement","id":"Q14517013$DBFBFD69-F54D-4C92-A7F4-A44F876E5776","rank":"normal","references":[{"hash":"732ec1c90a6f0694c7db9a71bf09fe7f2b674172","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"9123b0de1cc9c3954366ba797d598e4e1ea4146f","datavalue":{"value":{"entity-type":"item","numeric-id":10000,"id":"Q10000"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]}],"P17":[{"mainsnak":{"snaktype":"value","property":"P17","hash":"c2859f311753176d6bdfa7da54ceeeac7acb52c8","datavalue":{"value":{"entity-type":"item","numeric-id":31,"id":"Q31"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"Q14517013$C12E4DA5-44E1-41ED-BF3D-C84381246429","rank":"normal"}],"P18":[{"mainsnak":{"snaktype":"value","property":"P18","hash":"af765166ecaa7d01ea800812b5b356886b8849a0","datavalue":{"value":"Klerken Vredesmolen R01.jpg","type":"string"},"datatype":"commonsMedia"},"type":"statement","id":"Q14517013$5291801E-11BE-4CE7-8F42-D0D6A120F390","rank":"normal"}],"P2867":[{"mainsnak":{"snaktype":"value","property":"P2867","hash":"b1c627972ba2cc71e3567d2fb56cb5f90dd64007","datavalue":{"value":"893","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q14517013$2aff9dcd-4d24-cd92-b5af-f6268425695f","rank":"normal"}],"P31":[{"mainsnak":{"snaktype":"value","property":"P31","hash":"9b48263bb51c506553aac2281ae331353b5c9002","datavalue":{"value":{"entity-type":"item","numeric-id":38720,"id":"Q38720"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"Q14517013$46dd9d89-4999-eee6-20a4-c4f6650b1d9c","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P31","hash":"a1d6f3409c57de0361c68263c9397a99dabe19ea","datavalue":{"value":{"entity-type":"item","numeric-id":3851468,"id":"Q3851468"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"Q14517013$C83A8B1F-7798-493A-86C9-EC0EFEE356B3","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P31","hash":"ee5ba9185bdf9f0eb80b52e1cdc70c5883fac95a","datavalue":{"value":{"entity-type":"item","numeric-id":623605,"id":"Q623605"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"Q14517013$CF74DC2E-6814-4755-9BAD-6EE9FEF637DD","rank":"normal"}],"P2671":[{"mainsnak":{"snaktype":"value","property":"P2671","hash":"83fb38a3c6407f7d0d7bb051d1c31cea8ae26975","datavalue":{"value":"/g/121cb15z","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q14517013$E6FFEF32-0131-42FD-9C66-1A406B68059A","rank":"normal"}]},"sitelinks":{"commonswiki":{"site":"commonswiki","title":"Category:Vredesmolen, Klerken","badges":[],"url":"https://commons.wikimedia.org/wiki/Category:Vredesmolen,_Klerken"},"nlwiki":{"site":"nlwiki","title":"Vredesmolen","badges":[],"url":"https://nl.wikipedia.org/wiki/Vredesmolen"}}}}} + "https://www.wikidata.org/wiki/Special:EntityData/Q14517013.json", + { + "entities": { + "Q14517013": { + "pageid": 16187848, + "ns": 0, + "title": "Q14517013", + "lastrevid": 1408823680, + "modified": "2021-04-26T07:35:01Z", + "type": "item", + "id": "Q14517013", + "labels": { + "nl": {"language": "nl", "value": "Vredesmolen"}, + "en": {"language": "en", "value": "Peace Mill"} + }, + "descriptions": {"nl": {"language": "nl", "value": "molen in West-Vlaanderen"}}, + "aliases": {}, + "claims": { + "P625": [{ + "mainsnak": { + "snaktype": "value", + "property": "P625", + "hash": "d86538f14e8cca00bbf30fb029829aacbc6903a0", + "datavalue": { + "value": { + "latitude": 50.99444, + "longitude": 2.92528, + "altitude": null, + "precision": 0.0001, + "globe": "http://www.wikidata.org/entity/Q2" + }, "type": "globecoordinate" + }, + "datatype": "globe-coordinate" + }, + "type": "statement", + "id": "Q14517013$DBFBFD69-F54D-4C92-A7F4-A44F876E5776", + "rank": "normal", + "references": [{ + "hash": "732ec1c90a6f0694c7db9a71bf09fe7f2b674172", + "snaks": { + "P143": [{ + "snaktype": "value", + "property": "P143", + "hash": "9123b0de1cc9c3954366ba797d598e4e1ea4146f", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 10000, + "id": "Q10000" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }] + }, + "snaks-order": ["P143"] + }] + }], + "P17": [{ + "mainsnak": { + "snaktype": "value", + "property": "P17", + "hash": "c2859f311753176d6bdfa7da54ceeeac7acb52c8", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 31, + "id": "Q31" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "id": "Q14517013$C12E4DA5-44E1-41ED-BF3D-C84381246429", + "rank": "normal" + }], + "P18": [{ + "mainsnak": { + "snaktype": "value", + "property": "P18", + "hash": "af765166ecaa7d01ea800812b5b356886b8849a0", + "datavalue": { + "value": "Klerken Vredesmolen R01.jpg", + "type": "string" + }, + "datatype": "commonsMedia" + }, + "type": "statement", + "id": "Q14517013$5291801E-11BE-4CE7-8F42-D0D6A120F390", + "rank": "normal" + }], + "P2867": [{ + "mainsnak": { + "snaktype": "value", + "property": "P2867", + "hash": "b1c627972ba2cc71e3567d2fb56cb5f90dd64007", + "datavalue": {"value": "893", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "id": "Q14517013$2aff9dcd-4d24-cd92-b5af-f6268425695f", + "rank": "normal" + }], + "P31": [{ + "mainsnak": { + "snaktype": "value", + "property": "P31", + "hash": "9b48263bb51c506553aac2281ae331353b5c9002", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 38720, + "id": "Q38720" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "id": "Q14517013$46dd9d89-4999-eee6-20a4-c4f6650b1d9c", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P31", + "hash": "a1d6f3409c57de0361c68263c9397a99dabe19ea", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 3851468, + "id": "Q3851468" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "id": "Q14517013$C83A8B1F-7798-493A-86C9-EC0EFEE356B3", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P31", + "hash": "ee5ba9185bdf9f0eb80b52e1cdc70c5883fac95a", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 623605, + "id": "Q623605" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "id": "Q14517013$CF74DC2E-6814-4755-9BAD-6EE9FEF637DD", + "rank": "normal" + }], + "P2671": [{ + "mainsnak": { + "snaktype": "value", + "property": "P2671", + "hash": "83fb38a3c6407f7d0d7bb051d1c31cea8ae26975", + "datavalue": {"value": "/g/121cb15z", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "id": "Q14517013$E6FFEF32-0131-42FD-9C66-1A406B68059A", + "rank": "normal" + }] + }, + "sitelinks": { + "commonswiki": { + "site": "commonswiki", + "title": "Category:Vredesmolen, Klerken", + "badges": [], + "url": "https://commons.wikimedia.org/wiki/Category:Vredesmolen,_Klerken" + }, + "nlwiki": { + "site": "nlwiki", + "title": "Vredesmolen", + "badges": [], + "url": "https://nl.wikipedia.org/wiki/Vredesmolen" + } + } + } + } + } ) @@ -21,9 +203,1673 @@ export default class WikidataSpecTest extends T { T.isTrue(wdata.wikisites.has("nl"), "dutch for wikisite not found") equal("Vredesmolen", wdata.wikisites.get("nl")) } - - ] + + ], + ["Download Prince", async () => { + + Utils.injectJsonDownloadForTests( + "https://www.wikidata.org/wiki/Special:EntityData/Q2747456.json", + { + "entities": { + "Q2747456": { + "pageid": 2638026, + "ns": 0, + "title": "Q2747456", + "lastrevid": 1507566187, + "modified": "2021-10-03T20:26:12Z", + "type": "item", + "id": "Q2747456", + "labels": { + "nl": {"language": "nl", "value": "prins"}, + "am": {"language": "am", "value": "\u120d\u12d1\u120d"}, + "ar": {"language": "ar", "value": "\u0623\u0645\u064a\u0631"}, + "be": {"language": "be", "value": "\u043f\u0440\u044b\u043d\u0446"}, + "bg": {"language": "bg", "value": "\u043f\u0440\u0438\u043d\u0446"}, + "ca": {"language": "ca", "value": "pr\u00edncep"}, + "cs": {"language": "cs", "value": "princ"}, + "cy": {"language": "cy", "value": "tywysog"}, + "da": {"language": "da", "value": "prins"}, + "de": {"language": "de", "value": "Prinz"}, + "en": {"language": "en", "value": "prince"}, + "eo": {"language": "eo", "value": "princo"}, + "es": {"language": "es", "value": "pr\u00edncipe"}, + "fa": {"language": "fa", "value": "\u0634\u0627\u0647\u0632\u0627\u062f\u0647"}, + "fi": {"language": "fi", "value": "prinssi"}, + "fr": {"language": "fr", "value": "prince"}, + "he": {"language": "he", "value": "\u05e0\u05e1\u05d9\u05da"}, + "hr": {"language": "hr", "value": "princ"}, + "id": {"language": "id", "value": "pangeran"}, + "it": {"language": "it", "value": "principe"}, + "ja": {"language": "ja", "value": "\u30d7\u30ea\u30f3\u30b9"}, + "ka": { + "language": "ka", + "value": "\u10e3\u10e4\u10da\u10d8\u10e1\u10ec\u10e3\u10da\u10d8" + }, + "lv": {"language": "lv", "value": "princis"}, + "ms": {"language": "ms", "value": "putera"}, + "ne": { + "language": "ne", + "value": "\u0930\u093e\u091c\u0915\u0941\u092e\u093e\u0930" + }, + "nn": {"language": "nn", "value": "prins"}, + "pt": {"language": "pt", "value": "pr\u00edncipe"}, + "ro": {"language": "ro", "value": "prin\u021b"}, + "ru": {"language": "ru", "value": "\u043f\u0440\u0438\u043d\u0446"}, + "scn": {"language": "scn", "value": "pr\u00ecncipi"}, + "sk": {"language": "sk", "value": "princ"}, + "sl": {"language": "sl", "value": "princ"}, + "sv": {"language": "sv", "value": "prins"}, + "tr": {"language": "tr", "value": "prens"}, + "uk": {"language": "uk", "value": "\u043f\u0440\u0438\u043d\u0446"}, + "vec": {"language": "vec", "value": "principe"}, + "vi": {"language": "vi", "value": "v\u01b0\u01a1ng"}, + "ko": {"language": "ko", "value": "\uc655\uc790"}, + "th": {"language": "th", "value": "\u0e40\u0e08\u0e49\u0e32"}, + "la": {"language": "la", "value": "princeps"}, + "gl": {"language": "gl", "value": "pr\u00edncipe"}, + "nb": {"language": "nb", "value": "prins"}, + "el": { + "language": "el", + "value": "\u03c0\u03c1\u03af\u03b3\u03ba\u03b9\u03c0\u03b1\u03c2" + }, + "is": {"language": "is", "value": "prins"}, + "pl": {"language": "pl", "value": "ksi\u0105\u017c\u0119 (princeps)"}, + "nan": {"language": "nan", "value": "th\u00e2u-l\u00e2ng"}, + "be-tarask": { + "language": "be-tarask", + "value": "\u043f\u0440\u044b\u043d\u0446" + }, + "ur": {"language": "ur", "value": "\u0634\u06c1\u0632\u0627\u062f\u06c1"}, + "sco": {"language": "sco", "value": "prince"}, + "zh": {"language": "zh", "value": "\u738b\u7235"}, + "sr": {"language": "sr", "value": "\u043f\u0440\u0438\u043d\u0446"}, + "sh": {"language": "sh", "value": "princ"}, + "hy": { + "language": "hy", + "value": "\u0561\u0580\u0584\u0561\u0575\u0561\u0566\u0576" + }, + "et": {"language": "et", "value": "prints"}, + "bxr": { + "language": "bxr", + "value": "\u0445\u0430\u043d \u0445\u04af\u0431\u04af\u04af\u043d" + }, + "fy": {"language": "fy", "value": "prins"}, + "diq": {"language": "diq", "value": "prens"}, + "ba": {"language": "ba", "value": "\u043f\u0440\u0438\u043d\u0446"}, + "eu": {"language": "eu", "value": "printze"}, + "gd": {"language": "gd", "value": "prionnsa"}, + "gu": {"language": "gu", "value": "\u0a95\u0ac1\u0a82\u0ab5\u0ab0"}, + "lb": {"language": "lb", "value": "Pr\u00ebnz"}, + "ga": {"language": "ga", "value": "prionsa"}, + "hu": {"language": "hu", "value": "herceg"}, + "su": {"language": "su", "value": "pang\u00e9ran"}, + "ast": {"language": "ast", "value": "pr\u00edncipe"}, + "rmy": {"language": "rmy", "value": "rayon"}, + "yue": {"language": "yue", "value": "\u89aa\u738b"}, + "jv": {"language": "jv", "value": "pang\u00e9ran"}, + "zh-hant": {"language": "zh-hant", "value": "\u738b\u7235"}, + "se": {"language": "se", "value": "prinsa"}, + "smj": {"language": "smj", "value": "prinssa"}, + "smn": {"language": "smn", "value": "prinss\u00e2"}, + "sms": {"language": "sms", "value": "prinss"}, + "az": {"language": "az", "value": "Prens"}, + "wuu": {"language": "wuu", "value": "\u738b\u7235"}, + "yi": {"language": "yi", "value": "\u05e4\u05e8\u05d9\u05e0\u05e5"} + }, + "descriptions": { + "fr": {"language": "fr", "value": "titre de noblesse"}, + "es": {"language": "es", "value": "t\u00edtulo nobiliario"}, + "en": { + "language": "en", + "value": "son of a prince, king, queen, emperor or empress, or other high-ranking person (such as a grand duke)" + }, + "el": { + "language": "el", + "value": "\u03c4\u03af\u03c4\u03bb\u03bf\u03c2 \u03b5\u03c5\u03b3\u03b5\u03bd\u03b5\u03af\u03b1\u03c2" + }, + "de": { + "language": "de", + "value": "Adels-Titel, m\u00e4nnliches Mitglied der K\u00f6nigsfamilie" + }, + "pl": {"language": "pl", "value": "tytu\u0142 szlachecki"}, + "ca": {"language": "ca", "value": "t\u00edtol de noblesa"}, + "vi": { + "language": "vi", + "value": "con trai c\u1ee7a ho\u00e0ng t\u1eed, vua, ho\u00e0ng h\u1eadu, ho\u00e0ng \u0111\u1ebf, ho\u00e0ng h\u1eadu ho\u1eb7c nh\u1eefng ng\u01b0\u1eddi c\u00f3 \u0111\u1ecba v\u1ecb cao kh\u00e1c" + }, + "da": {"language": "da", "value": "kongelig titel"}, + "eu": {"language": "eu", "value": "noblezia titulu"}, + "hu": {"language": "hu", "value": "nemesi c\u00edm"}, + "zh": {"language": "zh", "value": "\u8cb4\u65cf\u982d\u929c"}, + "ar": { + "language": "ar", + "value": "\u0644\u0642\u0628 \u0646\u0628\u064a\u0644" + }, + "ast": {"language": "ast", "value": "t\u00edtulu de nobleza"}, + "ru": {"language": "ru", "value": "\u0442\u0438\u0442\u0443\u043b"}, + "be-tarask": { + "language": "be-tarask", + "value": "\u0448\u043b\u044f\u0445\u0435\u0446\u043a\u0456 \u0442\u044b\u0442\u0443\u043b" + }, + "zh-hant": {"language": "zh-hant", "value": "\u8cb4\u65cf\u982d\u929c"}, + "it": { + "language": "it", + "value": "figlio di un principe, re, regina, imperatore o imperatrice o altra persona di alto rango (come un granduca)" + }, + "nl": { + "language": "nl", + "value": "zoon van een prins(es), koning(in), keizer(in) of andere persoon met een adellijke rang (zoals een groothertog)" + }, + "ro": { + "language": "ro", + "value": "titlu nobiliar acordat \u00een general membrilor unei familii imperiale, regale, princiare etc." + }, + "lb": {"language": "lb", "value": "Adelstitel"}, + "id": { + "language": "id", + "value": "putra seorang pangeran, raja, ratu, kaisar atau permaisuri, atau orang berpangkat tinggi lainnya (seperti adipati agung)" + }, + "he": { + "language": "he", + "value": "\u05ea\u05d5\u05d0\u05e8 \u05d0\u05e6\u05d5\u05dc\u05d4" + }, + "fi": { + "language": "fi", + "value": "ylh\u00e4isaatelisarvo, monesti monarkin poika" + }, + "cs": { + "language": "cs", + "value": "titul potomka prince/princezny, kn\u00ed\u017eete/kn\u011b\u017eny, (velko)v\u00e9vody/v\u00e9vodkyn\u011b, kr\u00e1le/kr\u00e1lovny \u010di c\u00edsa\u0159e/c\u00edsa\u0159ovny" + }, + "uk": { + "language": "uk", + "value": "\u0434\u0438\u0442\u0438\u043d\u0430 \u043f\u0440\u0438\u043d\u0446\u0430(-\u0435\u0441\u0438), \u043a\u043e\u0440\u043e\u043b\u044f (\u043a\u043e\u0440\u043e\u043b\u0435\u0432\u0438), \u0456\u043d\u043c\u0435\u0440\u0430\u0442\u043e\u0440\u0430(-\u043a\u0438) \u0447\u0438 \u0456\u043d\u0448\u043e\u0457 \u0437\u043d\u0430\u0442\u043d\u043e\u0457 \u043e\u0441\u043e\u0431\u0438" + } + }, + "aliases": { + "es": [{"language": "es", "value": "princesa"}, { + "language": "es", + "value": "principe" + }], + "ru": [{ + "language": "ru", + "value": "\u043f\u0440\u0438\u043d\u0446\u0435\u0441\u0441\u0430" + }, {"language": "ru", "value": "\u0446\u0430\u0440\u0435\u0432\u0438\u0447"}], + "ca": [{"language": "ca", "value": "princesa"}], + "ba": [{ + "language": "ba", + "value": "\u043f\u0440\u0438\u043d\u0446\u0435\u0441\u0441\u0430" + }], + "gu": [{ + "language": "gu", + "value": "\u0aae\u0ab9\u0abe\u0ab0\u0abe\u0a9c \u0a95\u0ac1\u0a82\u0ab5\u0ab0" + }, {"language": "gu", "value": "\u0aae. \u0a95\u0ac1."}, { + "language": "gu", + "value": "\u0a8f\u0aae. \u0a95\u0ac7." + }], + "he": [{"language": "he", "value": "\u05e0\u05e1\u05d9\u05db\u05d4"}], + "de": [{"language": "de", "value": "Prinzessin"}], + "ast": [{"language": "ast", "value": "princesa"}], + "be-tarask": [{ + "language": "be-tarask", + "value": "\u043f\u0440\u044b\u043d\u0446\u044d\u0441\u0430" + }], + "nl": [{"language": "nl", "value": "prinsje"}], + "it": [{"language": "it", "value": "principessa"}], + "se": [{"language": "se", "value": "gonagasb\u00e1rdni"}], + "pl": [{"language": "pl", "value": "ksi\u0105\u017c\u0119"}], + "vi": [{"language": "vi", "value": "v\u01b0\u01a1ng t\u01b0\u1edbc"}], + "cs": [{"language": "cs", "value": "princezna"}] + }, + "claims": { + "P31": [{ + "mainsnak": { + "snaktype": "value", + "property": "P31", + "hash": "a456372c8e6a681381eca31ab0662159db12ab1e", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 355567, + "id": "Q355567" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "id": "q2747456$ff8e76c2-47b8-d2b7-a192-9af298c36c8e", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P31", + "hash": "0ec7ed0637d631867884c8c0553e2de4b90b63ca", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 3320743, + "id": "Q3320743" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "id": "Q2747456$7b3a375d-48d8-18db-12db-9be699a1c34f", + "rank": "normal" + }], + "P910": [{ + "mainsnak": { + "snaktype": "value", + "property": "P910", + "hash": "ee5be4ad914a3f79dc30c6a6ac320404d7b6bf65", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 7214172, + "id": "Q7214172" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "id": "Q2747456$92971E9D-FA6B-4CFA-88C9-91EF27DDE2DC", + "rank": "normal" + }], + "P508": [{ + "mainsnak": { + "snaktype": "value", + "property": "P508", + "hash": "36109efdac97e7f035d386101fb85a397380f9ee", + "datavalue": {"value": "8468", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "id": "Q2747456$cdaad4c5-4ec8-54b2-3dac-4db04f994fda", + "rank": "normal" + }], + "P1001": [{ + "mainsnak": { + "snaktype": "somevalue", + "property": "P1001", + "hash": "be44552ae528f03d39720570854717fa0ebedcef", + "datatype": "wikibase-item" + }, + "type": "statement", + "id": "Q2747456$5eea869d-4f5d-99ee-90bb-471cccbf4b84", + "rank": "normal" + }], + "P373": [{ + "mainsnak": { + "snaktype": "value", + "property": "P373", + "hash": "e766c6be546f129979614c185bb172cd237a626a", + "datavalue": {"value": "Princes", "type": "string"}, + "datatype": "string" + }, + "type": "statement", + "id": "Q2747456$D4EEC77F-1F89-46DA-BD9E-FA15F29B686A", + "rank": "normal", + "references": [{ + "hash": "fa278ebfc458360e5aed63d5058cca83c46134f1", + "snaks": { + "P143": [{ + "snaktype": "value", + "property": "P143", + "hash": "e4f6d9441d0600513c4533c672b5ab472dc73694", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 328, + "id": "Q328" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }] + }, + "snaks-order": ["P143"] + }] + }], + "P2521": [{ + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "3ac9f3b0f1b60d0fbeac8ce587b3f74470a2ea00", + "datavalue": { + "value": {"text": "princesse", "language": "fr"}, + "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$9c9a7d8e-4fea-87b1-0d41-7efd98922665", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "8eef33f2c1e8a583fd498d380838e5f72cc06491", + "datavalue": { + "value": {"text": "princess", "language": "en"}, + "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$e0281f91-4b2c-053b-9900-57d12d7d4211", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "1a86a592d40223b73b7f0686672650d48c997806", + "datavalue": { + "value": {"text": "princino", "language": "eo"}, + "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$1cb248ea-490c-b5f7-b011-06845ccac2b4", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "abbaf9a41f548f9a7c58e38f91db34cb370c876a", + "datavalue": { + "value": {"text": "prinses", "language": "nl"}, + "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$1d636ed1-4f4d-0851-ca7f-66c847e7c4be", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "37efe8398a055d9ace75c625cdc286b9aadb5ab0", + "datavalue": { + "value": {"text": "princesa", "language": "ca"}, + "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$316855ff-4047-0ffb-76fb-90057b0840ef", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "7810d8cabaaaeb41fad675cd9c3bfb39ab41d00f", + "datavalue": { + "value": { + "text": "\u043f\u0440\u0438\u043d\u0446\u0435\u0441\u0441\u0430", + "language": "ru" + }, "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$fa60cb7b-460d-c8ff-b99c-c2bf515b12a0", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "e18f093988121762e3b247104eb626501d14ad2e", + "datavalue": { + "value": { + "text": "\u05e0\u05e1\u05d9\u05db\u05d4", + "language": "he" + }, "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$03851c85-4db0-ff39-7608-1dc63852b6c8", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "3f8c2d8b4e28c17d49cc1bff30990657e0ab485a", + "datavalue": { + "value": { + "text": "n\u1eef v\u01b0\u01a1ng", + "language": "vi" + }, "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$6115764d-4391-6997-ecb2-7768f18b2b45", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "106d96fa708baf606b060bdc8c6b545f477eee32", + "datavalue": { + "value": {"text": "Prinzessin", "language": "de"}, + "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$6f2c129e-413c-dead-3404-146368643ab8", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "69a2a841f26ab197dca7c5a6e2dd595b67e4188c", + "datavalue": { + "value": { + "text": "\u03c0\u03c1\u03b9\u03b3\u03ba\u03af\u03c0\u03b9\u03c3\u03c3\u03b1", + "language": "el" + }, "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$9b901d48-4e41-ba93-344e-299c69a27ac6", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "560ecce28fcadaf0e2b8a584519fe94ffbf25ec1", + "datavalue": { + "value": {"text": "princesa", "language": "ast"}, + "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$520756e7-476d-a435-bc1c-0a56fa7851a1", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "44f2eb3f4fee6f4b4b3b992407bda0f6caed2536", + "datavalue": { + "value": {"text": "tywysoges", "language": "cy"}, + "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$698beb10-4e2c-b535-a89b-e29210f2be75", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "006e13a77c798832882c84070fe8f76cdc48611c", + "datavalue": { + "value": { + "text": "\u0623\u0645\u064a\u0631\u0629", + "language": "ar" + }, "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$b75e51e5-48e5-1f4c-d99c-d83dde03e91d", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "25eb24e42c0a566023ceb354777cb1ec14492ef1", + "datavalue": { + "value": { + "text": "\u043f\u0440\u044b\u043d\u0446\u044d\u0441\u0430", + "language": "be-tarask" + }, "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$075f0038-475e-e4ba-9801-52aac2067799", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "e72b1dd598ce40db3f7e9b195a3e9345b4ae4ba5", + "datavalue": { + "value": {"text": "princezna", "language": "cs"}, + "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$1085cbb9-4cd4-8a2f-a4c7-6f29fafea206", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "70d88bc577587e2732cf37a66dfd0920b175211a", + "datavalue": { + "value": {"text": "prinsesse", "language": "da"}, + "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$33d2e452-4ca2-8dea-4f98-242c53ef1811", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "eebf786f7c2b0963b9db4c2876bb24c6afc4ce1c", + "datavalue": { + "value": {"text": "principessa", "language": "it"}, + "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$3098804a-4758-d07f-8443-24ebe96c56ec", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P2521", + "hash": "649307549f96bfe54f16e9130f014bf018cc46c4", + "datavalue": { + "value": { + "text": "\u043f\u0440\u0438\u043d\u0446\u0435\u0441\u0430", + "language": "uk" + }, "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$ff433d7c-4e07-f7c0-14af-3b3f31f8ae9a", + "rank": "normal" + }], + "P3827": [{ + "mainsnak": { + "snaktype": "value", + "property": "P3827", + "hash": "22ee9c46325acd0a1ca54f27bff5d75331211f8a", + "datavalue": {"value": "princes", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "id": "Q2747456$6C64B5EA-8B74-4BF6-BB90-81C28320200A", + "rank": "normal" + }], + "P1343": [{ + "mainsnak": { + "snaktype": "value", + "property": "P1343", + "hash": "eda63bed5c3d7a3460033092338ab321a2374c7f", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 2041543, + "id": "Q2041543" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "qualifiers": { + "P805": [{ + "snaktype": "value", + "property": "P805", + "hash": "a83263a5d43ce3636971eac0d25071e09746ed50", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 23858844, + "id": "Q23858844" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }] + }, + "qualifiers-order": ["P805"], + "id": "Q2747456$BC72E96E-6B05-4437-97F4-2BC0AC5DFA6D", + "rank": "normal", + "references": [{ + "hash": "c454383fe86a434f02006970b5c8b8f3f9b6714d", + "snaks": { + "P3452": [{ + "snaktype": "value", + "property": "P3452", + "hash": "482b5f23c034bd9eb5565e3869de4856bd9d5311", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 23858844, + "id": "Q23858844" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }] + }, + "snaks-order": ["P3452"] + }] + }, { + "mainsnak": { + "snaktype": "value", + "property": "P1343", + "hash": "d5011798f92464584d8ccfc5f19f18f3659668bb", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 106727050, + "id": "Q106727050" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "qualifiers": { + "P1810": [{ + "snaktype": "value", + "property": "P1810", + "hash": "03c80cb894e30b3c675b60c14a8c96334cbb474c", + "datavalue": {"value": "Princes", "type": "string"}, + "datatype": "string" + }], + "P585": [{ + "snaktype": "value", + "property": "P585", + "hash": "ffb837135313cad3b2545c4b9ce5ee416deda3e2", + "datavalue": { + "value": { + "time": "+2021-05-07T00:00:00Z", + "timezone": 0, + "before": 0, + "after": 0, + "precision": 11, + "calendarmodel": "http://www.wikidata.org/entity/Q1985727" + }, "type": "time" + }, + "datatype": "time" + }] + }, + "qualifiers-order": ["P1810", "P585"], + "id": "Q2747456$D6FEFF9B-75B5-4D37-B4CE-4DB70C6254C9", + "rank": "normal" + }], + "P1889": [{ + "mainsnak": { + "snaktype": "value", + "property": "P1889", + "hash": "6999c7ae15eaea290cccb76ffdd06bc0677d0238", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 18244, + "id": "Q18244" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "id": "Q2747456$F24DA145-D17F-4574-AA66-6985CB25F420", + "rank": "normal" + }], + "P460": [{ + "mainsnak": { + "snaktype": "value", + "property": "P460", + "hash": "6615255f4b0abf58e9bbf71279496fb1a0b511fa", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 863048, + "id": "Q863048" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "id": "Q2747456$838f53a3-4fd7-a6b9-48bd-ee70d9e91dc1", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P460", + "hash": "5f65f50d44d2a5b28655dc0b966f518e2106d3e1", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 147925, + "id": "Q147925" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "id": "Q2747456$4c67b4d9-4a6f-dfe4-65c1-3aa104506737", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P460", + "hash": "2a1ef20476a8fa0d78b0bdfcdb34c88a72e4424f", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 11572959, + "id": "Q11572959" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "id": "Q2747456$14b54a7e-4c22-fae3-81b2-1bd50ebca9e3", + "rank": "normal" + }], + "P2924": [{ + "mainsnak": { + "snaktype": "value", + "property": "P2924", + "hash": "5fd70a45453598d8cbd3f35682444dffb93ef183", + "datavalue": {"value": "3167678", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "id": "Q2747456$D2F12FF3-B07F-408D-BAD1-87F8666ADBA6", + "rank": "normal" + }], + "P1417": [{ + "mainsnak": { + "snaktype": "value", + "property": "P1417", + "hash": "b55bafafbccecce645f2a5f3ccfe4f1a93d5c797", + "datavalue": {"value": "topic/prince-title", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "id": "Q2747456$3825CF57-55DE-4718-90B4-79DED5864AC4", + "rank": "normal" + }], + "P4212": [{ + "mainsnak": { + "snaktype": "value", + "property": "P4212", + "hash": "18175f20026e3c7967427cbf8230be7b80ba428b", + "datavalue": {"value": "pcrtSqFZmJvcTu", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "id": "Q2747456$9791794A-44F1-4FC2-BA56-BA56D2B3578A", + "rank": "normal" + }], + "P279": [{ + "mainsnak": { + "snaktype": "value", + "property": "P279", + "hash": "05fb47e9bcde5c8dc864b788fbcab6eece27147b", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 2478141, + "id": "Q2478141" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "id": "Q2747456$d68be51e-4bef-c388-920f-c76313d767a4", + "rank": "normal" + }], + "P6573": [{ + "mainsnak": { + "snaktype": "value", + "property": "P6573", + "hash": "a3dd889f664f66353f3bdc1217a652bf779f0882", + "datavalue": {"value": "Prinz", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "id": "Q2747456$6DCF9C3D-9898-4C78-A58F-FDC8400CCCA1", + "rank": "normal" + }], + "P3321": [{ + "mainsnak": { + "snaktype": "value", + "property": "P3321", + "hash": "83853e4f2ae83443c17c417de86f13d7adf2c6de", + "datavalue": { + "value": { + "text": "\u0623\u0645\u064a\u0631", + "language": "ar" + }, "type": "monolingualtext" + }, + "datatype": "monolingualtext" + }, + "type": "statement", + "id": "Q2747456$e5768817-48a9-44bc-637e-2137393ea3ff", + "rank": "normal" + }], + "P244": [{ + "mainsnak": { + "snaktype": "value", + "property": "P244", + "hash": "3484a6a7868e031d3d479ecf0dd02abd5ad5df67", + "datavalue": {"value": "sh85106721", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "id": "Q2747456$2BEAAB19-60A8-4B69-85B2-80E522D88798", + "rank": "normal", + "references": [{ + "hash": "ac5d47e9fbcc281bc0d27a205ae02e22ad24ce31", + "snaks": { + "P854": [{ + "snaktype": "value", + "property": "P854", + "hash": "b560dc6b281a39d061e189d2eb299a426a06f1a2", + "datavalue": { + "value": "https://github.com/JohnMarkOckerbloom/ftl/blob/master/data/wikimap", + "type": "string" + }, + "datatype": "url" + }], + "P813": [{ + "snaktype": "value", + "property": "P813", + "hash": "0dcf4f64e93fdcc654e2c7534285881fe48b9f3d", + "datavalue": { + "value": { + "time": "+2019-04-03T00:00:00Z", + "timezone": 0, + "before": 0, + "after": 0, + "precision": 11, + "calendarmodel": "http://www.wikidata.org/entity/Q1985727" + }, "type": "time" + }, + "datatype": "time" + }] + }, + "snaks-order": ["P854", "P813"] + }] + }], + "P7033": [{ + "mainsnak": { + "snaktype": "value", + "property": "P7033", + "hash": "bbeb07d3dd6a36a1b4ff44294353090777d3f68f", + "datavalue": {"value": "scot/9663", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "id": "Q2747456$7D6E3549-7ABD-43B0-BCF2-572F271FBE61", + "rank": "normal" + }], + "P6404": [{ + "mainsnak": { + "snaktype": "value", + "property": "P6404", + "hash": "b73a884b2dbc4d181d68748eb0a1369a60b6779a", + "datavalue": {"value": "principe", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "qualifiers": { + "P1810": [{ + "snaktype": "value", + "property": "P1810", + "hash": "aa57b954447e129789c598d135f12a17358aecac", + "datavalue": {"value": "principe", "type": "string"}, + "datatype": "string" + }], + "P577": [{ + "snaktype": "value", + "property": "P577", + "hash": "d2a40d22655021267a9386d3086e000722b5a2d3", + "datavalue": { + "value": { + "time": "+2011-01-01T00:00:00Z", + "timezone": 0, + "before": 0, + "after": 0, + "precision": 9, + "calendarmodel": "http://www.wikidata.org/entity/Q1985727" + }, "type": "time" + }, + "datatype": "time" + }] + }, + "qualifiers-order": ["P1810", "P577"], + "id": "Q2747456$B0237EEF-F865-48E1-B40C-6078B365CA08", + "rank": "normal" + }], + "P1245": [{ + "mainsnak": { + "snaktype": "value", + "property": "P1245", + "hash": "96bd0f2ac61d64e0c7f70fc77dbc936887d30178", + "datavalue": {"value": "5814", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "id": "Q2747456$CA27EF8B-8DE0-4B3D-98F2-2ED0857103E3", + "rank": "normal" + }], + "P487": [{ + "mainsnak": { + "snaktype": "value", + "property": "P487", + "hash": "14725f4cf317ce7d4b1a0e750232b59d06b5072c", + "datavalue": {"value": "\ud83e\udd34", "type": "string"}, + "datatype": "string" + }, + "type": "statement", + "id": "Q2747456$1df4cace-4275-e6a6-0c5a-edd013874f47", + "rank": "normal" + }], + "P8408": [{ + "mainsnak": { + "snaktype": "value", + "property": "P8408", + "hash": "1959b085f955100ebf2128c228f5a48c527b3066", + "datavalue": {"value": "Prince", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "id": "Q2747456$DE4D8776-C78F-4ECC-A2AB-FF4C3C605B3D", + "rank": "normal", + "references": [{ + "hash": "9a681f9dd95c90224547c404e11295f4f7dcf54e", + "snaks": { + "P248": [{ + "snaktype": "value", + "property": "P248", + "hash": "9d5780dddffa8746637a9929a936ab6b0f601e24", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 64139102, + "id": "Q64139102" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }], + "P813": [{ + "snaktype": "value", + "property": "P813", + "hash": "622a5a27fa5b25e7e7984974e9db494cf8460990", + "datavalue": { + "value": { + "time": "+2020-07-09T00:00:00Z", + "timezone": 0, + "before": 0, + "after": 0, + "precision": 11, + "calendarmodel": "http://www.wikidata.org/entity/Q1985727" + }, "type": "time" + }, + "datatype": "time" + }] + }, + "snaks-order": ["P248", "P813"] + }] + }], + "P646": [{ + "mainsnak": { + "snaktype": "value", + "property": "P646", + "hash": "e2a702b2c25f7f56f203253d626302e897f59a8e", + "datavalue": {"value": "/m/0dl76", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "id": "Q2747456$C85A80F8-BBE5-4036-B390-FE2D440662CE", + "rank": "normal" + }], + "P9486": [{ + "mainsnak": { + "snaktype": "value", + "property": "P9486", + "hash": "8112e14818e95883f0df779234ffa2b5bd7544ef", + "datavalue": {"value": "2114", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "id": "Q2747456$03DF860D-8766-4A8E-BA39-CA20E7748101", + "rank": "normal" + }], + "P268": [{ + "mainsnak": { + "snaktype": "value", + "property": "P268", + "hash": "6c26a220e139d739b090f743a20ceec3b2b13d36", + "datavalue": {"value": "11934545s", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "qualifiers": { + "P1810": [{ + "snaktype": "value", + "property": "P1810", + "hash": "03c80cb894e30b3c675b60c14a8c96334cbb474c", + "datavalue": {"value": "Princes", "type": "string"}, + "datatype": "string" + }] + }, + "qualifiers-order": ["P1810"], + "id": "Q2747456$58ba630c-6458-4a5a-8913-a294e6124d7b", + "rank": "normal", + "references": [{ + "hash": "7c27b83b9977dcc1e39904c165117c33f6d4d258", + "snaks": { + "P248": [{ + "snaktype": "value", + "property": "P248", + "hash": "3b090a7bae73c288393b2c8b9846cc7ed9a58f91", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 16583225, + "id": "Q16583225" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }], + "P854": [{ + "snaktype": "value", + "property": "P854", + "hash": "42ed86952731f89f4c99b0a5091aa580a24bf41f", + "datavalue": { + "value": "https://thes.bncf.firenze.sbn.it/termine.php?id=8468", + "type": "string" + }, + "datatype": "url" + }], + "P813": [{ + "snaktype": "value", + "property": "P813", + "hash": "fa626481f5288f46170160e657d94c0b692e3140", + "datavalue": { + "value": { + "time": "+2021-06-13T00:00:00Z", + "timezone": 0, + "before": 0, + "after": 0, + "precision": 11, + "calendarmodel": "http://www.wikidata.org/entity/Q1985727" + }, "type": "time" + }, + "datatype": "time" + }] + }, + "snaks-order": ["P248", "P854", "P813"] + }] + }], + "P950": [{ + "mainsnak": { + "snaktype": "value", + "property": "P950", + "hash": "cffc5e803a428e4e1c294de58122f1d3ed126bcd", + "datavalue": {"value": "XX542448", "type": "string"}, + "datatype": "external-id" + }, + "type": "statement", + "qualifiers": { + "P1810": [{ + "snaktype": "value", + "property": "P1810", + "hash": "c1ce0e3e614f65130d263d0a08d806a912624221", + "datavalue": {"value": "Pr\u00edncipes", "type": "string"}, + "datatype": "string" + }] + }, + "qualifiers-order": ["P1810"], + "id": "Q2747456$c8094f9b-d4b1-4050-9be0-252f7a070d8b", + "rank": "normal", + "references": [{ + "hash": "7c27b83b9977dcc1e39904c165117c33f6d4d258", + "snaks": { + "P248": [{ + "snaktype": "value", + "property": "P248", + "hash": "3b090a7bae73c288393b2c8b9846cc7ed9a58f91", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 16583225, + "id": "Q16583225" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }], + "P854": [{ + "snaktype": "value", + "property": "P854", + "hash": "42ed86952731f89f4c99b0a5091aa580a24bf41f", + "datavalue": { + "value": "https://thes.bncf.firenze.sbn.it/termine.php?id=8468", + "type": "string" + }, + "datatype": "url" + }], + "P813": [{ + "snaktype": "value", + "property": "P813", + "hash": "fa626481f5288f46170160e657d94c0b692e3140", + "datavalue": { + "value": { + "time": "+2021-06-13T00:00:00Z", + "timezone": 0, + "before": 0, + "after": 0, + "precision": 11, + "calendarmodel": "http://www.wikidata.org/entity/Q1985727" + }, "type": "time" + }, + "datatype": "time" + }] + }, + "snaks-order": ["P248", "P854", "P813"] + }] + }], + "P527": [{ + "mainsnak": { + "snaktype": "value", + "property": "P527", + "hash": "1f078eae805dfe58ac01a303b2a5474a99df8a48", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 28495701, + "id": "Q28495701" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "id": "Q2747456$6a3b7447-4721-18a4-578e-97af51eeb4a5", + "rank": "normal" + }, { + "mainsnak": { + "snaktype": "value", + "property": "P527", + "hash": "168b349e75ce98b28c0f65998a2fe2d2f1e0f7f5", + "datavalue": { + "value": { + "entity-type": "item", + "numeric-id": 3403409, + "id": "Q3403409" + }, "type": "wikibase-entityid" + }, + "datatype": "wikibase-item" + }, + "type": "statement", + "id": "Q2747456$d2253d2b-4584-2367-122e-557303f41540", + "rank": "normal" + }] + }, + "sitelinks": { + "amwiki": { + "site": "amwiki", + "title": "\u120d\u12d1\u120d", + "badges": [], + "url": "https://am.wikipedia.org/wiki/%E1%88%8D%E1%8B%91%E1%88%8D" + }, + "arwiki": { + "site": "arwiki", + "title": "\u0623\u0645\u064a\u0631 (\u0644\u0642\u0628)", + "badges": [], + "url": "https://ar.wikipedia.org/wiki/%D8%A3%D9%85%D9%8A%D8%B1_(%D9%84%D9%82%D8%A8)" + }, + "astwiki": { + "site": "astwiki", + "title": "Pr\u00edncipe", + "badges": [], + "url": "https://ast.wikipedia.org/wiki/Pr%C3%ADncipe" + }, + "azwiki": { + "site": "azwiki", + "title": "Prens", + "badges": [], + "url": "https://az.wikipedia.org/wiki/Prens" + }, + "be_x_oldwiki": { + "site": "be_x_oldwiki", + "title": "\u041f\u0440\u044b\u043d\u0446", + "badges": [], + "url": "https://be-tarask.wikipedia.org/wiki/%D0%9F%D1%80%D1%8B%D0%BD%D1%86" + }, + "bewiki": { + "site": "bewiki", + "title": "\u041f\u0440\u044b\u043d\u0446", + "badges": [], + "url": "https://be.wikipedia.org/wiki/%D0%9F%D1%80%D1%8B%D0%BD%D1%86" + }, + "bgwiki": { + "site": "bgwiki", + "title": "\u041f\u0440\u0438\u043d\u0446", + "badges": [], + "url": "https://bg.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BD%D1%86" + }, + "bxrwiki": { + "site": "bxrwiki", + "title": "\u0425\u0430\u043d \u0445\u04af\u0431\u04af\u04af\u043d", + "badges": [], + "url": "https://bxr.wikipedia.org/wiki/%D0%A5%D0%B0%D0%BD_%D1%85%D2%AF%D0%B1%D2%AF%D2%AF%D0%BD" + }, + "cawiki": { + "site": "cawiki", + "title": "Pr\u00edncep", + "badges": [], + "url": "https://ca.wikipedia.org/wiki/Pr%C3%ADncep" + }, + "cswiki": { + "site": "cswiki", + "title": "Princ", + "badges": [], + "url": "https://cs.wikipedia.org/wiki/Princ" + }, + "cywiki": { + "site": "cywiki", + "title": "Tywysog", + "badges": [], + "url": "https://cy.wikipedia.org/wiki/Tywysog" + }, + "dawiki": { + "site": "dawiki", + "title": "Prins", + "badges": [], + "url": "https://da.wikipedia.org/wiki/Prins" + }, + "dewiki": { + "site": "dewiki", + "title": "Prinz", + "badges": [], + "url": "https://de.wikipedia.org/wiki/Prinz" + }, + "dewikiquote": { + "site": "dewikiquote", + "title": "Prinz", + "badges": [], + "url": "https://de.wikiquote.org/wiki/Prinz" + }, + "diqwiki": { + "site": "diqwiki", + "title": "Prens", + "badges": [], + "url": "https://diq.wikipedia.org/wiki/Prens" + }, + "elwiki": { + "site": "elwiki", + "title": "\u03a0\u03c1\u03af\u03b3\u03ba\u03b9\u03c0\u03b1\u03c2", + "badges": [], + "url": "https://el.wikipedia.org/wiki/%CE%A0%CF%81%CE%AF%CE%B3%CE%BA%CE%B9%CF%80%CE%B1%CF%82" + }, + "enwiki": { + "site": "enwiki", + "title": "Prince", + "badges": [], + "url": "https://en.wikipedia.org/wiki/Prince" + }, + "enwikiquote": { + "site": "enwikiquote", + "title": "Prince", + "badges": [], + "url": "https://en.wikiquote.org/wiki/Prince" + }, + "eowiki": { + "site": "eowiki", + "title": "Princo", + "badges": [], + "url": "https://eo.wikipedia.org/wiki/Princo" + }, + "eswiki": { + "site": "eswiki", + "title": "Pr\u00edncipe", + "badges": [], + "url": "https://es.wikipedia.org/wiki/Pr%C3%ADncipe" + }, + "etwiki": { + "site": "etwiki", + "title": "Prints (j\u00e4reltulija)", + "badges": [], + "url": "https://et.wikipedia.org/wiki/Prints_(j%C3%A4reltulija)" + }, + "etwikiquote": { + "site": "etwikiquote", + "title": "Prints", + "badges": [], + "url": "https://et.wikiquote.org/wiki/Prints" + }, + "euwiki": { + "site": "euwiki", + "title": "Printze", + "badges": [], + "url": "https://eu.wikipedia.org/wiki/Printze" + }, + "fawiki": { + "site": "fawiki", + "title": "\u0634\u0627\u0647\u0632\u0627\u062f\u0647", + "badges": [], + "url": "https://fa.wikipedia.org/wiki/%D8%B4%D8%A7%D9%87%D8%B2%D8%A7%D8%AF%D9%87" + }, + "fiwiki": { + "site": "fiwiki", + "title": "Prinssi", + "badges": [], + "url": "https://fi.wikipedia.org/wiki/Prinssi" + }, + "frwiki": { + "site": "frwiki", + "title": "Prince (dignit\u00e9)", + "badges": [], + "url": "https://fr.wikipedia.org/wiki/Prince_(dignit%C3%A9)" + }, + "fywiki": { + "site": "fywiki", + "title": "Prins", + "badges": [], + "url": "https://fy.wikipedia.org/wiki/Prins" + }, + "gawiki": { + "site": "gawiki", + "title": "Prionsa", + "badges": [], + "url": "https://ga.wikipedia.org/wiki/Prionsa" + }, + "glwiki": { + "site": "glwiki", + "title": "Pr\u00edncipe", + "badges": [], + "url": "https://gl.wikipedia.org/wiki/Pr%C3%ADncipe" + }, + "hewiki": { + "site": "hewiki", + "title": "\u05e0\u05e1\u05d9\u05da", + "badges": [], + "url": "https://he.wikipedia.org/wiki/%D7%A0%D7%A1%D7%99%D7%9A" + }, + "hewikiquote": { + "site": "hewikiquote", + "title": "\u05e0\u05e1\u05d9\u05da", + "badges": [], + "url": "https://he.wikiquote.org/wiki/%D7%A0%D7%A1%D7%99%D7%9A" + }, + "hrwiki": { + "site": "hrwiki", + "title": "Princ", + "badges": [], + "url": "https://hr.wikipedia.org/wiki/Princ" + }, + "idwiki": { + "site": "idwiki", + "title": "Pangeran", + "badges": [], + "url": "https://id.wikipedia.org/wiki/Pangeran" + }, + "iswiki": { + "site": "iswiki", + "title": "Prins", + "badges": [], + "url": "https://is.wikipedia.org/wiki/Prins" + }, + "itwiki": { + "site": "itwiki", + "title": "Principe", + "badges": [], + "url": "https://it.wikipedia.org/wiki/Principe" + }, + "itwikiquote": { + "site": "itwikiquote", + "title": "Principe", + "badges": [], + "url": "https://it.wikiquote.org/wiki/Principe" + }, + "jawiki": { + "site": "jawiki", + "title": "\u30d7\u30ea\u30f3\u30b9", + "badges": [], + "url": "https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AA%E3%83%B3%E3%82%B9" + }, + "jvwiki": { + "site": "jvwiki", + "title": "Pang\u00e9ran", + "badges": [], + "url": "https://jv.wikipedia.org/wiki/Pang%C3%A9ran" + }, + "kawiki": { + "site": "kawiki", + "title": "\u10e3\u10e4\u10da\u10d8\u10e1\u10ec\u10e3\u10da\u10d8", + "badges": [], + "url": "https://ka.wikipedia.org/wiki/%E1%83%A3%E1%83%A4%E1%83%9A%E1%83%98%E1%83%A1%E1%83%AC%E1%83%A3%E1%83%9A%E1%83%98" + }, + "kowiki": { + "site": "kowiki", + "title": "\ud504\ub9b0\uc2a4", + "badges": [], + "url": "https://ko.wikipedia.org/wiki/%ED%94%84%EB%A6%B0%EC%8A%A4" + }, + "lawiki": { + "site": "lawiki", + "title": "Princeps", + "badges": [], + "url": "https://la.wikipedia.org/wiki/Princeps" + }, + "lawikiquote": { + "site": "lawikiquote", + "title": "Princeps", + "badges": [], + "url": "https://la.wikiquote.org/wiki/Princeps" + }, + "lvwiki": { + "site": "lvwiki", + "title": "Princis", + "badges": [], + "url": "https://lv.wikipedia.org/wiki/Princis" + }, + "mswiki": { + "site": "mswiki", + "title": "Putera", + "badges": [], + "url": "https://ms.wikipedia.org/wiki/Putera" + }, + "newiki": { + "site": "newiki", + "title": "\u0930\u093e\u091c\u0915\u0941\u092e\u093e\u0930", + "badges": [], + "url": "https://ne.wikipedia.org/wiki/%E0%A4%B0%E0%A4%BE%E0%A4%9C%E0%A4%95%E0%A5%81%E0%A4%AE%E0%A4%BE%E0%A4%B0" + }, + "nlwiki": { + "site": "nlwiki", + "title": "Prins", + "badges": [], + "url": "https://nl.wikipedia.org/wiki/Prins" + }, + "nnwiki": { + "site": "nnwiki", + "title": "Prins", + "badges": [], + "url": "https://nn.wikipedia.org/wiki/Prins" + }, + "nowiki": { + "site": "nowiki", + "title": "Prins", + "badges": [], + "url": "https://no.wikipedia.org/wiki/Prins" + }, + "plwiki": { + "site": "plwiki", + "title": "Ksi\u0105\u017c\u0119", + "badges": [], + "url": "https://pl.wikipedia.org/wiki/Ksi%C4%85%C5%BC%C4%99" + }, + "plwikiquote": { + "site": "plwikiquote", + "title": "Ksi\u0105\u017c\u0119", + "badges": [], + "url": "https://pl.wikiquote.org/wiki/Ksi%C4%85%C5%BC%C4%99" + }, + "ptwiki": { + "site": "ptwiki", + "title": "Pr\u00edncipe", + "badges": [], + "url": "https://pt.wikipedia.org/wiki/Pr%C3%ADncipe" + }, + "ptwikiquote": { + "site": "ptwikiquote", + "title": "Pr\u00edncipe", + "badges": [], + "url": "https://pt.wikiquote.org/wiki/Pr%C3%ADncipe" + }, + "rmywiki": { + "site": "rmywiki", + "title": "Rayon", + "badges": [], + "url": "https://rmy.wikipedia.org/wiki/Rayon" + }, + "rowiki": { + "site": "rowiki", + "title": "Prin\u021b", + "badges": [], + "url": "https://ro.wikipedia.org/wiki/Prin%C8%9B" + }, + "ruwiki": { + "site": "ruwiki", + "title": "\u041f\u0440\u0438\u043d\u0446", + "badges": [], + "url": "https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BD%D1%86" + }, + "scnwiki": { + "site": "scnwiki", + "title": "Pr\u00ecncipi", + "badges": [], + "url": "https://scn.wikipedia.org/wiki/Pr%C3%ACncipi" + }, + "scowiki": { + "site": "scowiki", + "title": "Prince", + "badges": [], + "url": "https://sco.wikipedia.org/wiki/Prince" + }, + "shwiki": { + "site": "shwiki", + "title": "Princ", + "badges": [], + "url": "https://sh.wikipedia.org/wiki/Princ" + }, + "simplewiki": { + "site": "simplewiki", + "title": "Prince", + "badges": [], + "url": "https://simple.wikipedia.org/wiki/Prince" + }, + "skwiki": { + "site": "skwiki", + "title": "Princ", + "badges": [], + "url": "https://sk.wikipedia.org/wiki/Princ" + }, + "slwiki": { + "site": "slwiki", + "title": "Princ", + "badges": [], + "url": "https://sl.wikipedia.org/wiki/Princ" + }, + "srwiki": { + "site": "srwiki", + "title": "Princ", + "badges": [], + "url": "https://sr.wikipedia.org/wiki/Princ" + }, + "suwiki": { + "site": "suwiki", + "title": "Pang\u00e9ran", + "badges": [], + "url": "https://su.wikipedia.org/wiki/Pang%C3%A9ran" + }, + "svwiki": { + "site": "svwiki", + "title": "Prins", + "badges": [], + "url": "https://sv.wikipedia.org/wiki/Prins" + }, + "thwiki": { + "site": "thwiki", + "title": "\u0e40\u0e08\u0e49\u0e32", + "badges": [], + "url": "https://th.wikipedia.org/wiki/%E0%B9%80%E0%B8%88%E0%B9%89%E0%B8%B2" + }, + "trwiki": { + "site": "trwiki", + "title": "Prens", + "badges": [], + "url": "https://tr.wikipedia.org/wiki/Prens" + }, + "ukwiki": { + "site": "ukwiki", + "title": "\u041f\u0440\u0438\u043d\u0446", + "badges": [], + "url": "https://uk.wikipedia.org/wiki/%D0%9F%D1%80%D0%B8%D0%BD%D1%86" + }, + "urwiki": { + "site": "urwiki", + "title": "\u0634\u06c1\u0632\u0627\u062f\u06c1", + "badges": [], + "url": "https://ur.wikipedia.org/wiki/%D8%B4%DB%81%D8%B2%D8%A7%D8%AF%DB%81" + }, + "vecwiki": { + "site": "vecwiki", + "title": "Principe", + "badges": [], + "url": "https://vec.wikipedia.org/wiki/Principe" + }, + "viwiki": { + "site": "viwiki", + "title": "V\u01b0\u01a1ng t\u01b0\u1edbc", + "badges": [], + "url": "https://vi.wikipedia.org/wiki/V%C6%B0%C6%A1ng_t%C6%B0%E1%BB%9Bc" + }, + "wuuwiki": { + "site": "wuuwiki", + "title": "\u738b\u7235", + "badges": [], + "url": "https://wuu.wikipedia.org/wiki/%E7%8E%8B%E7%88%B5" + }, + "zh_min_nanwiki": { + "site": "zh_min_nanwiki", + "title": "Prince", + "badges": [], + "url": "https://zh-min-nan.wikipedia.org/wiki/Prince" + }, + "zh_yuewiki": { + "site": "zh_yuewiki", + "title": "\u89aa\u738b", + "badges": [], + "url": "https://zh-yue.wikipedia.org/wiki/%E8%A6%AA%E7%8E%8B" + }, + "zhwiki": { + "site": "zhwiki", + "title": "\u738b\u7235", + "badges": [], + "url": "https://zh.wikipedia.org/wiki/%E7%8E%8B%E7%88%B5" + } + } + } + } + } + ) + + const wikidata = await Wikidata.LoadWikidataEntryAsync("2747456") + }] ]); } - + } \ No newline at end of file From a996ba2a7c6d12b6bb71cc6d8d40e45cc173edf6 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Thu, 7 Oct 2021 22:06:47 +0200 Subject: [PATCH 08/26] Graciously handle multiple entries in wikidata for fetching images and showing articles, verious bug fixes --- Logic/ImageProviders/ImageProvider.ts | 69 ++++++----- Logic/ImageProviders/LicenseInfo.ts | 1 + .../ImageProviders/WikimediaImageProvider.ts | 16 ++- Logic/Web/Wikidata.ts | 2 +- Logic/Web/Wikipedia.ts | 11 ++ UI/Base/TabbedComponent.ts | 16 ++- UI/BigComponents/FullWelcomePaneWithTabs.ts | 3 + UI/Image/Attribution.ts | 5 +- UI/SpecialVisualizations.ts | 11 +- UI/WikipediaBox.ts | 115 ++++++++++++------ css/index-tailwind-output.css | 50 +++++--- css/tabbedComponent.css | 2 +- index.css | 4 + test/Wikidata.spec.test.ts | 16 +++ 14 files changed, 231 insertions(+), 90 deletions(-) diff --git a/Logic/ImageProviders/ImageProvider.ts b/Logic/ImageProviders/ImageProvider.ts index be3d58ce5..1dd38c2b7 100644 --- a/Logic/ImageProviders/ImageProvider.ts +++ b/Logic/ImageProviders/ImageProvider.ts @@ -1,17 +1,20 @@ import {UIEventSource} from "../UIEventSource"; import BaseUIElement from "../../UI/BaseUIElement"; import {LicenseInfo} from "./LicenseInfo"; +import {Utils} from "../../Utils"; export interface ProvidedImage { - url: string, key: string, provider: ImageProvider + url: string, + key: string, + provider: ImageProvider } export default abstract class ImageProvider { - - public abstract readonly defaultKeyPrefixes : string[] = ["mapillary", "image"] - + + public abstract readonly defaultKeyPrefixes: string[] = ["mapillary", "image"] + private _cache = new Map>() - + GetAttributionFor(url: string): UIEventSource { const cached = this._cache.get(url); if (cached !== undefined) { @@ -31,43 +34,49 @@ export default abstract class ImageProvider { */ public GetRelevantUrls(allTags: UIEventSource, options?: { prefixes?: string[] - }):UIEventSource { + }): UIEventSource { const prefixes = options?.prefixes ?? this.defaultKeyPrefixes - if(prefixes === undefined){ - throw "The image provider"+this.constructor.name+" doesn't define `defaultKeyPrefixes`" + if (prefixes === undefined) { + throw "The image provider" + this.constructor.name + " doesn't define `defaultKeyPrefixes`" } const relevantUrls = new UIEventSource<{ url: string; key: string; provider: ImageProvider }[]>([]) const seenValues = new Set() - const self = this + const self =this allTags.addCallbackAndRunD(tags => { for (const key in tags) { - if(!prefixes.some(prefix => key.startsWith(prefix))){ + if (!prefixes.some(prefix => key.startsWith(prefix))) { continue } - const value = tags[key] - if(seenValues.has(value)){ - continue - } - seenValues.add(value) - this.ExtractUrls(key, value).then(promises => { - for (const promise of promises ?? []) { - if(promise === undefined){ - continue - } - promise.then(providedImage => { - if(providedImage === undefined){ - return - } - relevantUrls.data.push(providedImage) - relevantUrls.ping() - }) + const values = Utils.NoEmpty(tags[key]?.split(";")?.map(v => v.trim()) ?? []) + for (const value of values) { + + if (seenValues.has(value)) { + continue } - }) + seenValues.add(value) + this.ExtractUrls(key, value).then(promises => { + console.log("Got ", promises.length, "promises for", value,"by",self.constructor.name) + for (const promise of promises ?? []) { + if (promise === undefined) { + continue + } + promise.then(providedImage => { + if (providedImage === undefined) { + return + } + relevantUrls.data.push(providedImage) + relevantUrls.ping() + }) + } + }) + } + + } }) return relevantUrls } - public abstract ExtractUrls(key: string, value: string) : Promise[]>; - + public abstract ExtractUrls(key: string, value: string): Promise[]>; + } \ No newline at end of file diff --git a/Logic/ImageProviders/LicenseInfo.ts b/Logic/ImageProviders/LicenseInfo.ts index b5954693c..b295af1d4 100644 --- a/Logic/ImageProviders/LicenseInfo.ts +++ b/Logic/ImageProviders/LicenseInfo.ts @@ -1,4 +1,5 @@ export class LicenseInfo { + title: string = "" artist: string = ""; license: string = ""; licenseShortName: string = ""; diff --git a/Logic/ImageProviders/WikimediaImageProvider.ts b/Logic/ImageProviders/WikimediaImageProvider.ts index a00df6719..3dc6fca08 100644 --- a/Logic/ImageProviders/WikimediaImageProvider.ts +++ b/Logic/ImageProviders/WikimediaImageProvider.ts @@ -65,12 +65,26 @@ export class WikimediaImageProvider extends ImageProvider { "&format=json&origin=*"; const data = await Utils.downloadJson(url) const licenseInfo = new LicenseInfo(); - const license = (data.query.pages[-1].imageinfo ?? [])[0]?.extmetadata; + const pageInfo = data.query.pages[-1] + if(pageInfo === undefined){ + return undefined; + } + + const license = (pageInfo.imageinfo ?? [])[0]?.extmetadata; if (license === undefined) { console.warn("The file", filename ,"has no usable metedata or license attached... Please fix the license info file yourself!") return undefined; } + let title = pageInfo.title + if(title.startsWith("File:")){ + title= title.substr("File:".length) + } + if(title.endsWith(".jpg") || title.endsWith(".png")){ + title = title.substring(0, title.length - 4) + } + + licenseInfo.title = title licenseInfo.artist = license.Artist?.value; licenseInfo.license = license.License?.value; licenseInfo.copyrighted = license.Copyrighted?.value; diff --git a/Logic/Web/Wikidata.ts b/Logic/Web/Wikidata.ts index 725e8e8ed..b05ba9cc1 100644 --- a/Logic/Web/Wikidata.ts +++ b/Logic/Web/Wikidata.ts @@ -47,7 +47,7 @@ export default class Wikidata { const claimsList: any[] = entity.claims[claimId] const values = new Set() for (const claim of claimsList) { - const value = claim.mainsnak?.datavalueq?.value; + const value = claim.mainsnak?.datavalue?.value; if(value !== undefined){ values.add(value) } diff --git a/Logic/Web/Wikipedia.ts b/Logic/Web/Wikipedia.ts index dedfa144d..703346bd3 100644 --- a/Logic/Web/Wikipedia.ts +++ b/Logic/Web/Wikipedia.ts @@ -22,6 +22,10 @@ export default class Wikipedia { "mw-selflink", "hatnote" // Often redirects ] + + private static readonly idsToRemove = [ + "sjabloon_zie" + ] private static readonly _cache = new Map>() @@ -59,6 +63,13 @@ export default class Wikipedia { } } + for (const forbiddenId of Wikipedia.idsToRemove) { + const toRemove = content.querySelector("#"+forbiddenId) + toRemove?.parentElement?.removeChild(toRemove) + } + + + const links = Array.from(content.getElementsByTagName("a")) // Rewrite relative links to absolute links + open them in a new tab diff --git a/UI/Base/TabbedComponent.ts b/UI/Base/TabbedComponent.ts index 8f71a462a..f911c0b41 100644 --- a/UI/Base/TabbedComponent.ts +++ b/UI/Base/TabbedComponent.ts @@ -6,11 +6,16 @@ import {VariableUiElement} from "./VariableUIElement"; export class TabbedComponent extends Combine { - constructor(elements: { header: BaseUIElement | string, content: BaseUIElement | string }[], openedTab: (UIEventSource | number) = 0) { + constructor(elements: { header: BaseUIElement | string, content: BaseUIElement | string }[], + openedTab: (UIEventSource | number) = 0, + options?: { + leftOfHeader?: BaseUIElement + styleHeader?: (header: BaseUIElement) => void + }) { const openedTabSrc = typeof (openedTab) === "number" ? new UIEventSource(openedTab) : (openedTab ?? new UIEventSource(0)) - const tabs: BaseUIElement[] = [] + const tabs: BaseUIElement[] = [options?.leftOfHeader ] const contentElements: BaseUIElement[] = []; for (let i = 0; i < elements.length; i++) { let element = elements[i]; @@ -25,16 +30,19 @@ export class TabbedComponent extends Combine { } }) const content = Translations.W(element.content) - content.SetClass("relative p-4 w-full inline-block") + content.SetClass("relative w-full inline-block") contentElements.push(content); const tab = header.SetClass("block tab-single-header") tabs.push(tab) } const header = new Combine(tabs).SetClass("tabs-header-bar") + if(options?.styleHeader){ + options.styleHeader(header) + } const actualContent = new VariableUiElement( openedTabSrc.map(i => contentElements[i]) - ) + ).SetStyle("max-height: inherit; height: inherit") super([header, actualContent]) } diff --git a/UI/BigComponents/FullWelcomePaneWithTabs.ts b/UI/BigComponents/FullWelcomePaneWithTabs.ts index 8ee36ecec..3978bd310 100644 --- a/UI/BigComponents/FullWelcomePaneWithTabs.ts +++ b/UI/BigComponents/FullWelcomePaneWithTabs.ts @@ -73,6 +73,9 @@ export default class FullWelcomePaneWithTabs extends ScrollableFullScreen { } ); + tabs.forEach(c => c.content.SetClass("p-4")) + tabsWithAboutMc.forEach(c => c.content.SetClass("p-4")) + return new Toggle( new TabbedComponent(tabsWithAboutMc, State.state.welcomeMessageOpenedTab), new TabbedComponent(tabs, State.state.welcomeMessageOpenedTab), diff --git a/UI/Image/Attribution.ts b/UI/Image/Attribution.ts index f57911e93..713b228c6 100644 --- a/UI/Image/Attribution.ts +++ b/UI/Image/Attribution.ts @@ -21,10 +21,11 @@ export default class Attribution extends VariableUiElement { icon?.SetClass("block left").SetStyle("height: 2em; width: 2em; padding-right: 0.5em;"), new Combine([ - Translations.W(license?.artist ?? ".").SetClass("block font-bold"), + Translations.W(license?.title).SetClass("block"), + Translations.W(license?.artist ?? "").SetClass("block font-bold"), Translations.W((license?.license ?? "") === "" ? "CC0" : (license?.license ?? "")) ]).SetClass("flex flex-col") - ]).SetClass("flex flex-row bg-black text-white text-sm absolute bottom-0 left-0 p-0.5 pl-5 pr-3 rounded-lg") + ]).SetClass("flex flex-row bg-black text-white text-sm absolute bottom-0 left-0 p-0.5 pl-5 pr-3 rounded-lg no-images") })); } diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index d4c4ea2cc..3444bd5f2 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -100,7 +100,16 @@ export default class SpecialVisualizations { ], example: "`{wikipedia()}` is a basic example, `{wikipedia(name:etymology:wikidata)}` to show the wikipedia page of whom the feature was named after. Also remember that these can be styled, e.g. `{wikipedia():max-height: 10rem}` to limit the height", constr: (_, tagsSource, args) => - new WikipediaBox( tagsSource.map(tags => tags[args[0]])) + new VariableUiElement( + tagsSource.map(tags => tags[args[0]]) + .map(wikidata => { + const wikidatas : string[] = + Utils.NoEmpty(wikidata?.split(";")?.map(wd => wd.trim()) ?? []) + return new WikipediaBox(wikidatas) + }) + + ) + }, { funcName: "minimap", diff --git a/UI/WikipediaBox.ts b/UI/WikipediaBox.ts index 4b0f08d4f..5c3554aeb 100644 --- a/UI/WikipediaBox.ts +++ b/UI/WikipediaBox.ts @@ -10,27 +10,73 @@ import Translations from "./i18n/Translations"; import Svg from "../Svg"; import Wikidata, {WikidataResponse} from "../Logic/Web/Wikidata"; import Locale from "./i18n/Locale"; -import Toggle from "./Input/Toggle"; import Link from "./Base/Link"; +import {TabbedComponent} from "./Base/TabbedComponent"; -export default class WikipediaBox extends Toggle { +export default class WikipediaBox extends Combine { - constructor(wikidataId: string | UIEventSource) { - const wp = Translations.t.general.wikipedia; - if (typeof wikidataId === "string") { - wikidataId = new UIEventSource(wikidataId) + constructor(wikidataIds: string[]) { + + const mainContents = [] + + const pages = wikidataIds.map(wdId => WikipediaBox.createLinkedContent(wdId)) + if (wikidataIds.length == 1) { + const page = pages[0] + mainContents.push( + new Combine([ + new Combine([Svg.wikipedia_ui() + .SetStyle("width: 1.5rem").SetClass("inline-block mr-3"), page.titleElement]) + .SetClass("flex"), + page.linkElement + ]).SetClass("flex justify-between align-middle"), + ) + mainContents.push(page.contents) + } else if (wikidataIds.length > 1) { + + const tabbed = new TabbedComponent( + pages.map(page => { + const contents = page.contents.SetClass("block").SetStyle("max-height: inherit; height: inherit; padding-bottom: 3.3rem") + return { + header: page.titleElement.SetClass("pl-2 pr-2"), + content: new Combine([ + page.linkElement + .SetStyle("top: 2rem; right: 2.5rem;") + .SetClass("absolute subtle-background rounded-full p-3 opacity-50 hover:opacity-100 transition-opacity"), + contents + ]).SetStyle("max-height: inherit; height: inherit").SetClass("relative") + } + + }), + 0, + { + leftOfHeader: Svg.wikipedia_ui().SetStyle("width: 1.5rem; align-self: center;").SetClass("mr-4"), + styleHeader: header => header.SetClass("subtle-background").SetStyle("height: 3.3rem") + } + ) + tabbed.SetStyle("height: inherit; max-height: inherit; overflow: hidden") + mainContents.push(tabbed) + } + super(mainContents) + + + this.SetClass("block rounded-xl subtle-background m-1 p-2 flex flex-col") + .SetStyle("max-height: inherit") + } + + private static createLinkedContent(wikidataId: string): { + titleElement: BaseUIElement, + contents: BaseUIElement, + linkElement: BaseUIElement + } { + + const wp = Translations.t.general.wikipedia; + const wikiLink: UIEventSource<[string, string] | "loading" | "failed" | "no page"> = - wikidataId - .bind(id => { - if (id === undefined) { - return undefined - } - return Wikidata.LoadWikidataEntry(id); - }) + Wikidata.LoadWikidataEntry(wikidataId) .map(maybewikidata => { if (maybewikidata === undefined) { return "loading" @@ -72,38 +118,39 @@ export default class WikipediaBox extends Toggle { const [pagetitle, language] = status return WikipediaBox.createContents(pagetitle, language) - + }) ).SetClass("overflow-auto normal-background rounded-lg") - const linkElement = new VariableUiElement(wikiLink.map(state => { + const titleElement = new VariableUiElement(wikiLink.map(state => { if (typeof state !== "string") { const [pagetitle, language] = state - const url= `https://${language}.wikipedia.org/wiki/${pagetitle}` + return new Title(pagetitle, 3) + } + //return new Title(Translations.t.general.wikipedia.wikipediaboxTitle.Clone(), 2) + return new Title(wikidataId,3) + + })) + + const linkElement = new VariableUiElement(wikiLink.map(state => { + if (typeof state !== "string") { + const [pagetitle, language] = state + const url = `https://${language}.wikipedia.org/wiki/${pagetitle}` return new Link(Svg.pop_out_ui().SetStyle("width: 1.2rem").SetClass("block "), url, true) } - return undefined})) - .SetClass("flex items-center") + return undefined + })) + .SetClass("flex items-center") - const mainContent = new Combine([ - new Combine([ - new Combine([ - Svg.wikipedia_ui().SetStyle("width: 1.5rem").SetClass("mr-3"), - new Title(Translations.t.general.wikipedia.wikipediaboxTitle.Clone(), 2), - ]).SetClass("flex"), - - linkElement - ]).SetClass("flex justify-between"), - contents]).SetClass("block rounded-xl subtle-background m-1 p-2 flex flex-col") - .SetStyle("max-height: inherit") - super( - mainContent, - undefined, - wikidataId.map(id => id !== undefined) - ) + return { + contents: contents, + linkElement: linkElement, + titleElement: titleElement + } } + /** * Returns the actual content in a scrollable way * @param pagename diff --git a/css/index-tailwind-output.css b/css/index-tailwind-output.css index 054952756..b51496b0f 100644 --- a/css/index-tailwind-output.css +++ b/css/index-tailwind-output.css @@ -852,14 +852,14 @@ video { margin-right: 0.75rem; } -.mb-2 { - margin-bottom: 0.5rem; -} - .mr-4 { margin-right: 1rem; } +.mb-2 { + margin-bottom: 0.5rem; +} + .mt-3 { margin-top: 0.75rem; } @@ -1251,14 +1251,14 @@ video { border-radius: 0.25rem; } -.rounded-lg { - border-radius: 0.5rem; -} - .rounded-xl { border-radius: 0.75rem; } +.rounded-lg { + border-radius: 0.5rem; +} + .border { border-width: 1px; } @@ -1386,6 +1386,14 @@ video { padding: 0px; } +.pl-2 { + padding-left: 0.5rem; +} + +.pr-2 { + padding-right: 0.5rem; +} + .pl-6 { padding-left: 1.5rem; } @@ -1394,10 +1402,6 @@ video { padding-top: 0.5rem; } -.pl-2 { - padding-left: 0.5rem; -} - .pt-3 { padding-top: 0.75rem; } @@ -1458,10 +1462,6 @@ video { padding-top: 0px; } -.pr-2 { - padding-right: 0.5rem; -} - .text-center { text-align: center; } @@ -1582,6 +1582,10 @@ video { text-decoration: underline; } +.opacity-50 { + opacity: 0.5; +} + .opacity-0 { opacity: 0; } @@ -1628,6 +1632,12 @@ video { transition-duration: 150ms; } +.transition-opacity { + transition-property: opacity; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + .\!transition { transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter !important; transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter !important; @@ -1788,6 +1798,10 @@ svg, img { height: 100%; } +.no-images img { + display: none; +} + .mapcontrol svg path { fill: var(--subtle-detail-color-contrast) !important; } @@ -2189,6 +2203,10 @@ li::marker { color: rgba(30, 64, 175, var(--tw-text-opacity)); } +.hover\:opacity-100:hover { + opacity: 1; +} + .hover\:shadow-xl:hover { --tw-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); diff --git a/css/tabbedComponent.css b/css/tabbedComponent.css index d47b20548..2096eac05 100644 --- a/css/tabbedComponent.css +++ b/css/tabbedComponent.css @@ -8,7 +8,7 @@ justify-content: flex-start; align-items: start; background-color: var(--background-color); - max-width: 100vw; + max-width: 100%; overflow-x: auto; } diff --git a/index.css b/index.css index d5cd06476..8660c1ba3 100644 --- a/index.css +++ b/index.css @@ -93,6 +93,10 @@ svg, img { height: 100%; } +.no-images img { + display: none; +} + .mapcontrol svg path { fill: var(--subtle-detail-color-contrast) !important; } diff --git a/test/Wikidata.spec.test.ts b/test/Wikidata.spec.test.ts index c6b3e0ac0..1bc6a8558 100644 --- a/test/Wikidata.spec.test.ts +++ b/test/Wikidata.spec.test.ts @@ -8,6 +8,19 @@ export default class WikidataSpecTest extends T { constructor() { super("Wikidata", [ + ["Download Lion", async () => { + + Utils.injectJsonDownloadForTests( + "https://www.wikidata.org/wiki/Special:EntityData/Q140.json" , + WikidataSpecTest.Q140 + ) + + + const wikidata = await Wikidata.LoadWikidataEntryAsync("Q140") + T.equals(2, wikidata.claims.get("P18").size) + + + }], ["download wikidata", async () => { @@ -1869,7 +1882,10 @@ export default class WikidataSpecTest extends T { const wikidata = await Wikidata.LoadWikidataEntryAsync("2747456") }] + ]); } + + private static Q140 = {"entities":{"Q140":{"pageid":275,"ns":0,"title":"Q140","lastrevid":1503881580,"modified":"2021-09-26T19:53:55Z","type":"item","id":"Q140","labels":{"fr":{"language":"fr","value":"lion"},"it":{"language":"it","value":"leone"},"nb":{"language":"nb","value":"l\u00f8ve"},"ru":{"language":"ru","value":"\u043b\u0435\u0432"},"de":{"language":"de","value":"L\u00f6we"},"es":{"language":"es","value":"le\u00f3n"},"nn":{"language":"nn","value":"l\u00f8ve"},"da":{"language":"da","value":"l\u00f8ve"},"af":{"language":"af","value":"leeu"},"ar":{"language":"ar","value":"\u0623\u0633\u062f"},"bg":{"language":"bg","value":"\u043b\u044a\u0432"},"bn":{"language":"bn","value":"\u09b8\u09bf\u0982\u09b9"},"br":{"language":"br","value":"leon"},"bs":{"language":"bs","value":"lav"},"ca":{"language":"ca","value":"lle\u00f3"},"cs":{"language":"cs","value":"lev"},"el":{"language":"el","value":"\u03bb\u03b9\u03bf\u03bd\u03c4\u03ac\u03c1\u03b9"},"fi":{"language":"fi","value":"leijona"},"ga":{"language":"ga","value":"leon"},"gl":{"language":"gl","value":"Le\u00f3n"},"gu":{"language":"gu","value":"\u0ab8\u0abf\u0a82\u0ab9"},"he":{"language":"he","value":"\u05d0\u05e8\u05d9\u05d4"},"hi":{"language":"hi","value":"\u0938\u093f\u0902\u0939"},"hu":{"language":"hu","value":"oroszl\u00e1n"},"id":{"language":"id","value":"Singa"},"ja":{"language":"ja","value":"\u30e9\u30a4\u30aa\u30f3"},"ko":{"language":"ko","value":"\uc0ac\uc790"},"mk":{"language":"mk","value":"\u043b\u0430\u0432"},"ml":{"language":"ml","value":"\u0d38\u0d3f\u0d02\u0d39\u0d02"},"mr":{"language":"mr","value":"\u0938\u093f\u0902\u0939"},"my":{"language":"my","value":"\u1001\u103c\u1004\u103a\u1039\u101e\u1031\u1037"},"ne":{"language":"ne","value":"\u0938\u093f\u0902\u0939"},"nl":{"language":"nl","value":"leeuw"},"pl":{"language":"pl","value":"lew afryka\u0144ski"},"pt":{"language":"pt","value":"le\u00e3o"},"pt-br":{"language":"pt-br","value":"le\u00e3o"},"scn":{"language":"scn","value":"liuni"},"sq":{"language":"sq","value":"Luani"},"sr":{"language":"sr","value":"\u043b\u0430\u0432"},"sw":{"language":"sw","value":"simba"},"ta":{"language":"ta","value":"\u0b9a\u0bbf\u0b99\u0bcd\u0b95\u0bae\u0bcd"},"te":{"language":"te","value":"\u0c38\u0c3f\u0c02\u0c39\u0c02"},"th":{"language":"th","value":"\u0e2a\u0e34\u0e07\u0e42\u0e15"},"tr":{"language":"tr","value":"aslan"},"uk":{"language":"uk","value":"\u043b\u0435\u0432"},"vi":{"language":"vi","value":"s\u01b0 t\u1eed"},"zh":{"language":"zh","value":"\u7345\u5b50"},"sco":{"language":"sco","value":"lion"},"zh-hant":{"language":"zh-hant","value":"\u7345\u5b50"},"fa":{"language":"fa","value":"\u0634\u06cc\u0631"},"zh-hans":{"language":"zh-hans","value":"\u72ee\u5b50"},"ee":{"language":"ee","value":"Dzata"},"ilo":{"language":"ilo","value":"leon"},"ksh":{"language":"ksh","value":"L\u00f6hv"},"zh-hk":{"language":"zh-hk","value":"\u7345\u5b50"},"as":{"language":"as","value":"\u09b8\u09bf\u0982\u09b9"},"zh-cn":{"language":"zh-cn","value":"\u72ee\u5b50"},"zh-mo":{"language":"zh-mo","value":"\u7345\u5b50"},"zh-my":{"language":"zh-my","value":"\u72ee\u5b50"},"zh-sg":{"language":"zh-sg","value":"\u72ee\u5b50"},"zh-tw":{"language":"zh-tw","value":"\u7345\u5b50"},"ast":{"language":"ast","value":"lle\u00f3n"},"sat":{"language":"sat","value":"\u1c61\u1c5f\u1c74\u1c5f\u1c60\u1c69\u1c5e"},"bho":{"language":"bho","value":"\u0938\u093f\u0902\u0939"},"en":{"language":"en","value":"lion"},"ks":{"language":"ks","value":"\u067e\u0627\u062f\u064e\u0631 \u0633\u0655\u06c1\u06c1"},"be-tarask":{"language":"be-tarask","value":"\u043b\u0435\u045e"},"nan":{"language":"nan","value":"Sai"},"la":{"language":"la","value":"leo"},"en-ca":{"language":"en-ca","value":"Lion"},"en-gb":{"language":"en-gb","value":"lion"},"ab":{"language":"ab","value":"\u0410\u043b\u044b\u043c"},"am":{"language":"am","value":"\u12a0\u1295\u1260\u1233"},"an":{"language":"an","value":"Panthera leo"},"ang":{"language":"ang","value":"L\u0113o"},"arc":{"language":"arc","value":"\u0710\u072a\u071d\u0710"},"arz":{"language":"arz","value":"\u0633\u0628\u0639"},"av":{"language":"av","value":"\u0413\u044a\u0430\u043b\u0431\u0430\u0446\u04c0"},"az":{"language":"az","value":"\u015eir"},"ba":{"language":"ba","value":"\u0410\u0440\u044b\u04ab\u043b\u0430\u043d"},"be":{"language":"be","value":"\u043b\u0435\u045e"},"bo":{"language":"bo","value":"\u0f66\u0f7a\u0f44\u0f0b\u0f42\u0f7a\u0f0d"},"bpy":{"language":"bpy","value":"\u09a8\u0982\u09b8\u09be"},"bxr":{"language":"bxr","value":"\u0410\u0440\u0441\u0430\u043b\u0430\u043d"},"ce":{"language":"ce","value":"\u041b\u043e\u043c"},"chr":{"language":"chr","value":"\u13e2\u13d3\u13e5 \u13a4\u13cd\u13c6\u13b4\u13c2"},"chy":{"language":"chy","value":"P\u00e9hpe'\u00e9nan\u00f3se'hame"},"ckb":{"language":"ckb","value":"\u0634\u06ce\u0631"},"co":{"language":"co","value":"Lionu"},"csb":{"language":"csb","value":"Lew"},"cu":{"language":"cu","value":"\u041b\u044c\u0432\u044a"},"cv":{"language":"cv","value":"\u0410\u0440\u0103\u0441\u043b\u0430\u043d"},"cy":{"language":"cy","value":"Llew"},"dsb":{"language":"dsb","value":"law"},"eo":{"language":"eo","value":"leono"},"et":{"language":"et","value":"l\u00f5vi"},"eu":{"language":"eu","value":"lehoi"},"fo":{"language":"fo","value":"leyvur"},"frr":{"language":"frr","value":"l\u00f6\u00f6w"},"gag":{"language":"gag","value":"aslan"},"gd":{"language":"gd","value":"le\u00f2mhann"},"gn":{"language":"gn","value":"Le\u00f5"},"got":{"language":"got","value":"\ud800\udf3b\ud800\udf39\ud800\udf45\ud800\udf30/Liwa"},"ha":{"language":"ha","value":"Zaki"},"hak":{"language":"hak","value":"S\u1e73\u0302-\u00e9"},"haw":{"language":"haw","value":"Liona"},"hif":{"language":"hif","value":"Ser"},"hr":{"language":"hr","value":"lav"},"hsb":{"language":"hsb","value":"law"},"ht":{"language":"ht","value":"Lyon"},"hy":{"language":"hy","value":"\u0561\u057c\u0575\u0578\u0582\u056e"},"ia":{"language":"ia","value":"Panthera leo"},"ig":{"language":"ig","value":"Od\u00fam"},"io":{"language":"io","value":"leono"},"is":{"language":"is","value":"lj\u00f3n"},"jbo":{"language":"jbo","value":"cinfo"},"jv":{"language":"jv","value":"Singa"},"ka":{"language":"ka","value":"\u10da\u10dd\u10db\u10d8"},"kab":{"language":"kab","value":"Izem"},"kbd":{"language":"kbd","value":"\u0425\u044c\u044d\u0449"},"kg":{"language":"kg","value":"Nkosi"},"kk":{"language":"kk","value":"\u0410\u0440\u044b\u0441\u0442\u0430\u043d"},"kn":{"language":"kn","value":"\u0cb8\u0cbf\u0c82\u0cb9"},"ku":{"language":"ku","value":"\u015e\u00ear"},"lb":{"language":"lb","value":"L\u00e9iw"},"lbe":{"language":"lbe","value":"\u0410\u0441\u043b\u0430\u043d"},"lez":{"language":"lez","value":"\u0410\u0441\u043b\u0430\u043d"},"li":{"language":"li","value":"Liew"},"lij":{"language":"lij","value":"Lion"},"ln":{"language":"ln","value":"Nk\u0254\u0301si"},"lt":{"language":"lt","value":"li\u016btas"},"ltg":{"language":"ltg","value":"\u013bovs"},"lv":{"language":"lv","value":"lauva"},"mdf":{"language":"mdf","value":"\u041e\u0440\u043a\u0441\u043e\u0444\u0442\u0430"},"mhr":{"language":"mhr","value":"\u0410\u0440\u044b\u0441\u043b\u0430\u043d"},"mn":{"language":"mn","value":"\u0410\u0440\u0441\u043b\u0430\u043d"},"mrj":{"language":"mrj","value":"\u0410\u0440\u044b\u0441\u043b\u0430\u043d"},"ms":{"language":"ms","value":"Singa"},"mt":{"language":"mt","value":"iljun"},"nah":{"language":"nah","value":"Cu\u0101miztli"},"nrm":{"language":"nrm","value":"lion"},"su":{"language":"su","value":"Singa"},"de-ch":{"language":"de-ch","value":"L\u00f6we"},"ky":{"language":"ky","value":"\u0410\u0440\u0441\u0442\u0430\u043d"},"lmo":{"language":"lmo","value":"Panthera leo"},"ceb":{"language":"ceb","value":"Panthera leo"},"diq":{"language":"diq","value":"\u015e\u00ear"},"new":{"language":"new","value":"\u0938\u093f\u0902\u0939"},"nds":{"language":"nds","value":"L\u00f6\u00f6w"},"ak":{"language":"ak","value":"Gyata"},"cdo":{"language":"cdo","value":"S\u0103i"},"ady":{"language":"ady","value":"\u0410\u0441\u043b\u044a\u0430\u043d"},"azb":{"language":"azb","value":"\u0622\u0633\u0644\u0627\u0646"},"lfn":{"language":"lfn","value":"Leon"},"kbp":{"language":"kbp","value":"T\u0254\u0254y\u028b\u028b"},"gsw":{"language":"gsw","value":"L\u00f6we"},"din":{"language":"din","value":"K\u00f6r"},"inh":{"language":"inh","value":"\u041b\u043e\u043c"},"bm":{"language":"bm","value":"Waraba"},"hyw":{"language":"hyw","value":"\u0531\u057c\u056b\u0582\u056e"},"nds-nl":{"language":"nds-nl","value":"leeuw"},"kw":{"language":"kw","value":"Lew"},"ext":{"language":"ext","value":"Le\u00f3n"},"bcl":{"language":"bcl","value":"Leon"},"mg":{"language":"mg","value":"Liona"},"lld":{"language":"lld","value":"Lion"},"lzh":{"language":"lzh","value":"\u7345"},"ary":{"language":"ary","value":"\u0633\u0628\u0639"},"sv":{"language":"sv","value":"lejon"},"nso":{"language":"nso","value":"Tau"},"nv":{"language":"nv","value":"N\u00e1shd\u00f3\u00edtsoh bitsiij\u012f\u02bc dadit\u0142\u02bcoo\u00edg\u00ed\u00ed"},"oc":{"language":"oc","value":"panthera leo"},"or":{"language":"or","value":"\u0b38\u0b3f\u0b02\u0b39"},"os":{"language":"os","value":"\u0426\u043e\u043c\u0430\u0445\u044a"},"pa":{"language":"pa","value":"\u0a38\u0a3c\u0a47\u0a30"},"pam":{"language":"pam","value":"Leon"},"pcd":{"language":"pcd","value":"Lion"},"pms":{"language":"pms","value":"Lion"},"pnb":{"language":"pnb","value":"\u0628\u0628\u0631 \u0634\u06cc\u0631"},"ps":{"language":"ps","value":"\u0632\u0645\u0631\u06cc"},"qu":{"language":"qu","value":"Liyun"},"rn":{"language":"rn","value":"Intare"},"ro":{"language":"ro","value":"Leul"},"sl":{"language":"sl","value":"lev"},"sn":{"language":"sn","value":"Shumba"},"so":{"language":"so","value":"Libaax"},"ss":{"language":"ss","value":"Libubesi"},"st":{"language":"st","value":"Tau"},"stq":{"language":"stq","value":"Leeuwe"},"sr-ec":{"language":"sr-ec","value":"\u043b\u0430\u0432"},"sr-el":{"language":"sr-el","value":"lav"},"rm":{"language":"rm","value":"Liun"},"sm":{"language":"sm","value":"Leona"},"tcy":{"language":"tcy","value":"\u0cb8\u0cbf\u0cae\u0ccd\u0cae"},"szl":{"language":"szl","value":"Lew"},"rue":{"language":"rue","value":"\u041b\u0435\u0432"},"rw":{"language":"rw","value":"Intare"},"sah":{"language":"sah","value":"\u0425\u0430\u0445\u0430\u0439"},"sh":{"language":"sh","value":"Lav"},"sk":{"language":"sk","value":"lev p\u00fa\u0161\u0165ov\u00fd"},"tg":{"language":"tg","value":"\u0428\u0435\u0440"},"ti":{"language":"ti","value":"\u12a3\u1295\u1260\u1233"},"tl":{"language":"tl","value":"Leon"},"tum":{"language":"tum","value":"Nkhalamu"},"udm":{"language":"udm","value":"\u0410\u0440\u044b\u0441\u043b\u0430\u043d"},"ug":{"language":"ug","value":"\u0634\u0649\u0631"},"ur":{"language":"ur","value":"\u0628\u0628\u0631"},"vec":{"language":"vec","value":"Leon"},"vep":{"language":"vep","value":"lev"},"vls":{"language":"vls","value":"l\u00eaeuw"},"war":{"language":"war","value":"leon"},"wo":{"language":"wo","value":"gaynde"},"xal":{"language":"xal","value":"\u0410\u0440\u0441\u043b\u04a3"},"xmf":{"language":"xmf","value":"\u10dc\u10ef\u10d8\u10da\u10dd"},"yi":{"language":"yi","value":"\u05dc\u05d9\u05d9\u05d1"},"yo":{"language":"yo","value":"K\u00ecn\u00ec\u00fan"},"yue":{"language":"yue","value":"\u7345\u5b50"},"zu":{"language":"zu","value":"ibhubesi"},"tk":{"language":"tk","value":"\u00ddolbars"},"tt":{"language":"tt","value":"\u0430\u0440\u044b\u0441\u043b\u0430\u043d"},"uz":{"language":"uz","value":"Arslon"},"se":{"language":"se","value":"Ledjon"},"si":{"language":"si","value":"\u0dc3\u0dd2\u0d82\u0dc4\u0dba\u0dcf"},"sgs":{"language":"sgs","value":"Li\u016bts"},"vro":{"language":"vro","value":"L\u00f5vi"},"xh":{"language":"xh","value":"Ingonyama"},"sa":{"language":"sa","value":"\u0938\u093f\u0902\u0939\u0903 \u092a\u0936\u0941\u0903"},"za":{"language":"za","value":"Saeceij"},"sd":{"language":"sd","value":"\u0628\u0628\u0631 \u0634\u064a\u0646\u0647\u0646"},"wuu":{"language":"wuu","value":"\u72ee"},"shn":{"language":"shn","value":"\u101e\u1062\u1004\u103a\u1087\u101e\u102e\u1088"},"alt":{"language":"alt","value":"\u0410\u0440\u0441\u043b\u0430\u043d"},"avk":{"language":"avk","value":"Krapol (Panthera leo)"},"dag":{"language":"dag","value":"Gbu\u0263inli"},"shi":{"language":"shi","value":"Agrzam"},"mni":{"language":"mni","value":"\uabc5\uabe3\uabe1\uabc1\uabe5"}},"descriptions":{"fr":{"language":"fr","value":"esp\u00e8ce de mammif\u00e8res carnivores"},"it":{"language":"it","value":"mammifero carnivoro della famiglia dei Felidi"},"nb":{"language":"nb","value":"kattedyr"},"ru":{"language":"ru","value":"\u0432\u0438\u0434 \u0445\u0438\u0449\u043d\u044b\u0445 \u043c\u043b\u0435\u043a\u043e\u043f\u0438\u0442\u0430\u044e\u0449\u0438\u0445"},"de":{"language":"de","value":"Art der Gattung Eigentliche Gro\u00dfkatzen (Panthera)"},"es":{"language":"es","value":"mam\u00edfero carn\u00edvoro de la familia de los f\u00e9lidos"},"en":{"language":"en","value":"species of big cat"},"ko":{"language":"ko","value":"\uace0\uc591\uc774\uacfc\uc5d0 \uc18d\ud558\ub294 \uc721\uc2dd\ub3d9\ubb3c"},"ca":{"language":"ca","value":"mam\u00edfer carn\u00edvor de la fam\u00edlia dels f\u00e8lids"},"fi":{"language":"fi","value":"suuri kissael\u00e4in"},"pt-br":{"language":"pt-br","value":"esp\u00e9cie de mam\u00edfero carn\u00edvoro do g\u00eanero Panthera e da fam\u00edlia Felidae"},"ta":{"language":"ta","value":"\u0bb5\u0bbf\u0bb2\u0b99\u0bcd\u0b95\u0bc1"},"nl":{"language":"nl","value":"groot roofdier uit de familie der katachtigen"},"he":{"language":"he","value":"\u05de\u05d9\u05df \u05d1\u05e1\u05d5\u05d2 \u05e4\u05e0\u05ea\u05e8, \u05d8\u05d5\u05e8\u05e3 \u05d2\u05d3\u05d5\u05dc \u05d1\u05de\u05e9\u05e4\u05d7\u05ea \u05d4\u05d7\u05ea\u05d5\u05dc\u05d9\u05d9\u05dd"},"pt":{"language":"pt","value":"esp\u00e9cie de felino"},"sco":{"language":"sco","value":"species o big cat"},"zh-hans":{"language":"zh-hans","value":"\u5927\u578b\u732b\u79d1\u52a8\u7269"},"uk":{"language":"uk","value":"\u0432\u0438\u0434 \u043a\u043b\u0430\u0441\u0443 \u0441\u0441\u0430\u0432\u0446\u0456\u0432, \u0440\u044f\u0434\u0443 \u0445\u0438\u0436\u0438\u0445, \u0440\u043e\u0434\u0438\u043d\u0438 \u043a\u043e\u0442\u044f\u0447\u0438\u0445"},"hu":{"language":"hu","value":"macskaf\u00e9l\u00e9k csal\u00e1dj\u00e1ba tartoz\u00f3 eml\u0151sfaj"},"bn":{"language":"bn","value":"\u099c\u0999\u09cd\u0997\u09b2\u09c7\u09b0 \u09b0\u09be\u099c\u09be"},"hi":{"language":"hi","value":"\u091c\u0902\u0917\u0932 \u0915\u093e \u0930\u093e\u091c\u093e"},"ilo":{"language":"ilo","value":"sebbangan ti dakkel a pusa"},"ksh":{"language":"ksh","value":"et jr\u00fch\u00dfde Kazedier op der \u00c4hd, der K\u00fcnning vun de Diehre"},"fa":{"language":"fa","value":"\u06af\u0631\u0628\u0647\u200c \u0628\u0632\u0631\u06af \u0628\u0648\u0645\u06cc \u0622\u0641\u0631\u06cc\u0642\u0627 \u0648 \u0622\u0633\u06cc\u0627"},"gl":{"language":"gl","value":"\u00e9 un mam\u00edfero carn\u00edvoro da familia dos f\u00e9lidos e unha das 4 especies do x\u00e9nero Panthera"},"sq":{"language":"sq","value":"mace e madhe e familjes Felidae"},"el":{"language":"el","value":"\u03b5\u03af\u03b4\u03bf\u03c2 \u03c3\u03b1\u03c1\u03ba\u03bf\u03c6\u03ac\u03b3\u03bf \u03b8\u03b7\u03bb\u03b1\u03c3\u03c4\u03b9\u03ba\u03cc"},"scn":{"language":"scn","value":"specia di mamm\u00ecfiru"},"bg":{"language":"bg","value":"\u0432\u0438\u0434 \u0431\u043e\u0437\u0430\u0439\u043d\u0438\u043a"},"ne":{"language":"ne","value":"\u0920\u0942\u0932\u094b \u092c\u093f\u0930\u093e\u0932\u094b\u0915\u094b \u092a\u094d\u0930\u091c\u093e\u0924\u093f"},"pl":{"language":"pl","value":"gatunek ssaka z rodziny kotowatych"},"af":{"language":"af","value":"Soogdier en roofdier van die familie Felidae, een van die \"groot katte\""},"mk":{"language":"mk","value":"\u0432\u0438\u0434 \u0433\u043e\u043b\u0435\u043c\u0430 \u043c\u0430\u0447\u043a\u0430"},"nn":{"language":"nn","value":"kattedyr"},"zh-hant":{"language":"zh-hant","value":"\u5927\u578b\u8c93\u79d1\u52d5\u7269"},"zh":{"language":"zh","value":"\u4ea7\u81ea\u975e\u6d32\u548c\u4e9a\u6d32\u7684\u5927\u578b\u732b\u79d1\u52a8\u7269"},"zh-cn":{"language":"zh-cn","value":"\u5927\u578b\u732b\u79d1\u52a8\u7269"},"zh-hk":{"language":"zh-hk","value":"\u5927\u578b\u8c93\u79d1\u52d5\u7269"},"zh-mo":{"language":"zh-mo","value":"\u5927\u578b\u8c93\u79d1\u52d5\u7269"},"zh-my":{"language":"zh-my","value":"\u5927\u578b\u732b\u79d1\u52a8\u7269"},"zh-sg":{"language":"zh-sg","value":"\u5927\u578b\u732b\u79d1\u52a8\u7269"},"zh-tw":{"language":"zh-tw","value":"\u5927\u578b\u8c93\u79d1\u52d5\u7269"},"sw":{"language":"sw","value":"mnyama mla nyama kama paka mkubwa"},"th":{"language":"th","value":"\u0e0a\u0e37\u0e48\u0e2d\u0e2a\u0e31\u0e15\u0e27\u0e4c\u0e1b\u0e48\u0e32\u0e0a\u0e19\u0e34\u0e14\u0e2b\u0e19\u0e36\u0e48\u0e07 \u0e2d\u0e22\u0e39\u0e48\u0e43\u0e19\u0e2a\u0e32\u0e22\u0e1e\u0e31\u0e19\u0e18\u0e38\u0e4c\u0e02\u0e2d\u0e07\u0e41\u0e21\u0e27\u0e43\u0e2b\u0e0d\u0e48"},"ar":{"language":"ar","value":"\u062d\u064a\u0648\u0627\u0646 \u0645\u0646 \u0627\u0644\u062b\u062f\u064a\u064a\u0627\u062a \u0645\u0646 \u0641\u0635\u064a\u0644\u0629 \u0627\u0644\u0633\u0646\u0648\u0631\u064a\u0627\u062a \u0648\u0623\u062d\u062f \u0627\u0644\u0633\u0646\u0648\u0631\u064a\u0627\u062a \u0627\u0644\u0623\u0631\u0628\u0639\u0629 \u0627\u0644\u0643\u0628\u064a\u0631\u0629 \u0627\u0644\u0645\u0646\u062a\u0645\u064a\u0629 \u0644\u062c\u0646\u0633 \u0627\u0644\u0646\u0645\u0631"},"ml":{"language":"ml","value":"\u0d38\u0d38\u0d4d\u0d24\u0d28\u0d3f\u0d15\u0d33\u0d3f\u0d32\u0d46 \u0d2b\u0d46\u0d32\u0d3f\u0d21\u0d47 \u0d15\u0d41\u0d1f\u0d41\u0d02\u0d2c\u0d24\u0d4d\u0d24\u0d3f\u0d32\u0d46 \u0d2a\u0d3e\u0d28\u0d4d\u0d24\u0d31 \u0d1c\u0d28\u0d41\u0d38\u0d4d\u0d38\u0d3f\u0d7d \u0d09\u0d7e\u0d2a\u0d4d\u0d2a\u0d46\u0d1f\u0d4d\u0d1f \u0d12\u0d30\u0d41 \u0d35\u0d28\u0d4d\u0d2f\u0d1c\u0d40\u0d35\u0d3f\u0d2f\u0d3e\u0d23\u0d4d \u0d38\u0d3f\u0d02\u0d39\u0d02"},"cs":{"language":"cs","value":"ko\u010dkovit\u00e1 \u0161elma"},"gu":{"language":"gu","value":"\u0aac\u0abf\u0ab2\u0abe\u0aa1\u0ac0 \u0ab5\u0a82\u0ab6\u0aa8\u0ac1\u0a82 \u0ab8\u0ab8\u0acd\u0aa4\u0aa8 \u0aaa\u0acd\u0ab0\u0abe\u0aa3\u0ac0"},"mr":{"language":"mr","value":"\u092e\u093e\u0902\u091c\u0930\u093e\u091a\u0940 \u092e\u094b\u0920\u0940 \u091c\u093e\u0924"},"sr":{"language":"sr","value":"\u0432\u0435\u043b\u0438\u043a\u0438 \u0441\u0438\u0441\u0430\u0440 \u0438\u0437 \u043f\u043e\u0440\u043e\u0434\u0438\u0446\u0435 \u043c\u0430\u0447\u0430\u043a\u0430"},"ast":{"language":"ast","value":"especie de mam\u00edferu carn\u00edvoru"},"te":{"language":"te","value":"\u0c2a\u0c46\u0c26\u0c4d\u0c26 \u0c2a\u0c3f\u0c32\u0c4d\u0c32\u0c3f \u0c1c\u0c24\u0c3f"},"bho":{"language":"bho","value":"\u092c\u093f\u0932\u093e\u0930\u092c\u0902\u0938 \u0915\u0947 \u092c\u0921\u093c\u0939\u0928 \u091c\u093e\u0928\u0935\u0930"},"da":{"language":"da","value":"en af de fem store katte i sl\u00e6gten Panthera"},"vi":{"language":"vi","value":"M\u1ed9t lo\u00e0i m\u00e8o l\u1edbn thu\u1ed9c chi Panthera"},"ja":{"language":"ja","value":"\u98df\u8089\u76ee\u30cd\u30b3\u79d1\u306e\u52d5\u7269"},"ga":{"language":"ga","value":"speiceas cat"},"bs":{"language":"bs","value":"vrsta velike ma\u010dke"},"tr":{"language":"tr","value":"Afrika ve Asya'ya \u00f6zg\u00fc b\u00fcy\u00fck bir kedi"},"as":{"language":"as","value":"\u09b8\u09cd\u09a4\u09a8\u09cd\u09af\u09aa\u09be\u09af\u09bc\u09c0 \u09aa\u09cd\u09f0\u09be\u09a3\u09c0"},"my":{"language":"my","value":"\u1014\u102d\u102f\u1037\u1010\u102d\u102f\u1000\u103a\u101e\u1010\u1039\u1010\u101d\u102b \u1019\u103b\u102d\u102f\u1038\u1005\u102d\u1010\u103a (\u1000\u103c\u1031\u102c\u1004\u103a\u1019\u103b\u102d\u102f\u1038\u101b\u1004\u103a\u1038\u101d\u1004\u103a)"},"id":{"language":"id","value":"spesies hewan keluarga jenis kucing"},"ks":{"language":"ks","value":"\u0628\u062c \u0628\u0631\u0627\u0631\u0646 \u06be\u0646\u062f \u06a9\u0633\u0645 \u06cc\u0633 \u0627\u0634\u06cc\u0627 \u062a\u06c1 \u0627\u0641\u0631\u06cc\u06a9\u0627 \u0645\u0646\u0632 \u0645\u0644\u0627\u0646 \u0686\u06be\u06c1"},"br":{"language":"br","value":"bronneg kigdebrer"},"sat":{"language":"sat","value":"\u1c75\u1c64\u1c68 \u1c68\u1c6e\u1c71 \u1c68\u1c5f\u1c61\u1c5f"},"mni":{"language":"mni","value":"\uabc2\uabdd\uabc2\uabdb\uabc0\uabe4 \uabc1\uabe5\uabcd\uabe4\uabe1 \uabc6\uabe5\uabd5 \uabc1\uabe5 \uabd1\uabc6\uabe7\uabd5\uabc1\uabe4\uabe1\uabd2\uabe4 \uabc3\uabc5\uabe8\uabe1\uabd7 \uabd1\uabc3"},"ro":{"language":"ro","value":"mamifer carnivor"}},"aliases":{"es":[{"language":"es","value":"Panthera leo"},{"language":"es","value":"leon"}],"en":[{"language":"en","value":"Asiatic Lion"},{"language":"en","value":"Panthera leo"},{"language":"en","value":"African lion"},{"language":"en","value":"the lion"},{"language":"en","value":"\ud83e\udd81"}],"pt-br":[{"language":"pt-br","value":"Panthera leo"}],"fr":[{"language":"fr","value":"lionne"},{"language":"fr","value":"lionceau"}],"zh":[{"language":"zh","value":"\u9b03\u6bdb"},{"language":"zh","value":"\u72ee\u5b50"},{"language":"zh","value":"\u7345"},{"language":"zh","value":"\u525b\u679c\u7345"},{"language":"zh","value":"\u975e\u6d32\u72ee"}],"de":[{"language":"de","value":"Panthera leo"}],"ca":[{"language":"ca","value":"Panthera leo"}],"sco":[{"language":"sco","value":"Panthera leo"}],"hu":[{"language":"hu","value":"P. leo"},{"language":"hu","value":"Panthera leo"}],"ilo":[{"language":"ilo","value":"Panthera leo"},{"language":"ilo","value":"Felis leo"}],"ksh":[{"language":"ksh","value":"L\u00f6hw"},{"language":"ksh","value":"L\u00f6hf"},{"language":"ksh","value":"L\u00f6v"}],"gl":[{"language":"gl","value":"Panthera leo"}],"ja":[{"language":"ja","value":"\u767e\u7363\u306e\u738b"},{"language":"ja","value":"\u7345\u5b50"},{"language":"ja","value":"\u30b7\u30b7"}],"sq":[{"language":"sq","value":"Mbreti i Kafsh\u00ebve"}],"el":[{"language":"el","value":"\u03c0\u03b1\u03bd\u03b8\u03ae\u03c1"}],"pl":[{"language":"pl","value":"Panthera leo"},{"language":"pl","value":"lew"}],"zh-hk":[{"language":"zh-hk","value":"\u7345"}],"af":[{"language":"af","value":"Panthera leo"}],"mk":[{"language":"mk","value":"Panthera leo"}],"ar":[{"language":"ar","value":"\u0644\u064a\u062b"}],"zh-hant":[{"language":"zh-hant","value":"\u7345"}],"zh-cn":[{"language":"zh-cn","value":"\u72ee"}],"zh-hans":[{"language":"zh-hans","value":"\u72ee"}],"zh-mo":[{"language":"zh-mo","value":"\u7345"}],"zh-my":[{"language":"zh-my","value":"\u72ee"}],"zh-sg":[{"language":"zh-sg","value":"\u72ee"}],"zh-tw":[{"language":"zh-tw","value":"\u7345"}],"gu":[{"language":"gu","value":"\u0ab5\u0aa8\u0ab0\u0abe\u0a9c"},{"language":"gu","value":"\u0ab8\u0abe\u0ab5\u0a9c"},{"language":"gu","value":"\u0a95\u0ac7\u0ab8\u0ab0\u0ac0"}],"ast":[{"language":"ast","value":"Panthera leo"},{"language":"ast","value":"lle\u00f3n africanu"}],"hi":[{"language":"hi","value":"\u092a\u0947\u0902\u0925\u0947\u0930\u093e \u0932\u093f\u092f\u094b"}],"te":[{"language":"te","value":"\u0c2a\u0c3e\u0c02\u0c25\u0c47\u0c30\u0c3e \u0c32\u0c3f\u0c2f\u0c4b"}],"nl":[{"language":"nl","value":"Panthera leo"}],"bho":[{"language":"bho","value":"\u092a\u0948\u0928\u094d\u0925\u0947\u0930\u093e \u0932\u093f\u092f\u094b"},{"language":"bho","value":"\u092a\u0948\u0902\u0925\u0947\u0930\u093e \u0932\u093f\u092f\u094b"}],"ru":[{"language":"ru","value":"\u0430\u0437\u0438\u0430\u0442\u0441\u043a\u0438\u0439 \u043b\u0435\u0432"},{"language":"ru","value":"\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u043a\u043e\u0448\u043a\u0430"},{"language":"ru","value":"\u0446\u0430\u0440\u044c \u0437\u0432\u0435\u0440\u0435\u0439"},{"language":"ru","value":"\u0430\u0444\u0440\u0438\u043a\u0430\u043d\u0441\u043a\u0438\u0439 \u043b\u0435\u0432"}],"ga":[{"language":"ga","value":"Panthera leo"}],"bg":[{"language":"bg","value":"Panthera leo"},{"language":"bg","value":"\u043b\u044a\u0432\u0438\u0446\u0430"}],"sat":[{"language":"sat","value":"\u1c60\u1c69\u1c5e"}],"nan":[{"language":"nan","value":"Panthera leo"}],"la":[{"language":"la","value":"Panthera leo"}],"nds-nl":[{"language":"nds-nl","value":"leywe"}]},"claims":{"P225":[{"mainsnak":{"snaktype":"value","property":"P225","hash":"e2be083a19a0c5e1a3f8341be88c5ec0e347580f","datavalue":{"value":"Panthera leo","type":"string"},"datatype":"string"},"type":"statement","qualifiers":{"P405":[{"snaktype":"value","property":"P405","hash":"a817d3670bc2f9a3586b6377a65d54fff72ef888","datavalue":{"value":{"entity-type":"item","numeric-id":1043,"id":"Q1043"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P574":[{"snaktype":"value","property":"P574","hash":"506af9838b7d37b45786395b95170263f1951a31","datavalue":{"value":{"time":"+1758-01-01T00:00:00Z","timezone":0,"before":0,"after":0,"precision":9,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}],"P31":[{"snaktype":"value","property":"P31","hash":"60a983bb1006c765614eb370c3854e64ec50599f","datavalue":{"value":{"entity-type":"item","numeric-id":14594740,"id":"Q14594740"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P405","P574","P31"],"id":"q140$8CCA0B07-C81F-4456-ABAA-A7348C86C9B4","rank":"normal","references":[{"hash":"89e96b63b05055cc80c950cf5fea109c7d453658","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"c26dbcef1202a7d198982ed24f6ea69b704f95fe","datavalue":{"value":{"entity-type":"item","numeric-id":82575,"id":"Q82575"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P577":[{"snaktype":"value","property":"P577","hash":"539fa499b6ea982e64006270bb26f52a57a8e32b","datavalue":{"value":{"time":"+1996-06-13T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}],"P813":[{"snaktype":"value","property":"P813","hash":"96dfb8481e184edb40553947f8fe08ce080f1553","datavalue":{"value":{"time":"+2013-09-19T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P577","P813"]},{"hash":"f2fcc71ba228fd0db2b328c938e601507006fa46","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"603c636b2210e4a74b7d40c9e969b7e503bbe252","datavalue":{"value":{"entity-type":"item","numeric-id":1538807,"id":"Q1538807"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"6892402e621d2b47092e15284d64cdbb395e71f7","datavalue":{"value":{"time":"+2015-09-19T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]}],"P105":[{"mainsnak":{"snaktype":"value","property":"P105","hash":"aebf3611b23ed90c7c0fc80f6cd1cb7be110ea59","datavalue":{"value":{"entity-type":"item","numeric-id":7432,"id":"Q7432"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"q140$CD2903E5-743A-4B4F-AE9E-9C0C83426B11","rank":"normal","references":[{"hash":"89e96b63b05055cc80c950cf5fea109c7d453658","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"c26dbcef1202a7d198982ed24f6ea69b704f95fe","datavalue":{"value":{"entity-type":"item","numeric-id":82575,"id":"Q82575"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P577":[{"snaktype":"value","property":"P577","hash":"539fa499b6ea982e64006270bb26f52a57a8e32b","datavalue":{"value":{"time":"+1996-06-13T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}],"P813":[{"snaktype":"value","property":"P813","hash":"96dfb8481e184edb40553947f8fe08ce080f1553","datavalue":{"value":{"time":"+2013-09-19T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P577","P813"]},{"hash":"f2fcc71ba228fd0db2b328c938e601507006fa46","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"603c636b2210e4a74b7d40c9e969b7e503bbe252","datavalue":{"value":{"entity-type":"item","numeric-id":1538807,"id":"Q1538807"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"6892402e621d2b47092e15284d64cdbb395e71f7","datavalue":{"value":{"time":"+2015-09-19T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]}],"P171":[{"mainsnak":{"snaktype":"value","property":"P171","hash":"cbf0d3943e6cbac8afbec1ff11525c84ee04e442","datavalue":{"value":{"entity-type":"item","numeric-id":127960,"id":"Q127960"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"q140$C1CA40D8-39C3-4DB4-B763-207A22796D85","rank":"normal","references":[{"hash":"89e96b63b05055cc80c950cf5fea109c7d453658","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"c26dbcef1202a7d198982ed24f6ea69b704f95fe","datavalue":{"value":{"entity-type":"item","numeric-id":82575,"id":"Q82575"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P577":[{"snaktype":"value","property":"P577","hash":"539fa499b6ea982e64006270bb26f52a57a8e32b","datavalue":{"value":{"time":"+1996-06-13T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}],"P813":[{"snaktype":"value","property":"P813","hash":"96dfb8481e184edb40553947f8fe08ce080f1553","datavalue":{"value":{"time":"+2013-09-19T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P577","P813"]},{"hash":"f2fcc71ba228fd0db2b328c938e601507006fa46","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"603c636b2210e4a74b7d40c9e969b7e503bbe252","datavalue":{"value":{"entity-type":"item","numeric-id":1538807,"id":"Q1538807"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"6892402e621d2b47092e15284d64cdbb395e71f7","datavalue":{"value":{"time":"+2015-09-19T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]}],"P1403":[{"mainsnak":{"snaktype":"value","property":"P1403","hash":"baa11a4c668601014a48e2998ab76aa1ea7a5b99","datavalue":{"value":{"entity-type":"item","numeric-id":15294488,"id":"Q15294488"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"Q140$816d2b99-4aa5-5eb9-784b-34e2704d2927","rank":"normal"}],"P141":[{"mainsnak":{"snaktype":"value","property":"P141","hash":"80026ea5b2066a2538fee5c0897b459bb6770689","datavalue":{"value":{"entity-type":"item","numeric-id":278113,"id":"Q278113"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"q140$B12A2FD5-692F-4D9A-8FC7-144AA45A16F8","rank":"normal","references":[{"hash":"355df53bb7c6d100219cd2a331afd51719337d88","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"eb153b77c6029ffa1ca09f9128b8e47fe58fce5a","datavalue":{"value":{"entity-type":"item","numeric-id":56011232,"id":"Q56011232"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P627":[{"snaktype":"value","property":"P627","hash":"3642ac96e05180279c47a035c129d3af38d85027","datavalue":{"value":"15951","type":"string"},"datatype":"string"}],"P813":[{"snaktype":"value","property":"P813","hash":"76bc602d4f902d015c358223e7c0917bd65095e0","datavalue":{"value":{"time":"+2018-08-10T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P627","P813"]}]}],"P181":[{"mainsnak":{"snaktype":"value","property":"P181","hash":"8467347aac1f01e518c1b94d5bb68c65f9efe84a","datavalue":{"value":"Lion distribution.png","type":"string"},"datatype":"commonsMedia"},"type":"statement","id":"q140$12F383DD-D831-4AE9-A0ED-98C27A8C5BA7","rank":"normal"}],"P830":[{"mainsnak":{"snaktype":"value","property":"P830","hash":"8cafbfe99d80fcfabbd236d4cc01d33cc8a8b41d","datavalue":{"value":"328672","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$486d7ab8-4af8-b6e1-85bb-e0749b02c2d9","rank":"normal","references":[{"hash":"7e71b7ede7931e7e2ee9ce54e832816fe948b402","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"6e81987ab11fb1740bd862639411d0700be3b22c","datavalue":{"value":{"entity-type":"item","numeric-id":82486,"id":"Q82486"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"7c1a33cf9a0bf6cdd57b66f089065ba44b6a8953","datavalue":{"value":{"time":"+2014-10-30T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]}],"P815":[{"mainsnak":{"snaktype":"value","property":"P815","hash":"27f6bd8fb4504eb79b92e6b63679b83af07d5fed","datavalue":{"value":"183803","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$71177A4F-4308-463D-B370-8B354EC2D2C3","rank":"normal","references":[{"hash":"ff0dd9eabf88b0dcefa74b223d065dd644e42050","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"c26dbcef1202a7d198982ed24f6ea69b704f95fe","datavalue":{"value":{"entity-type":"item","numeric-id":82575,"id":"Q82575"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"6b8fcfa6afb3911fecec93ae1dff2b6b6cde5659","datavalue":{"value":{"time":"+2013-12-07T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]}],"P685":[{"mainsnak":{"snaktype":"value","property":"P685","hash":"c863e255c042b2b9b6a788ebd6e24f38a46dfa88","datavalue":{"value":"9689","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$A9F4ABE4-D079-4868-BC18-F685479BB244","rank":"normal","references":[{"hash":"5667273d9f2899620fec2016bb2afd29aa7080ce","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"1851bc60ddfbcf6f76bd45aa7124fc0d5857a379","datavalue":{"value":{"entity-type":"item","numeric-id":13711410,"id":"Q13711410"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"6b8fcfa6afb3911fecec93ae1dff2b6b6cde5659","datavalue":{"value":{"time":"+2013-12-07T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]}],"P959":[{"mainsnak":{"snaktype":"value","property":"P959","hash":"55cab2a9d2af860a89a8d0e2eaefedb64202a3d8","datavalue":{"value":"14000228","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$A967D17D-485D-434F-BBF2-E6226E63BA42","rank":"normal","references":[{"hash":"3e398e6df20323ce88e644e5a1e4ec0bc77a5f41","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"603c636b2210e4a74b7d40c9e969b7e503bbe252","datavalue":{"value":{"entity-type":"item","numeric-id":1538807,"id":"Q1538807"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"d2bace4e146678a5e5f761e9a441b53b95dc2e87","datavalue":{"value":{"time":"+2014-01-10T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]}],"P842":[{"mainsnak":{"snaktype":"value","property":"P842","hash":"991987fc3fa4d1cfd3a601dcfc9dd1f802255de7","datavalue":{"value":"49734","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$3FF45860-DBC3-4629-AAF8-F2899B6C6876","rank":"normal","references":[{"hash":"1111bfc1dc63ee739fb9dd3f5534346c7fd478f0","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"00fe2206a3342fa25c0cfe1d08783c49a1986f12","datavalue":{"value":{"entity-type":"item","numeric-id":796451,"id":"Q796451"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"14c5b75e8d3f4c43cb5b570380dd98e421bb9751","datavalue":{"value":{"time":"+2014-01-30T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]}],"P227":[{"mainsnak":{"snaktype":"value","property":"P227","hash":"3343c5fd594f8f0264332d87ce95e76ffeaebffd","datavalue":{"value":"4140572-9","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$0059e08d-4308-8401-58e8-2cb683c03837","rank":"normal"}],"P349":[{"mainsnak":{"snaktype":"value","property":"P349","hash":"08812c4ef85f397bf00b015d1baf3b00d81cb9bf","datavalue":{"value":"00616831","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$B7933772-D27D-49D4-B1BB-AA36ADCA81B0","rank":"normal"}],"P1014":[{"mainsnak":{"snaktype":"value","property":"P1014","hash":"3d27204feb184f21c042777dc9674150cb07ee92","datavalue":{"value":"300310388","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$8e3c9dc3-442e-2e61-8617-f4a41b5be668","rank":"normal"}],"P646":[{"mainsnak":{"snaktype":"value","property":"P646","hash":"0c053bce57fe07b05c300a09b322d9f89236884b","datavalue":{"value":"/m/096mb","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$D94D8A4F-3414-4BE0-82C1-306BD136C017","rank":"normal","references":[{"hash":"2b00cb481cddcac7623114367489b5c194901c4a","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"a94b740202b097dd33355e0e6c00e54b9395e5e0","datavalue":{"value":{"entity-type":"item","numeric-id":15241312,"id":"Q15241312"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P577":[{"snaktype":"value","property":"P577","hash":"fde79ecb015112d2f29229ccc1ec514ed3e71fa2","datavalue":{"value":{"time":"+2013-10-28T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P577"]}]}],"P1036":[{"mainsnak":{"snaktype":"value","property":"P1036","hash":"02435ba66ab8e5fb26652ae1a84695be24b3e22a","datavalue":{"value":"599.757","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$e75ed89a-408d-9bc1-8d99-41663921debd","rank":"normal"}],"P1245":[{"mainsnak":{"snaktype":"value","property":"P1245","hash":"f3da4ca7d35fc3e02a9ea1662688d8f6c4658df0","datavalue":{"value":"5961","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$010e79a0-475e-fcf4-a554-375b64943783","rank":"normal"}],"P910":[{"mainsnak":{"snaktype":"value","property":"P910","hash":"056367b51cd51edd6c2840134fde01cf40469172","datavalue":{"value":{"entity-type":"item","numeric-id":6987175,"id":"Q6987175"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"Q140$BC4DE2D4-BF45-49AF-A9A6-C0A976F60825","rank":"normal"}],"P373":[{"mainsnak":{"snaktype":"value","property":"P373","hash":"76c006bc5e2975bcda2e7d60ddcbaaa8c84f69e5","datavalue":{"value":"Panthera leo","type":"string"},"datatype":"string"},"type":"statement","id":"q140$939BA4B2-28D3-4C74-B143-A0EA6F423B43","rank":"normal"}],"P846":[{"mainsnak":{"snaktype":"value","property":"P846","hash":"d0428680cd2b36efde61dc69ccc5a8ff7a735cb5","datavalue":{"value":"5219404","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$4CE8E6D4-E9A1-46F1-8EEF-B469E8485F9E","rank":"normal","references":[{"hash":"5b8345ffc93a361b71f5d201a97f587e5e57efe5","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"dbb8dd1efbe0158a5227213bd628eeac27a1da65","datavalue":{"value":{"entity-type":"item","numeric-id":1531570,"id":"Q1531570"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"3eb17b10ce02d44f47540a6fbdbb3cbb7e77d5f5","datavalue":{"value":{"time":"+2015-05-15T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]}],"P487":[{"mainsnak":{"snaktype":"value","property":"P487","hash":"5f93415dd33bfde6a546fdd65e5a7013e012c336","datavalue":{"value":"\ud83e\udd81","type":"string"},"datatype":"string"},"type":"statement","id":"Q140$da5262fc-4ac5-390b-b424-4f296b2d711d","rank":"normal"}],"P2040":[{"mainsnak":{"snaktype":"value","property":"P2040","hash":"5b13a3fa0fde6ba09d8e417738c05268bd065e32","datavalue":{"value":"6353","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$E97A1A2E-D146-4C62-AE92-5AF5F7E146EF","rank":"normal","references":[{"hash":"348b5187938d682071c94e22f1b30659af715dc7","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"213dc0d84ed983cbb28466ebb0c45bf8b0730ea2","datavalue":{"value":{"entity-type":"item","numeric-id":20962955,"id":"Q20962955"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"3d2c713dec9143721ae196af88fee0fde5ae20f2","datavalue":{"value":{"time":"+2015-09-10T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]}],"P935":[{"mainsnak":{"snaktype":"value","property":"P935","hash":"c3518a9944958337bcce384587f3abc3de6ddf34","datavalue":{"value":"Panthera leo","type":"string"},"datatype":"string"},"type":"statement","id":"Q140$F7AAEE1F-4D18-4538-99F0-1A2B5AD7269F","rank":"normal"}],"P1417":[{"mainsnak":{"snaktype":"value","property":"P1417","hash":"492d3483075b6915990940a4392f5ec035cbe05e","datavalue":{"value":"animal/lion","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$FE89C38F-6C79-4F06-8C15-81DCAC8D745F","rank":"normal"}],"P244":[{"mainsnak":{"snaktype":"value","property":"P244","hash":"2e41780263804dd45d7deaf7955a2d1d221f6096","datavalue":{"value":"sh85077276","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$634d86d1-45b1-920d-e9ef-78d5f4023288","rank":"normal","references":[{"hash":"88d810dd1ff791aeb0b5779876b0c9f19acb59b6","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"c120f07504c77593a9d734f50361ea829f601960","datavalue":{"value":{"entity-type":"item","numeric-id":620946,"id":"Q620946"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"0980c2f2b51e6b2d4c1dd9a77b9fb95dc282bc79","datavalue":{"value":{"time":"+2016-06-01T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]}],"P1843":[{"mainsnak":{"snaktype":"value","property":"P1843","hash":"3b1cfb68cc46255ceba7ff7893ac1cabbb4ddd92","datavalue":{"value":{"text":"Lion","language":"en"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","qualifiers":{"P7018":[{"snaktype":"value","property":"P7018","hash":"40a60b39201df345ffbf5aa724269d5fd61ae028","datavalue":{"value":{"entity-type":"sense","id":"L17815-S1"},"type":"wikibase-entityid"},"datatype":"wikibase-sense"}]},"qualifiers-order":["P7018"],"id":"Q140$6E257597-55C7-4AF3-B3D6-0F2204FAD35C","rank":"normal","references":[{"hash":"eada84c58a38325085267509899037535799e978","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"ba14d022d7e0c8b74595e7b8aaa1bc2451dd806a","datavalue":{"value":{"entity-type":"item","numeric-id":32059,"id":"Q32059"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"3e51c3c32949f8a45f2c3331f55ea6ae68ecf3fe","datavalue":{"value":{"time":"+2016-10-21T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]},{"hash":"cdc389b112247cb50b855fb86e98b7a7892e96f0","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"e17975e5c866df46673c91b2287a82cf23d14f5a","datavalue":{"value":{"entity-type":"item","numeric-id":27310853,"id":"Q27310853"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P304":[{"snaktype":"value","property":"P304","hash":"ff7ad3502ff7a4a9b0feeb4248a7bed9767a1ec6","datavalue":{"value":"166","type":"string"},"datatype":"string"}]},"snaks-order":["P248","P304"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"38a9c57a5c62a707adc86decd2bd00be89eab6f3","datavalue":{"value":{"text":"Leeu","language":"af"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$5E731B05-20D6-491B-97E7-94D90CBB70F0","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"a4455f1ef49d7d17896563760a420031c41d65c1","datavalue":{"value":{"text":"Gyata","language":"ak"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$721B4D81-D948-4002-A13E-0B2567626FD6","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"b955c9239d6ced23c0db577e20219b0417a2dd9b","datavalue":{"value":{"text":"Ley\u00f3n","language":"an"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$E2B52F3D-B12D-48B5-86EA-6A4DCBC091D3","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"e18a8ecb17321c203fcf8f402e82558ce0599b39","datavalue":{"value":{"text":"Li\u00f3n","language":"an"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$339ADC90-41C6-4CDB-B6C3-DA9F952FCC15","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"297bf417fff1510d19b27c08fa9f34e2653b9510","datavalue":{"value":{"text":"\u0623\u064e\u0633\u064e\u062f\u064c","language":"ar"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$F1849268-0E70-4EC0-A630-EC0D2DCBB298","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"5577ef6920a3ade2365d878740d1d097fcdae399","datavalue":{"value":{"text":"L\u00e9we","language":"bar"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$BDD65B40-7ECB-4725-B33F-417A83AF5102","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"de8fa35eca4e61dfb8fe2df360e734fb1cd37092","datavalue":{"value":{"text":"L\u00f6we","language":"bar"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$486EE5F1-9AB5-4789-98AC-E435D81E784F","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"246c27f44da8bedd2e3313de393fe648b2b40ea9","datavalue":{"value":{"text":"\u041b\u0435\u045e (Lew)","language":"be"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$47AA6BD4-0B09-4B20-9092-0AEAD8056157","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"64c42db53ef288871161f0a656808f06daae817d","datavalue":{"value":{"text":"\u041b\u044a\u0432 (L\u0103v)","language":"bg"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$ADF0B08A-9626-4821-8118-0A875CBE5FB9","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"6041e2730af3095f4f0cbf331382e22b596d2305","datavalue":{"value":{"text":"\u09b8\u09bf\u0982\u09b9","language":"bn"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$8DF5BDCD-B470-46C3-A44A-7375B8A5DCDE","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"8499f437dc8678b0c4b740b40cab41031fce874d","datavalue":{"value":{"text":"Lle\u00f3","language":"ca"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$F55C3E63-DB2C-4F6D-B10B-4C1BB70C06A0","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"b973abb618a6f17b8a9547b852e5817b5c4da00b","datavalue":{"value":{"text":"\u041b\u043e\u044c\u043c","language":"ce"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$F32B0BFA-3B85-4A26-A888-78FD8F09F943","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"62f53c7229efad1620a5cce4dc5a535d88c4989f","datavalue":{"value":{"text":"Lev","language":"cs"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$1630DAB7-C4D0-4268-A598-8BBB9480221E","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"0df7e23666c947b42aea5572a9f5a987229718d3","datavalue":{"value":{"text":"Llew","language":"cy"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$F33991E8-A532-47F5-B135-A13761DB2E95","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"14942ad0830a0eb7b06704234eea637f99b53a24","datavalue":{"value":{"text":"L\u00f8ve","language":"da"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$478F0603-640A-44BE-9453-700FDD32100F","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"8af089542ef6207b918f656bcf9a96e745970915","datavalue":{"value":{"text":"L\u00f6we","language":"de"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","qualifiers":{"P7018":[{"snaktype":"value","property":"P7018","hash":"2da239e18a0208847a72fbeab011c8c2fb3b4d99","datavalue":{"value":{"entity-type":"sense","id":"L41680-S1"},"type":"wikibase-entityid"},"datatype":"wikibase-sense"}]},"qualifiers-order":["P7018"],"id":"Q140$11F5F498-3688-4F4B-B2FA-7121BE5AA701","rank":"normal","references":[{"hash":"cdc389b112247cb50b855fb86e98b7a7892e96f0","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"e17975e5c866df46673c91b2287a82cf23d14f5a","datavalue":{"value":{"entity-type":"item","numeric-id":27310853,"id":"Q27310853"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P304":[{"snaktype":"value","property":"P304","hash":"ff7ad3502ff7a4a9b0feeb4248a7bed9767a1ec6","datavalue":{"value":"166","type":"string"},"datatype":"string"}]},"snaks-order":["P248","P304"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"c0c8b50001810c1ec643b88479df82ea85c819a2","datavalue":{"value":{"text":"Dzata","language":"ee"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$8F6EC307-A293-4AFC-8154-E3FF187C0D7D","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"57a3384eeb13d1bcffeb3cf0efd0f3e3f511b35d","datavalue":{"value":{"text":"\u039b\u03b9\u03bf\u03bd\u03c4\u03ac\u03c1\u03b9 (Liond\u00e1ri)","language":"el"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$560B3341-3E06-4D09-8869-FC47C841D14C","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"ee7109a46f8259ae6f52791cfe599b7c4c272831","datavalue":{"value":{"text":"Leono","language":"eo"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$67F2B7A6-1C81-407A-AA61-A1BFF148EC69","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"3b8f4f61c3a18792bfaff5d332f03c80932dce05","datavalue":{"value":{"text":"Le\u00f3n","language":"es"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$DB29EAF7-4405-4030-8056-ED17089B3805","rank":"normal","references":[{"hash":"d3a8e536300044db1d823eae6891b2c7baa49f66","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"ba14d022d7e0c8b74595e7b8aaa1bc2451dd806a","datavalue":{"value":{"entity-type":"item","numeric-id":32059,"id":"Q32059"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"620d2e76d21bb1d326fc360db5bece2070115240","datavalue":{"value":{"time":"+2016-10-19T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"41fffb83f35736829d60f782bdce68463f0ab47c","datavalue":{"value":{"text":"L\u00f5vi","language":"et"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$19B76CC4-AA11-443B-BC76-DB2D0DA5B9CB","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"b96549e5ae538fb7e0b48089508333b31aec8fe7","datavalue":{"value":{"text":"Lehoi","language":"eu"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$88F712C1-4EEF-4E42-8C61-84E55CF2DCE0","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"b343c833d8de3dfd5c8b31336afd137380ab42dc","datavalue":{"value":{"text":"\u0634\u06cc\u0631 (\u0160ayr)","language":"fa"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$B72DB989-EF39-42F5-8FA8-5FC669079DB7","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"51aaf9a4a7c5e77ba931a5280d1fec984c91963b","datavalue":{"value":{"text":"Leijona","language":"fi"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$6861CDE9-707D-43AD-B352-3BCD7B9D4267","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"038249fb112acc26895af45fab412395f999ae11","datavalue":{"value":{"text":"Leyva","language":"fo"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$A044100A-C49F-4AA6-8861-F0300F28126E","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"92ec25b64605d026b07b0cda6e623fbbf2f3dfb4","datavalue":{"value":{"text":"Lion","language":"fr"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$122623FD-3915-49E9-8890-0B6883317507","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"59be091f7839e7a6061c6d1690ed77f3b21b9ff4","datavalue":{"value":{"text":"L\u00f6\u00f6w","language":"frr"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$76B87E52-A02C-4E99-A4B3-D6105B642521","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"126b0f2c5ed11124233dfefff8bd132a1fe1218a","datavalue":{"value":{"text":"Le\u00f3n-leoa","language":"gl"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$A4864784-EED3-4898-83FE-A2FCC0C3982E","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"49e0d3858de566edce1a28b0e96f42b2d0df718f","datavalue":{"value":{"text":"\u0ab8\u0abf\u0a82\u0ab9","language":"gu"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$4EE122CE-7671-480E-86A4-4A4DDABC04BA","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"dff0c422f7403c50d28dd51ca2989d03108b7584","datavalue":{"value":{"text":"Liona","language":"haw"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$FBB6AC65-A224-4C29-8024-079C0687E9FB","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"c174addd56c0f42f6ec3e87c72fb9651e4923a00","datavalue":{"value":{"text":"\u05d0\u05e8\u05d9\u05d4","language":"he"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$B72D9BDB-A2CC-471D-AF20-8F7FB677D533","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"c38a63a06b569fc8fee3e98c4cf8d5501990811e","datavalue":{"value":{"text":"si\u1e45ha)","language":"hi"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$9AA9171C-E912-41F2-AB26-643AA538E644","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"94f073519a5b64c48398c73a5f0f135a4f0f4306","datavalue":{"value":{"text":"\u0936\u0947\u0930","language":"hi"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$0714B97B-03E0-4ACC-80A0-6A17874DDBA8","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"1fbda5b1494db298c698fc28ed0fe68b1c137b2e","datavalue":{"value":{"text":"\u0938\u093f\u0902\u0939","language":"hi"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$3CE22F68-038C-4A94-9A1F-96B82760DEB9","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"fac41ebd8d1da777acd93720267c7a70016156e4","datavalue":{"value":{"text":"Lav","language":"hr"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$C5351C11-E287-4D3B-A9B2-56716F0E69E5","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"71e0bda709fb17d58f4bd8e12fff7f937a61673c","datavalue":{"value":{"text":"Oroszl\u00e1n","language":"hu"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$AD06E7D2-3B1F-4D14-B2E9-DD2513BE8B4B","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"05e86680d70a2c0adf9a6e6eb51bbdf8c6ae44bc","datavalue":{"value":{"text":"\u0531\u057c\u0575\u0578\u0582\u056e","language":"hy"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$3E02B802-8F7B-4C48-A3F9-FBBFDB0D8DB3","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"979f25bee6af37e19471530c6344a0d22a0d594c","datavalue":{"value":{"text":"Lj\u00f3n","language":"is"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$59788C31-A354-4229-AD89-361CB6076EF7","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"789e5f5a7ec6003076bc7fd2996faf8ca8468719","datavalue":{"value":{"text":"Leone","language":"it"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$4901AE59-7749-43D1-BC65-DEEC0DFEB72F","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"4a5bdf9bb40f1cab9a92b7dba1d1d74a8440c7ed","datavalue":{"value":{"text":"\u30e9\u30a4\u30aa\u30f3 (Raion)","language":"ja"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$4CF2E0D9-5CF3-46A3-A197-938E94270CE2","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"ebba3893211c78dad7ae74a51448e8c7f6e73309","datavalue":{"value":{"text":"\uc0ac\uc790 (saja)","language":"ko"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$64B6CECD-5FFE-4612-819F-CAB2E726B228","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"ed1fe1812cee80102262dd3b7e170759fbeab86a","datavalue":{"value":{"text":"\u0410\u0440\u0441\u0442\u0430\u043d","language":"ky"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$3D9597D3-E35F-4EFF-9CAF-E013B45F283F","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"a0868f5f83bb886a408aa9b25b95dbfc59bde4dc","datavalue":{"value":{"text":"Leo","language":"la"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$4D650414-6AFE-430F-892F-B7774AC7AF70","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"054af77b10151632045612df9b96313dfcc3550c","datavalue":{"value":{"text":"Liew","language":"li"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$D5B466A8-AEFB-4083-BF3E-194C5CE45CD3","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"9193a46891a365ee1b0a17dd6e2591babc642811","datavalue":{"value":{"text":"Nkosi","language":"ln"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$55F213DF-5AAB-4490-83CB-B9E5D2B894CD","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"c5952ec6b650f1c66f37194eb88c2889560740b2","datavalue":{"value":{"text":"Li\u016btas","language":"lt"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$8551F80C-A244-4351-A98A-8A9F37A736A2","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"e3541d0807682631f8fff2d224b2cb1b3d2a4c11","datavalue":{"value":{"text":"Lauva","language":"lv"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$488A2D59-533A-4C02-8AC3-01241FE63D94","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"22e20da399aff10787267691b5211b6fc0bddf38","datavalue":{"value":{"text":"\u041b\u0430\u0432 (lav)","language":"mk"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$9E2377E9-1D37-4BBC-A409-1C40CDD99A86","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"fe4c9bc3b3cce21a779f72fae808f8ed213d226b","datavalue":{"value":{"text":"\u0d38\u0d3f\u0d02\u0d39\u0d02 (simham)","language":"ml"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$8BEA9E08-4687-434A-9FB4-4B23B2C40838","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"85aa09066722caf2181681a24575ad89ca76210e","datavalue":{"value":{"text":"si\u1e45ha)","language":"mr"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$46B51EF5-7ADB-4637-B744-89AD1E3B5D19","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"441f3832d6e3c4439c6986075096c7021a0939dd","datavalue":{"value":{"text":"\u0936\u0947\u0930 (\u015a\u0113ra)","language":"mr"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$12BBC825-32E3-4026-A5E5-0330DEB21D79","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"89b35a359c3891dce190d778e9ae0a9634cfd71f","datavalue":{"value":{"text":"\u0938\u093f\u0902\u0939 (singh","language":"mr"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$006148E2-658F-4C74-9C3E-26488B7AEB8D","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"5723b45deee51dfe5a2555f2db17bad14acb298a","datavalue":{"value":{"text":"Iljun","language":"mt"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$13D221F5-9763-4550-9CC3-9A697286B785","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"d1ce3ab04f25af38248152eb8caa286b63366c2a","datavalue":{"value":{"text":"Leeuw","language":"nl"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$65E80D17-6F20-4BAE-A2B4-DD934C0BE153","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"12f3384cc32e65dfb501e2fee19ccf709f9df757","datavalue":{"value":{"text":"L\u00f8ve","language":"nn"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$78E95514-1969-4DA3-97CD-0DBADF1223E7","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"a3fedaf780a0d004ba318881f6adbe173750d09e","datavalue":{"value":{"text":"L\u00f8ve","language":"nb"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$809DE1EA-861E-4813-BED7-D9C465341CB3","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"695d2ef10540ba13cf8b3541daa1d39fd720eea0","datavalue":{"value":{"text":"N\u00e1shd\u00f3\u00edtsoh bitsiij\u012f\u02bc dadit\u0142\u02bcoo\u00edg\u00ed\u00ed","language":"nv"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$E9EDAF16-6650-40ED-B888-C524BD00DF40","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"3c143e8a8cebf92d76d3ae2d7e3bb3f87e963fb4","datavalue":{"value":{"text":"\u0a2c\u0a71\u0a2c\u0a30 \u0a38\u0a3c\u0a47\u0a30","language":"pa"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$13AE1DAB-4B29-49A5-9893-C0014C61D21E","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"195e48d11222aec830fb1d5c2de898c9528abc57","datavalue":{"value":{"text":"lew afryka\u0144ski","language":"pl"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$6966C1C3-9DD6-48BC-B511-B0827642E41D","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"8bd3ae632e7731ae9e72c50744383006ec6eb73e","datavalue":{"value":{"text":"Le\u00e3o","language":"pt"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$BD454649-347E-4AE5-81B8-360C16C7CDA7","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"79d3336733b7bf4b7dadffd6d6ebabdb892074d1","datavalue":{"value":{"text":"Leu","language":"ro"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$7323EF68-7AA0-4D38-82D8-0A94E61A26F0","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"376b852a92b6472e969ae7b995c4aacea23955eb","datavalue":{"value":{"text":"\u041b\u0435\u0432 (Lev)","language":"ru"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$A7C413B9-0916-4534-941D-C24BA0334816","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"aa323e0bea79d79900227699b3d42d689a772ca1","datavalue":{"value":{"text":"Lioni","language":"sc"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$2EF83D2C-0DB9-4D3C-8FDD-86237E566260","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"a290fe08983742eac8b5bc479022564fb6b2ce81","datavalue":{"value":{"text":"Lev","language":"sl"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$B276673A-08C1-47E2-99A9-D0861321E157","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"d3b070ff1452d47f87c109a9e0bfa52e61b24a4e","datavalue":{"value":{"text":"Libubesi","language":"ss"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$86BFAB38-1DB8-4903-A17D-A6B8E81819CC","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"3adea59d97f3caf9bb6b1c3d7ae6365f7f656dca","datavalue":{"value":{"text":"Tau","language":"st"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$2FA8893D-2401-42E9-8DC3-288CC1DEDB0C","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"0e73b32fe31a107a95de83706a12f2db419c6909","datavalue":{"value":{"text":"Lejon","language":"sv"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$1A8E006E-CC7B-4066-9DE7-9B82D096779E","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"34550af2fdc48f77cf66cabc5c59d1acf1d8afd0","datavalue":{"value":{"text":"Simba","language":"sw"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$B02CA616-44CF-4AA6-9734-2C05810131EB","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"701f87cf9926c9af2c41434ff130dcb234a6cd95","datavalue":{"value":{"text":"\u0b9a\u0bbf\u0b99\u0bcd\u0b95\u0bae\u0bcd","language":"ta"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$DA87A994-A002-45AD-A71F-99FB72F8B92F","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"856fd4809c90e3c34c6876e4410661dc04f5da8d","datavalue":{"value":{"text":"\u0e2a\u0e34\u0e07\u0e42\u0e15","language":"th"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$BDA8E989-3537-4662-8CC3-33534705A7F1","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"f8598a8369426da0c86bf8bab356a927487eae66","datavalue":{"value":{"text":"Aslan","language":"tr"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$AAE5F227-C0DB-4DF3-B1F4-517699BBDDF1","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"f3c8320bd46913aee164999ab7f68388c1bd9920","datavalue":{"value":{"text":"\u041b\u0435\u0432 (Lev)","language":"uk"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$494C3503-6016-4539-83AF-6344173C2DCB","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"6cc2d534293320533e15dc713f1d2c07b3811b6a","datavalue":{"value":{"text":"Leon","language":"vec"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$E6F1DA81-9F36-4CC8-B57E-95E3BDC2F5D0","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"32553481e45abf6f5e6292baea486e978c36f8fe","datavalue":{"value":{"text":"S\u01b0 t\u1eed","language":"vi"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$11D7996C-0492-41CC-AEE7-3C136172DFC7","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"69077fc29f9251d1de124cd3f3c45cd6f0bb6b65","datavalue":{"value":{"text":"\u05dc\u05d9\u05d9\u05d1","language":"yi"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$969FEF9A-C1C7-41FE-8181-07F6D87B0346","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"e3aaa8cde18be4ea6b4af6ca62b83e7dc23d76e1","datavalue":{"value":{"text":"\u72ee\u5b50 (sh\u012bzi)","language":"zh"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$3BC22F6C-F460-4354-9BA2-28CEDA9FF170","rank":"normal","references":[{"hash":"2e0c13df5b13edc9b3db9d8129e466c0894710ac","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"2b1e96d67dc01973d72472f712fd98ce87c6f0d7","datavalue":{"value":{"entity-type":"item","numeric-id":13679,"id":"Q13679"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"98f5efae94b2bb9f8ffee6c677ee71f836743ef6","datavalue":{"value":{"text":"Lion d'Afrique","language":"fr"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$62D09BBF-718A-4139-AF50-DA4185ED67F2","rank":"normal","references":[{"hash":"362e3c5d6de1d193ef97205ba38834ba075191fc","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"ba14d022d7e0c8b74595e7b8aaa1bc2451dd806a","datavalue":{"value":{"entity-type":"item","numeric-id":32059,"id":"Q32059"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"c7813bad20c2553e26e45c37e3502ce7252312df","datavalue":{"value":{"time":"+2016-10-20T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"c584bdbd3cdc1215292a4971b920c684d103ea06","datavalue":{"value":{"text":"African Lion","language":"en"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$C871BB58-C689-4DBA-A088-DAC205377979","rank":"normal","references":[{"hash":"eada84c58a38325085267509899037535799e978","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"ba14d022d7e0c8b74595e7b8aaa1bc2451dd806a","datavalue":{"value":{"entity-type":"item","numeric-id":32059,"id":"Q32059"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"3e51c3c32949f8a45f2c3331f55ea6ae68ecf3fe","datavalue":{"value":{"time":"+2016-10-21T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"1d03eace9366816c6fda340c0390caac2f3cea8e","datavalue":{"value":{"text":"L\u00e9iw","language":"lb"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$c65c7614-4d6e-3a87-9771-4f8c13618249","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"925c7abced1e89fa7e8000dc9dc78627cdac9769","datavalue":{"value":{"text":"Lle\u00f3n","language":"ast"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$1024eadb-45dd-7d9a-15f6-8602946ba661","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"0bda7868c3f498ba6fde78d46d0fbcf286e42dd8","datavalue":{"value":{"text":"\u0644\u064e\u064a\u0652\u062b\u064c","language":"ar"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$c226ff70-48dd-7b4d-00ff-7a683fe510aa","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"28de99c4aa35cc049cf8c9dd18af1791944137d9","datavalue":{"value":{"text":"\u10da\u10dd\u10db\u10d8","language":"ka"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$8fe60d1a-465a-9614-cbe4-595e22429b0c","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"4550db0f44e21c5eadeaa5a1d8fc614c9eb05f52","datavalue":{"value":{"text":"leon","language":"ga"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$4950cb9c-4f1e-ce27-0d8c-ba3f18096044","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P1843","hash":"9d268eb76ed921352c205b3f890d1f9428f638f3","datavalue":{"value":{"text":"Singa","language":"ms"},"type":"monolingualtext"},"datatype":"monolingualtext"},"type":"statement","id":"Q140$67401360-49dd-b13c-8269-e703b30c9a53","rank":"normal"}],"P627":[{"mainsnak":{"snaktype":"value","property":"P627","hash":"3642ac96e05180279c47a035c129d3af38d85027","datavalue":{"value":"15951","type":"string"},"datatype":"string"},"type":"statement","id":"Q140$6BE03095-BC68-4CE5-BB99-9F3E33A6F31D","rank":"normal","references":[{"hash":"182efbdb9110d036ca433f3b49bd3a1ae312858b","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"ba14d022d7e0c8b74595e7b8aaa1bc2451dd806a","datavalue":{"value":{"entity-type":"item","numeric-id":32059,"id":"Q32059"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"8c1c5174f4811115ea8a0def725fdc074c2ef036","datavalue":{"value":{"time":"+2016-07-10T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]}],"P2833":[{"mainsnak":{"snaktype":"value","property":"P2833","hash":"519877b77b20416af2401e5c0645954c6700d6fd","datavalue":{"value":"panthera-leo","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$C0A723AE-ED2E-4FDC-827F-496E4CF29A52","rank":"normal"}],"P3063":[{"mainsnak":{"snaktype":"value","property":"P3063","hash":"81cdb0273eaf0a0126b62e2ff43b8e09505eea54","datavalue":{"value":{"amount":"+108","unit":"http://www.wikidata.org/entity/Q573","upperBound":"+116","lowerBound":"+100"},"type":"quantity"},"datatype":"quantity"},"type":"statement","id":"Q140$878ff87d-40d0-bb2b-c83d-4cef682c2687","rank":"normal","references":[{"hash":"7d748004a43983fabae420123742fda0e9b52840","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"f618501ace3a6524b053661d067b775547f96f58","datavalue":{"value":{"entity-type":"item","numeric-id":26706243,"id":"Q26706243"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P478":[{"snaktype":"value","property":"P478","hash":"ca3c5e6054c169ee3d0dfaf660f3eecd77942070","datavalue":{"value":"4","type":"string"},"datatype":"string"}],"P304":[{"snaktype":"value","property":"P304","hash":"dd1977567f22f4cf510adfaadf5e3574813b3521","datavalue":{"value":"46","type":"string"},"datatype":"string"}]},"snaks-order":["P248","P478","P304"]}]}],"P3031":[{"mainsnak":{"snaktype":"value","property":"P3031","hash":"e6271e8d12b20c9735d2bbd80eed58581059bf3a","datavalue":{"value":"PNTHLE","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$65AD2857-AB65-4CC0-9AB9-9D6C924784FE","rank":"normal"}],"P3151":[{"mainsnak":{"snaktype":"value","property":"P3151","hash":"e85e5599d303d9a6bb360f3133fb69a76d98d0e2","datavalue":{"value":"41964","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$15D7A4EB-F0A3-4C61-8D2B-E557D7BF5CF7","rank":"normal"}],"P3186":[{"mainsnak":{"snaktype":"value","property":"P3186","hash":"85ec7843064210afdfef6ec565a47f229c6d15e5","datavalue":{"value":"644245","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$6903E136-2DB2-42C9-98CB-82F61208FDAD","rank":"normal","references":[{"hash":"5790a745e549ea7e4e6d7ca467148b544529ba96","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"c897ca3efd1604ef7b80a14ac0d2b8d6849c0856","datavalue":{"value":{"entity-type":"item","numeric-id":26936509,"id":"Q26936509"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"555ca5385c445e4fd4762281d4873682eff2ce30","datavalue":{"value":{"time":"+2016-09-24T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]},{"hash":"3edd37192f877cad0ff97acc3db56ef2cc83945b","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"4f7c4fd187630ba8cbb174c2756113983df4ce82","datavalue":{"value":{"entity-type":"item","numeric-id":45029859,"id":"Q45029859"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"56b6aa0388c9a2711946589902bc195718bb0675","datavalue":{"value":{"time":"+2017-12-26T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]},{"hash":"1318ed8ea451b84fe98461305665d8688603bab3","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"0fbeeecce08896108ed797d8ec22c7c10a6015e2","datavalue":{"value":{"entity-type":"item","numeric-id":45029998,"id":"Q45029998"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"4bac1c0d2ffc45d91b51fc0881eb6bcc7916e854","datavalue":{"value":{"time":"+2018-01-02T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]},{"hash":"6f761664a6f331d95bbaa1434447d82afd597a93","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"6c09d1d89e83bd0dfa6c94e01d24a9a47489d83e","datavalue":{"value":{"entity-type":"item","numeric-id":58035056,"id":"Q58035056"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"03182012ca72fcd757b8a1fe05ba927cbe9ef374","datavalue":{"value":{"time":"+2018-11-02T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]}],"P3485":[{"mainsnak":{"snaktype":"value","property":"P3485","hash":"df4e58fc2a196833ab3e33483099e2481e61ba9e","datavalue":{"value":{"amount":"+112","unit":"1"},"type":"quantity"},"datatype":"quantity"},"type":"statement","id":"Q140$4B70AA09-AE2F-4F4C-9BAF-09890CDA11B8","rank":"normal","references":[{"hash":"fa278ebfc458360e5aed63d5058cca83c46134f1","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"e4f6d9441d0600513c4533c672b5ab472dc73694","datavalue":{"value":{"entity-type":"item","numeric-id":328,"id":"Q328"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]}],"P3827":[{"mainsnak":{"snaktype":"value","property":"P3827","hash":"6bb26d581721d7330c407259d46ab5e25cc4a6b1","datavalue":{"value":"lions","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$CCDE6F7D-B4EA-4875-A4D6-5649ACFA8E2F","rank":"normal"}],"P268":[{"mainsnak":{"snaktype":"value","property":"P268","hash":"a20cdf81e39cd47f4da30073671792380029924c","datavalue":{"value":"11932251d","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$000FDB77-C70C-4464-9F00-605787964BBA","rank":"normal","references":[{"hash":"d4bd87b862b12d99d26e86472d44f26858dee639","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"f30cbd35620c4ea6d0633aaf0210a8916130469b","datavalue":{"value":{"entity-type":"item","numeric-id":8447,"id":"Q8447"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]}],"P3417":[{"mainsnak":{"snaktype":"value","property":"P3417","hash":"e3b5d21350aef37f27ad8b24142d6b83d9eec0a6","datavalue":{"value":"Lions","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$1f96d096-4e4b-06de-740f-7b7215e5ae3f","rank":"normal"}],"P4024":[{"mainsnak":{"snaktype":"value","property":"P4024","hash":"a698e7dcd6f9b0b00ee8e02846c668db83064833","datavalue":{"value":"Panthera_leo","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$F5DC21E8-BF52-4A0D-9A15-63B89297BD70","rank":"normal","references":[{"hash":"d4bd87b862b12d99d26e86472d44f26858dee639","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"f30cbd35620c4ea6d0633aaf0210a8916130469b","datavalue":{"value":{"entity-type":"item","numeric-id":8447,"id":"Q8447"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]}],"P1225":[{"mainsnak":{"snaktype":"value","property":"P1225","hash":"9af40267f10f15926877e9a3f78faeab7b0dda82","datavalue":{"value":"10665610","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$268074ED-3CD7-46C9-A8FF-8C3679C45547","rank":"normal"}],"P4728":[{"mainsnak":{"snaktype":"value","property":"P4728","hash":"37eafa980604019b327b1a3552313fb7ae256697","datavalue":{"value":"105514","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$50C24ECC-C42C-4A58-8F34-6AF0AC6C4EFE","rank":"normal","references":[{"hash":"d4bd87b862b12d99d26e86472d44f26858dee639","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"f30cbd35620c4ea6d0633aaf0210a8916130469b","datavalue":{"value":{"entity-type":"item","numeric-id":8447,"id":"Q8447"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]}],"P3219":[{"mainsnak":{"snaktype":"value","property":"P3219","hash":"dedb8825588940caff5a34d04a0e69af296f05dd","datavalue":{"value":"lion","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$2A5A2CA3-AB6E-4F68-927F-042D1BD22915","rank":"normal"}],"P1343":[{"mainsnak":{"snaktype":"value","property":"P1343","hash":"5b0ef3d5413cd39d887fbe70d2d3b3f4a94ea9d8","datavalue":{"value":{"entity-type":"item","numeric-id":1138524,"id":"Q1138524"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","qualifiers":{"P805":[{"snaktype":"value","property":"P805","hash":"f7bf629d348040dd1a59dc5a3199edb50279e8f5","datavalue":{"value":{"entity-type":"item","numeric-id":19997008,"id":"Q19997008"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P805"],"id":"Q140$DFE4D4B0-0D84-41F2-B448-4A81AC982927","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P1343","hash":"6bc15c6f82feca4f3b173c90209a416f99464cac","datavalue":{"value":{"entity-type":"item","numeric-id":4086271,"id":"Q4086271"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","qualifiers":{"P805":[{"snaktype":"value","property":"P805","hash":"69ace59e966574e4ffb454d26940a58fb45ed7de","datavalue":{"value":{"entity-type":"item","numeric-id":25295952,"id":"Q25295952"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P805"],"id":"Q140$b82b0461-4ff0-10ac-9825-d4b95fc7a85a","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P1343","hash":"ecb04d74140f2ee856c06658b03ec90a21c2edf2","datavalue":{"value":{"entity-type":"item","numeric-id":1970746,"id":"Q1970746"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","qualifiers":{"P805":[{"snaktype":"value","property":"P805","hash":"169607f1510535f3e1c5e7debce48d1903510f74","datavalue":{"value":{"entity-type":"item","numeric-id":30202801,"id":"Q30202801"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P805"],"id":"Q140$bd49e319-477f-0cd2-a404-642156321081","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P1343","hash":"88389772f86dcd7d415ddd029f601412e5cc894a","datavalue":{"value":{"entity-type":"item","numeric-id":602358,"id":"Q602358"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","qualifiers":{"P805":[{"snaktype":"value","property":"P805","hash":"67f2e59eb3f6480bdbaa3954055dfbf8fd045bc4","datavalue":{"value":{"entity-type":"item","numeric-id":24451091,"id":"Q24451091"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P805"],"id":"Q140$906ae22e-4c63-d325-c91e-dc3ee6b7504d","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P1343","hash":"42346dfe9209b7359c1f5db829a368b38d407797","datavalue":{"value":{"entity-type":"item","numeric-id":19180675,"id":"Q19180675"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","qualifiers":{"P805":[{"snaktype":"value","property":"P805","hash":"195bd04166c04364a657fcd18abd1a082dad3cb0","datavalue":{"value":{"entity-type":"item","numeric-id":24758519,"id":"Q24758519"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P805"],"id":"Q140$92e7eeb1-4a72-9abf-4260-a96abc32bc42","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P1343","hash":"7d6f86cef085693a10b0e0663a0960f58d0e15e2","datavalue":{"value":{"entity-type":"item","numeric-id":4173137,"id":"Q4173137"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","qualifiers":{"P805":[{"snaktype":"value","property":"P805","hash":"75e5bdfbbf8498b195840749ef3a9bd309b796f7","datavalue":{"value":{"entity-type":"item","numeric-id":25054587,"id":"Q25054587"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P805"],"id":"Q140$6c9c319a-4e71-540e-8866-a6017f0e6bae","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P1343","hash":"75dd89e79770a3e631dbba27144940f8f1bc1773","datavalue":{"value":{"entity-type":"item","numeric-id":1768721,"id":"Q1768721"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","qualifiers":{"P805":[{"snaktype":"value","property":"P805","hash":"a1b448ff5f8818a2254835e0816a03a785bac665","datavalue":{"value":{"entity-type":"item","numeric-id":96599885,"id":"Q96599885"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P805"],"id":"Q140$A0FD93F4-A401-47A1-BC8E-F0D35A8E8BAD","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P1343","hash":"4cfd4eb1fe49d401455df557a7d9b1154f22a725","datavalue":{"value":{"entity-type":"item","numeric-id":3181656,"id":"Q3181656"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","qualifiers":{"P1932":[{"snaktype":"value","property":"P1932","hash":"a3f6e8ce10c4527693415dbc99b5ea285b2f411c","datavalue":{"value":"Lion, The","type":"string"},"datatype":"string"}]},"qualifiers-order":["P1932"],"id":"Q140$100f480e-4ad9-b340-8251-4e875d00315d","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P1343","hash":"d5011798f92464584d8ccfc5f19f18f3659668bb","datavalue":{"value":{"entity-type":"item","numeric-id":106727050,"id":"Q106727050"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","qualifiers":{"P1810":[{"snaktype":"value","property":"P1810","hash":"7d78547303d5e9e014a7c8cef6072faee91088ce","datavalue":{"value":"Lions","type":"string"},"datatype":"string"}],"P585":[{"snaktype":"value","property":"P585","hash":"ffb837135313cad3b2545c4b9ce5ee416deda3e2","datavalue":{"value":{"time":"+2021-05-07T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"qualifiers-order":["P1810","P585"],"id":"Q140$A4D208BD-6A69-4561-B402-2E17AAE6E028","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P1343","hash":"d12a9ecb0df8fce076df898533fea0339e5881bd","datavalue":{"value":{"entity-type":"item","numeric-id":10886720,"id":"Q10886720"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","qualifiers":{"P805":[{"snaktype":"value","property":"P805","hash":"52ddab8de77b01303d508a1de615ca13060ec188","datavalue":{"value":{"entity-type":"item","numeric-id":107513600,"id":"Q107513600"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P805"],"id":"Q140$07daf548-4c8d-fa7c-16f4-4c7062f7e48a","rank":"normal"}],"P4733":[{"mainsnak":{"snaktype":"value","property":"P4733","hash":"fc789f67f6d4d9b5879a8631eefe61f51a60f979","datavalue":{"value":{"entity-type":"item","numeric-id":3177438,"id":"Q3177438"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"Q140$3773ba15-4723-261a-f9a8-544496938efa","rank":"normal","references":[{"hash":"649ae5511d5389d870d19e83543fa435de796536","snaks":{"P143":[{"snaktype":"value","property":"P143","hash":"9931bb1a17358e94590f8fa0b9550de881616d97","datavalue":{"value":{"entity-type":"item","numeric-id":784031,"id":"Q784031"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P143"]}]}],"P5019":[{"mainsnak":{"snaktype":"value","property":"P5019","hash":"44aac3d8a2bd240b4bc81741a0980dc48781181b","datavalue":{"value":"l\u00f6we","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$2be40b22-49f1-c9e7-1812-8e3fd69d662d","rank":"normal"}],"P2924":[{"mainsnak":{"snaktype":"value","property":"P2924","hash":"710d75c07e28936461d03b20b2fc7455599301a1","datavalue":{"value":"2135124","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$6326B120-CE04-4F02-94CA-D7BBC2589A39","rank":"normal"}],"P5055":[{"mainsnak":{"snaktype":"value","property":"P5055","hash":"c5264fc372b7e66566d54d73f86c8ab8c43fb033","datavalue":{"value":"10196306","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$F8D43B92-CC3A-4967-A28F-C3E6308946F6","rank":"normal","references":[{"hash":"7131076724beb97fed351cb7e7f6ac6d61dd05b9","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"1e3ad3cb9e0170e28b7c7c335fba55cafa6ef789","datavalue":{"value":{"entity-type":"item","numeric-id":51885189,"id":"Q51885189"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"2b1446fcfcd471ab6d36521b4ad2ac183ff8bc0d","datavalue":{"value":{"time":"+2018-06-07T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]}],"P5221":[{"mainsnak":{"snaktype":"value","property":"P5221","hash":"623ca9614dd0d8b8720bf35b4d57be91dcef5fe6","datavalue":{"value":"123566","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$472fe544-402d-2574-6b2e-98c5b01bb294","rank":"normal"}],"P5698":[{"mainsnak":{"snaktype":"value","property":"P5698","hash":"e966694183143d709403fae7baabb5fdf98d219a","datavalue":{"value":"70719","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$EF3F712D-B0E5-4151-81E4-67804D6241E6","rank":"normal"}],"P5397":[{"mainsnak":{"snaktype":"value","property":"P5397","hash":"49a827bc1853a3b5612b437dd61eb5c28dc0bab0","datavalue":{"value":"12799","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$DE37BF10-A59D-48F1-926A-7303EDEEDDD0","rank":"normal"}],"P6033":[{"mainsnak":{"snaktype":"value","property":"P6033","hash":"766727ded3adbbfec0bed77affc89ea4e5214d65","datavalue":{"value":"panthera-leo","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$A27BADCC-0F72-45A5-814B-BDE62BD7A1B4","rank":"normal"}],"P18":[{"mainsnak":{"snaktype":"value","property":"P18","hash":"d3ceb5bb683335c91781e4d52906d2fb1cc0c35d","datavalue":{"value":"Lion waiting in Namibia.jpg","type":"string"},"datatype":"commonsMedia"},"type":"statement","qualifiers":{"P21":[{"snaktype":"value","property":"P21","hash":"0576a008261e5b2544d1ff3328c94bd529379536","datavalue":{"value":{"entity-type":"item","numeric-id":44148,"id":"Q44148"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P2096":[{"snaktype":"value","property":"P2096","hash":"6923fafa02794ae7d0773e565de7dd49a2694b38","datavalue":{"value":{"text":"Lle\u00f3","language":"ca"},"type":"monolingualtext"},"datatype":"monolingualtext"},{"snaktype":"value","property":"P2096","hash":"563784f05211416fda8662a0773f52165ccf6c2a","datavalue":{"value":{"text":"Machu de lle\u00f3n en Namibia","language":"ast"},"type":"monolingualtext"},"datatype":"monolingualtext"},{"snaktype":"value","property":"P2096","hash":"52722803d98964d77b79d3ed62bd24b4f25e6993","datavalue":{"value":{"text":"\u043b\u044a\u0432","language":"bg"},"type":"monolingualtext"},"datatype":"monolingualtext"}]},"qualifiers-order":["P21","P2096"],"id":"q140$5903FDF3-DBBD-4527-A738-450EAEAA45CB","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P18","hash":"6907d4c168377a18d6a5eb390ab32a7da42d8218","datavalue":{"value":"Okonjima Lioness.jpg","type":"string"},"datatype":"commonsMedia"},"type":"statement","qualifiers":{"P21":[{"snaktype":"value","property":"P21","hash":"a274865baccd3ff04c28d5ffdcc12e0079f5a201","datavalue":{"value":{"entity-type":"item","numeric-id":43445,"id":"Q43445"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P2096":[{"snaktype":"value","property":"P2096","hash":"a9d1363e8fc83ba822c45a81de59fe5b8eb434cf","datavalue":{"value":{"text":"\u043b\u044a\u0432\u0438\u0446\u0430","language":"bg"},"type":"monolingualtext"},"datatype":"monolingualtext"},{"snaktype":"value","property":"P2096","hash":"b36ab7371664b7b62ee7be65db4e248074a5330c","datavalue":{"value":{"text":"Lleona n'Okonjima Lodge, Namibia","language":"ast"},"type":"monolingualtext"},"datatype":"monolingualtext"},{"snaktype":"value","property":"P2096","hash":"31c78a574eabc0426d7984aa4988752e35b71f0c","datavalue":{"value":{"text":"lwica","language":"pl"},"type":"monolingualtext"},"datatype":"monolingualtext"}]},"qualifiers-order":["P21","P2096"],"id":"Q140$4da15225-f7dc-4942-a685-0669e5d3af14","rank":"normal"}],"P6573":[{"mainsnak":{"snaktype":"value","property":"P6573","hash":"c27b457b12eeecb053d60af6ecf9b0baa133bef5","datavalue":{"value":"L\u00f6we","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$45B1C3EB-E335-4245-A193-8C48B4953E51","rank":"normal"}],"P443":[{"mainsnak":{"snaktype":"value","property":"P443","hash":"8a9afb9293804f976c415060900bf9afbc2cfdff","datavalue":{"value":"LL-Q188 (deu)-Sebastian Wallroth-L\u00f6we.wav","type":"string"},"datatype":"commonsMedia"},"type":"statement","qualifiers":{"P407":[{"snaktype":"value","property":"P407","hash":"46bfd327b830f66f7061ea92d1be430c135fa91f","datavalue":{"value":{"entity-type":"item","numeric-id":188,"id":"Q188"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P407"],"id":"Q140$5EC64299-429F-45E8-B18F-19325401189C","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P443","hash":"7d058dfd1e8a41f026974faec3dc0588e29c6854","datavalue":{"value":"LL-Q150 (fra)-Ash Crow-lion.wav","type":"string"},"datatype":"commonsMedia"},"type":"statement","qualifiers":{"P407":[{"snaktype":"value","property":"P407","hash":"d197d0a5efa4b4c23a302a829dd3ef43684fe002","datavalue":{"value":{"entity-type":"item","numeric-id":150,"id":"Q150"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P407"],"id":"Q140$A4575261-6577-4EF6-A0C9-DA5FA523D1C2","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P443","hash":"79b9f51c9b4eec305813d5bb697b403d798cf1c5","datavalue":{"value":"LL-Q33965 (sat)-Joy sagar Murmu-\u1c60\u1c69\u1c5e.wav","type":"string"},"datatype":"commonsMedia"},"type":"statement","qualifiers":{"P407":[{"snaktype":"value","property":"P407","hash":"58ae6998321952889f733126c11c582eeef20e72","datavalue":{"value":{"entity-type":"item","numeric-id":33965,"id":"Q33965"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P407"],"id":"Q140$7eedc8fa-4d1c-7ee9-3c67-0c89ef464d9f","rank":"normal","references":[{"hash":"d0b5c88b6f49dda9160c706291a9b8645825d99c","snaks":{"P854":[{"snaktype":"value","property":"P854","hash":"38c1012cea9eb73cf1bd11eba0c2f745d2463340","datavalue":{"value":"https://lingualibre.org/wiki/Q403065","type":"string"},"datatype":"url"}]},"snaks-order":["P854"]}]}],"P1296":[{"mainsnak":{"snaktype":"value","property":"P1296","hash":"c1f872d4cd22219a7315c0198a83c1918ded97ee","datavalue":{"value":"0120024","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$6C51384B-2EBF-4E6B-9201-A44F0A145C04","rank":"normal"}],"P486":[{"mainsnak":{"snaktype":"value","property":"P486","hash":"b7003b0fb28287301200b6b3871a5437d877913b","datavalue":{"value":"D008045","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$B2F98DD2-B679-43DD-B731-FA33FB1EE4B9","rank":"normal"}],"P989":[{"mainsnak":{"snaktype":"value","property":"P989","hash":"132884b2a696a8b56c8b1460e126f745e2fa6d01","datavalue":{"value":"Ru-Lion (intro).ogg","type":"string"},"datatype":"commonsMedia"},"type":"statement","qualifiers":{"P407":[{"snaktype":"value","property":"P407","hash":"d291ddb7cd77c94a7bd709a8395934147e0864fc","datavalue":{"value":{"entity-type":"item","numeric-id":7737,"id":"Q7737"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P407"],"id":"Q140$857D8831-673B-427E-A182-6A9FFA980424","rank":"normal"}],"P51":[{"mainsnak":{"snaktype":"value","property":"P51","hash":"73b0e8c8458ebc27374fd08d8ef5241f2f28e3e9","datavalue":{"value":"Lion raring-sound1TamilNadu178.ogg","type":"string"},"datatype":"commonsMedia"},"type":"statement","id":"Q140$1c254aff-48b1-d3c5-930c-b360ce6fe043","rank":"normal"}],"P4212":[{"mainsnak":{"snaktype":"value","property":"P4212","hash":"e006ce3295d617a4818dc758c28f444446538019","datavalue":{"value":"pcrt5TAeZsO7W4","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$AD6CD534-1FD2-4AC7-9CF8-9D2B4C46927C","rank":"normal"}],"P2067":[{"mainsnak":{"snaktype":"value","property":"P2067","hash":"97a863433c30b47a6175abb95941d185397ea14a","datavalue":{"value":{"amount":"+1.65","unit":"http://www.wikidata.org/entity/Q11570"},"type":"quantity"},"datatype":"quantity"},"type":"statement","qualifiers":{"P642":[{"snaktype":"value","property":"P642","hash":"f5e24bc6ec443d6cb3678e4561bc298090b54f60","datavalue":{"value":{"entity-type":"item","numeric-id":4128476,"id":"Q4128476"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P642"],"id":"Q140$198da244-7e66-4258-9434-537e9ce0ffab","rank":"normal","references":[{"hash":"94a79329d5eac70f7ddb005e0d1dc78c53e77797","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"4a7fef7ea264a7c71765ce60e3d42f4c043c9646","datavalue":{"value":{"entity-type":"item","numeric-id":45106562,"id":"Q45106562"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P248"]}]},{"mainsnak":{"snaktype":"value","property":"P2067","hash":"ba9933059ce368e3afde1e96d78b1217172c954e","datavalue":{"value":{"amount":"+188","unit":"http://www.wikidata.org/entity/Q11570"},"type":"quantity"},"datatype":"quantity"},"type":"statement","qualifiers":{"P642":[{"snaktype":"value","property":"P642","hash":"b388540fc86300a506b3a753ec58dec445525ffa","datavalue":{"value":{"entity-type":"item","numeric-id":78101716,"id":"Q78101716"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P21":[{"snaktype":"value","property":"P21","hash":"0576a008261e5b2544d1ff3328c94bd529379536","datavalue":{"value":{"entity-type":"item","numeric-id":44148,"id":"Q44148"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P642","P21"],"id":"Q140$a3092626-4295-efb8-bbb6-eed913d02fc7","rank":"normal","references":[{"hash":"94a79329d5eac70f7ddb005e0d1dc78c53e77797","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"4a7fef7ea264a7c71765ce60e3d42f4c043c9646","datavalue":{"value":{"entity-type":"item","numeric-id":45106562,"id":"Q45106562"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P248"]}]},{"mainsnak":{"snaktype":"value","property":"P2067","hash":"6951281811b2a8a3a78044e2003d6c162d5ba1a3","datavalue":{"value":{"amount":"+126","unit":"http://www.wikidata.org/entity/Q11570"},"type":"quantity"},"datatype":"quantity"},"type":"statement","qualifiers":{"P642":[{"snaktype":"value","property":"P642","hash":"b388540fc86300a506b3a753ec58dec445525ffa","datavalue":{"value":{"entity-type":"item","numeric-id":78101716,"id":"Q78101716"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P21":[{"snaktype":"value","property":"P21","hash":"a274865baccd3ff04c28d5ffdcc12e0079f5a201","datavalue":{"value":{"entity-type":"item","numeric-id":43445,"id":"Q43445"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P642","P21"],"id":"Q140$20d80fe2-4796-23d1-42c2-c103546aa874","rank":"normal","references":[{"hash":"94a79329d5eac70f7ddb005e0d1dc78c53e77797","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"4a7fef7ea264a7c71765ce60e3d42f4c043c9646","datavalue":{"value":{"entity-type":"item","numeric-id":45106562,"id":"Q45106562"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P248"]}]}],"P7725":[{"mainsnak":{"snaktype":"value","property":"P7725","hash":"e9338e052dfaa9267c2357bec2e167ca625af667","datavalue":{"value":{"amount":"+2.5","unit":"1","upperBound":"+4.0","lowerBound":"+1.0"},"type":"quantity"},"datatype":"quantity"},"type":"statement","id":"Q140$f1f04a23-0d34-484a-9419-78d12958170c","rank":"normal","references":[{"hash":"94a79329d5eac70f7ddb005e0d1dc78c53e77797","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"4a7fef7ea264a7c71765ce60e3d42f4c043c9646","datavalue":{"value":{"entity-type":"item","numeric-id":45106562,"id":"Q45106562"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P248"]}]}],"P4214":[{"mainsnak":{"snaktype":"value","property":"P4214","hash":"5a112dbdaed17b1ee3fe7a63b1f978e5fd41008a","datavalue":{"value":{"amount":"+27","unit":"http://www.wikidata.org/entity/Q577"},"type":"quantity"},"datatype":"quantity"},"type":"statement","id":"Q140$ec1ccab2-f506-4c81-9179-4625bbbbbe27","rank":"normal","references":[{"hash":"a8ccf5105b0e2623ae145dd8a9b927c9bd957ddf","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"5b45c23ddb076fe9c5accfe4a4bbd1c24c4c87cb","datavalue":{"value":{"entity-type":"item","numeric-id":83566668,"id":"Q83566668"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P248"]}]}],"P7862":[{"mainsnak":{"snaktype":"value","property":"P7862","hash":"6e74ddb544498b93407179cc9a7f9b8610762ff5","datavalue":{"value":{"amount":"+8","unit":"http://www.wikidata.org/entity/Q5151"},"type":"quantity"},"datatype":"quantity"},"type":"statement","id":"Q140$17b64a1e-4a13-9e2a-f8a2-a9317890aa53","rank":"normal","references":[{"hash":"94a79329d5eac70f7ddb005e0d1dc78c53e77797","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"4a7fef7ea264a7c71765ce60e3d42f4c043c9646","datavalue":{"value":{"entity-type":"item","numeric-id":45106562,"id":"Q45106562"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P248"]}]}],"P7818":[{"mainsnak":{"snaktype":"value","property":"P7818","hash":"5c7bac858cf66d079e6c13c88f3f001eb446cdce","datavalue":{"value":"Lion","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$C2D3546E-C42A-404A-A288-580F9C705E12","rank":"normal"}],"P7829":[{"mainsnak":{"snaktype":"value","property":"P7829","hash":"17fbb02db65a7e80691f58be750382d61148406e","datavalue":{"value":"Lion","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$74998F51-E783-40CB-A56A-3189647AB3D4","rank":"normal"}],"P7827":[{"mainsnak":{"snaktype":"value","property":"P7827","hash":"f85db9fe2c187554aefc51e5529d75e0c5af4767","datavalue":{"value":"Le\u00f3n","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$5DA64E1B-F1F1-4254-8629-985DFE8672A2","rank":"normal"}],"P7822":[{"mainsnak":{"snaktype":"value","property":"P7822","hash":"3cd23fddc416227c2ba85d91aa03dc80a8e95836","datavalue":{"value":"Leone","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$DF657EF2-67A8-4272-871D-E95B3719A8B6","rank":"normal"}],"P6105":[{"mainsnak":{"snaktype":"value","property":"P6105","hash":"8bbda0afe53fc428d3a0d9528c97d2145ee41dce","datavalue":{"value":"79432","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$2AE92335-1BC6-4B92-BAF3-9AB41608E638","rank":"normal"}],"P6864":[{"mainsnak":{"snaktype":"value","property":"P6864","hash":"6f87ce0800057dbe88f27748b3077938973eb5c8","datavalue":{"value":"85426","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$9089C4B9-59A8-45A6-821B-05C1BB4C107C","rank":"normal"}],"P2347":[{"mainsnak":{"snaktype":"value","property":"P2347","hash":"41e41b306cdd5e55007ac02da022d9f4ce230b03","datavalue":{"value":"7345","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$3CEB44D7-6C0B-4E66-87ED-37D723A1CCC8","rank":"normal","references":[{"hash":"f9bf1a1f034ddd51bd9928ac535e0f57d748e2cf","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"7133f11674741f52cadaae6029068fad9cbb52e3","datavalue":{"value":{"entity-type":"item","numeric-id":89345680,"id":"Q89345680"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P248"]}]}],"P7033":[{"mainsnak":{"snaktype":"value","property":"P7033","hash":"e31b2e07ae0ce3d3a087d3c818c7bf29c7b04b72","datavalue":{"value":"scot/9244","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$F8148EB5-7934-4491-9B40-3378B7D292A6","rank":"normal"}],"P8408":[{"mainsnak":{"snaktype":"value","property":"P8408","hash":"51c04ed4f03488e8f428256ee41eb20eabe3ff38","datavalue":{"value":"Lion","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$2855E519-BCD1-4AB3-B3E9-BB53C5CB2E22","rank":"normal","references":[{"hash":"9a681f9dd95c90224547c404e11295f4f7dcf54e","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"9d5780dddffa8746637a9929a936ab6b0f601e24","datavalue":{"value":{"entity-type":"item","numeric-id":64139102,"id":"Q64139102"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P813":[{"snaktype":"value","property":"P813","hash":"622a5a27fa5b25e7e7984974e9db494cf8460990","datavalue":{"value":{"time":"+2020-07-09T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P813"]}]}],"P8519":[{"mainsnak":{"snaktype":"value","property":"P8519","hash":"ad8031a668b5310633a04a9223714b3482d388b2","datavalue":{"value":"64570","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$ba4fa085-0e54-4226-a46b-770f7d5a995f","rank":"normal"}],"P279":[{"mainsnak":{"snaktype":"value","property":"P279","hash":"761c3439637add8f8fe3a351d6231333693835f6","datavalue":{"value":{"entity-type":"item","numeric-id":6667323,"id":"Q6667323"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"Q140$cb41b7d3-46f0-e6d9-ced6-c2803e0c06b7","rank":"normal"}],"P2670":[{"mainsnak":{"snaktype":"value","property":"P2670","hash":"6563f1e596253f1574515891267de01c5c1e688e","datavalue":{"value":{"entity-type":"item","numeric-id":17611534,"id":"Q17611534"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"Q140$24984be4-4813-b6ad-ec83-1a37b7332c8a","rank":"normal"},{"mainsnak":{"snaktype":"value","property":"P2670","hash":"684855138cc32d11b487d0178c194f10c63f5f86","datavalue":{"value":{"entity-type":"item","numeric-id":98520146,"id":"Q98520146"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"Q140$56e8c9b3-4892-e95d-f7c5-02b10ffe77e8","rank":"normal"}],"P31":[{"mainsnak":{"snaktype":"value","property":"P31","hash":"06629d890d7ab0ff85c403d8aadf57ce9809c01f","datavalue":{"value":{"entity-type":"item","numeric-id":16521,"id":"Q16521"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"q140$8EE98E5B-4A9C-4BF5-B456-FB77E8EE4E69","rank":"normal"}],"P2581":[{"mainsnak":{"snaktype":"value","property":"P2581","hash":"beca27cf7dd079eb27b7690e13a446d98448ae91","datavalue":{"value":"00049156n","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$90562c9a-4e9c-082d-d577-e0869524d9a1","rank":"normal"}],"P7506":[{"mainsnak":{"snaktype":"value","property":"P7506","hash":"0562f57f9a54c65a2d45711f6dd5dd53ce37f6f8","datavalue":{"value":"1107856","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$00d453bf-4786-bde9-63f4-2db9f3610e88","rank":"normal"}],"P5184":[{"mainsnak":{"snaktype":"value","property":"P5184","hash":"201d8de9b05ae85fe4f917c7e54c4a0218517888","datavalue":{"value":"b11s0701a","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$a2b832c9-4c5c-e402-e10d-cf2b08d35a56","rank":"normal"}],"P6900":[{"mainsnak":{"snaktype":"value","property":"P6900","hash":"f7218c6984cd57078497a62ad595b089bdd97c49","datavalue":{"value":"\u30e9\u30a4\u30aa\u30f3","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$d15d143d-4826-4860-9aa3-6a350d6bc36f","rank":"normal"}],"P3553":[{"mainsnak":{"snaktype":"value","property":"P3553","hash":"c82c6e1156e098d5ef396248c412371b90e0dc56","datavalue":{"value":"19563862","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$5edb95fa-4647-2e9a-9dbf-b68e1326eb79","rank":"normal"}],"P5337":[{"mainsnak":{"snaktype":"value","property":"P5337","hash":"793cfa52df3c5a6747c0cb5db959db944b04dbed","datavalue":{"value":"CAAqIQgKIhtDQkFTRGdvSUwyMHZNRGsyYldJU0FtcGhLQUFQAQ","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$6137dbc1-4c6a-af60-00ee-2a32c63bfdfa","rank":"normal"}],"P6200":[{"mainsnak":{"snaktype":"value","property":"P6200","hash":"0ce08dd38017230d41f530f6e97baf484f607235","datavalue":{"value":"ce2gz91pyv2t","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$01ed0f16-4a4a-213d-e457-0d4d5d670d49","rank":"normal"}],"P4527":[{"mainsnak":{"snaktype":"value","property":"P4527","hash":"b07d29aa5112080a9294a7421e46ed0b73ac96c7","datavalue":{"value":"430792","type":"string"},"datatype":"external-id"},"type":"statement","qualifiers":{"P1810":[{"snaktype":"value","property":"P1810","hash":"7d78547303d5e9e014a7c8cef6072faee91088ce","datavalue":{"value":"Lions","type":"string"},"datatype":"string"}]},"qualifiers-order":["P1810"],"id":"Q140$C37C600C-4929-4203-A06E-8D797BA9B22A","rank":"normal"}],"P8989":[{"mainsnak":{"snaktype":"value","property":"P8989","hash":"37087c42c921d83773f62d77e7360dc44504c122","datavalue":{"value":{"entity-type":"item","numeric-id":104595349,"id":"Q104595349"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"Q140$1ece61f5-c008-4750-8b67-e15337f28e86","rank":"normal"}],"P1552":[{"mainsnak":{"snaktype":"value","property":"P1552","hash":"1aa7db66bfad11e427c40ec79f3295de877967f1","datavalue":{"value":{"entity-type":"item","numeric-id":120446,"id":"Q120446"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"Q140$0bd4b0d9-49ff-b5b4-5c10-9500bc0ce19d","rank":"normal"}],"P9198":[{"mainsnak":{"snaktype":"value","property":"P9198","hash":"d3ab4ab9d788dc348d16e13fc77164ea71cef2ae","datavalue":{"value":"352","type":"string"},"datatype":"external-id"},"type":"statement","id":"Q140$C5D80C89-2862-490F-AA85-C260F32BE30B","rank":"normal"}],"P9566":[{"mainsnak":{"snaktype":"value","property":"P9566","hash":"053e0b7c15c8e5a61a71077c4cffa73b9d03005b","datavalue":{"value":{"entity-type":"item","numeric-id":3255068,"id":"Q3255068"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","id":"Q140$C7DAEA4E-B613-48A6-BFCD-88B551D1EF7A","rank":"normal","references":[{"hash":"0eedf63ac49c9b21aa7ff0a5e70b71aa6069a8ed","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"abfcfc68aa085f872d633958be83cba2ab96ce4a","datavalue":{"value":{"entity-type":"item","numeric-id":1637051,"id":"Q1637051"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P248"]},{"hash":"6db51e3163554f674ff270c93a2871c8d859a49e","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"abfcfc68aa085f872d633958be83cba2ab96ce4a","datavalue":{"value":{"entity-type":"item","numeric-id":1637051,"id":"Q1637051"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P577":[{"snaktype":"value","property":"P577","hash":"ccd6ea06a2c9c0f54f5b1f45991a659225b5f4ef","datavalue":{"value":{"time":"+2013-01-01T00:00:00Z","timezone":0,"before":0,"after":0,"precision":9,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P577"]}]}],"P508":[{"mainsnak":{"snaktype":"value","property":"P508","hash":"e87c854abf600fb5de7b9b677d94a06e18851333","datavalue":{"value":"34922","type":"string"},"datatype":"external-id"},"type":"statement","qualifiers":{"P1810":[{"snaktype":"value","property":"P1810","hash":"137692b9bcc178e7b7d232631cb607d45e2f543d","datavalue":{"value":"Leoni","type":"string"},"datatype":"string"}],"P4970":[{"snaktype":"value","property":"P4970","hash":"271ec192bf14b9eb639120c60d5961ab8692444d","datavalue":{"value":"Panthera leo","type":"string"},"datatype":"string"}]},"qualifiers-order":["P1810","P4970"],"id":"Q140$52702f98-7843-4e0e-b646-76629e04e555","rank":"normal"}],"P950":[{"mainsnak":{"snaktype":"value","property":"P950","hash":"f447323110fd744383394f91c2dfba2fc3187242","datavalue":{"value":"XX530613","type":"string"},"datatype":"external-id"},"type":"statement","qualifiers":{"P1810":[{"snaktype":"value","property":"P1810","hash":"e2b2bda5457e0d5f7859e5c54996e1884062dfd1","datavalue":{"value":"Leones","type":"string"},"datatype":"string"}]},"qualifiers-order":["P1810"],"id":"Q140$773f47cf-3133-4892-80eb-9d4dc5e97582","rank":"normal","references":[{"hash":"184729506e049d06de85686ede30c92b3e52451d","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"3b090a7bae73c288393b2c8b9846cc7ed9a58f91","datavalue":{"value":{"entity-type":"item","numeric-id":16583225,"id":"Q16583225"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}],"P854":[{"snaktype":"value","property":"P854","hash":"b16c3ffac23bb97abe5d0c4d6ccffe4d010ab71a","datavalue":{"value":"https://thes.bncf.firenze.sbn.it/termine.php?id=34922","type":"string"},"datatype":"url"}],"P813":[{"snaktype":"value","property":"P813","hash":"7721e97431215c374db84a9df785dc964a16bd17","datavalue":{"value":{"time":"+2021-06-15T00:00:00Z","timezone":0,"before":0,"after":0,"precision":11,"calendarmodel":"http://www.wikidata.org/entity/Q1985727"},"type":"time"},"datatype":"time"}]},"snaks-order":["P248","P854","P813"]}]}],"P7603":[{"mainsnak":{"snaktype":"value","property":"P7603","hash":"c86436e278d690f057cfecc86babf982948015f3","datavalue":{"value":{"entity-type":"item","numeric-id":2851528,"id":"Q2851528"},"type":"wikibase-entityid"},"datatype":"wikibase-item"},"type":"statement","qualifiers":{"P17":[{"snaktype":"value","property":"P17","hash":"18fb076bdc1c07e578546d1670ba193b768531ac","datavalue":{"value":{"entity-type":"item","numeric-id":668,"id":"Q668"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"qualifiers-order":["P17"],"id":"Q140$64262d09-4a19-3945-8a09-c2195b7614a7","rank":"normal"}],"P6800":[{"mainsnak":{"snaktype":"value","property":"P6800","hash":"1da99908e2ffdf6de901a1b8a2dbab0c62886565","datavalue":{"value":"http://www.ensembl.org/Panthera_leo","type":"string"},"datatype":"url"},"type":"statement","id":"Q140$87DC0D37-FC9E-4FFE-B92D-1A3A7C019A1D","rank":"normal","references":[{"hash":"53eb51e25c6356d2d4673dc249ea837dd14feca0","snaks":{"P248":[{"snaktype":"value","property":"P248","hash":"4ec639fccc9ddb8e079f7d27ca43220e3c512c20","datavalue":{"value":{"entity-type":"item","numeric-id":1344256,"id":"Q1344256"},"type":"wikibase-entityid"},"datatype":"wikibase-item"}]},"snaks-order":["P248"]}]}]},"sitelinks":{"abwiki":{"site":"abwiki","title":"\u0410\u043b\u044b\u043c","badges":[],"url":"https://ab.wikipedia.org/wiki/%D0%90%D0%BB%D1%8B%D0%BC"},"adywiki":{"site":"adywiki","title":"\u0410\u0441\u043b\u044a\u0430\u043d","badges":[],"url":"https://ady.wikipedia.org/wiki/%D0%90%D1%81%D0%BB%D1%8A%D0%B0%D0%BD"},"afwiki":{"site":"afwiki","title":"Leeu","badges":["Q17437796"],"url":"https://af.wikipedia.org/wiki/Leeu"},"alswiki":{"site":"alswiki","title":"L\u00f6we","badges":[],"url":"https://als.wikipedia.org/wiki/L%C3%B6we"},"altwiki":{"site":"altwiki","title":"\u0410\u0440\u0441\u043b\u0430\u043d","badges":[],"url":"https://alt.wikipedia.org/wiki/%D0%90%D1%80%D1%81%D0%BB%D0%B0%D0%BD"},"amwiki":{"site":"amwiki","title":"\u12a0\u1295\u1260\u1233","badges":[],"url":"https://am.wikipedia.org/wiki/%E1%8A%A0%E1%8A%95%E1%89%A0%E1%88%B3"},"angwiki":{"site":"angwiki","title":"L\u0113o","badges":[],"url":"https://ang.wikipedia.org/wiki/L%C4%93o"},"anwiki":{"site":"anwiki","title":"Panthera leo","badges":[],"url":"https://an.wikipedia.org/wiki/Panthera_leo"},"arcwiki":{"site":"arcwiki","title":"\u0710\u072a\u071d\u0710","badges":[],"url":"https://arc.wikipedia.org/wiki/%DC%90%DC%AA%DC%9D%DC%90"},"arwiki":{"site":"arwiki","title":"\u0623\u0633\u062f","badges":["Q17437796"],"url":"https://ar.wikipedia.org/wiki/%D8%A3%D8%B3%D8%AF"},"arywiki":{"site":"arywiki","title":"\u0633\u0628\u0639","badges":[],"url":"https://ary.wikipedia.org/wiki/%D8%B3%D8%A8%D8%B9"},"arzwiki":{"site":"arzwiki","title":"\u0633\u0628\u0639","badges":[],"url":"https://arz.wikipedia.org/wiki/%D8%B3%D8%A8%D8%B9"},"astwiki":{"site":"astwiki","title":"Panthera leo","badges":[],"url":"https://ast.wikipedia.org/wiki/Panthera_leo"},"aswiki":{"site":"aswiki","title":"\u09b8\u09bf\u0982\u09b9","badges":[],"url":"https://as.wikipedia.org/wiki/%E0%A6%B8%E0%A6%BF%E0%A6%82%E0%A6%B9"},"avkwiki":{"site":"avkwiki","title":"Krapol (Panthera leo)","badges":[],"url":"https://avk.wikipedia.org/wiki/Krapol_(Panthera_leo)"},"avwiki":{"site":"avwiki","title":"\u0413\u044a\u0430\u043b\u0431\u0430\u0446\u04c0","badges":[],"url":"https://av.wikipedia.org/wiki/%D0%93%D1%8A%D0%B0%D0%BB%D0%B1%D0%B0%D1%86%D3%80"},"azbwiki":{"site":"azbwiki","title":"\u0622\u0633\u0644\u0627\u0646","badges":[],"url":"https://azb.wikipedia.org/wiki/%D8%A2%D8%B3%D9%84%D8%A7%D9%86"},"azwiki":{"site":"azwiki","title":"\u015eir","badges":[],"url":"https://az.wikipedia.org/wiki/%C5%9Eir"},"bat_smgwiki":{"site":"bat_smgwiki","title":"Li\u016bts","badges":[],"url":"https://bat-smg.wikipedia.org/wiki/Li%C5%ABts"},"bawiki":{"site":"bawiki","title":"\u0410\u0440\u044b\u04ab\u043b\u0430\u043d","badges":[],"url":"https://ba.wikipedia.org/wiki/%D0%90%D1%80%D1%8B%D2%AB%D0%BB%D0%B0%D0%BD"},"bclwiki":{"site":"bclwiki","title":"Leon","badges":[],"url":"https://bcl.wikipedia.org/wiki/Leon"},"be_x_oldwiki":{"site":"be_x_oldwiki","title":"\u041b\u0435\u045e","badges":[],"url":"https://be-tarask.wikipedia.org/wiki/%D0%9B%D0%B5%D1%9E"},"bewiki":{"site":"bewiki","title":"\u041b\u0435\u045e","badges":[],"url":"https://be.wikipedia.org/wiki/%D0%9B%D0%B5%D1%9E"},"bgwiki":{"site":"bgwiki","title":"\u041b\u044a\u0432","badges":[],"url":"https://bg.wikipedia.org/wiki/%D0%9B%D1%8A%D0%B2"},"bhwiki":{"site":"bhwiki","title":"\u0938\u093f\u0902\u0939","badges":[],"url":"https://bh.wikipedia.org/wiki/%E0%A4%B8%E0%A4%BF%E0%A4%82%E0%A4%B9"},"bmwiki":{"site":"bmwiki","title":"Waraba","badges":[],"url":"https://bm.wikipedia.org/wiki/Waraba"},"bnwiki":{"site":"bnwiki","title":"\u09b8\u09bf\u0982\u09b9","badges":[],"url":"https://bn.wikipedia.org/wiki/%E0%A6%B8%E0%A6%BF%E0%A6%82%E0%A6%B9"},"bowiki":{"site":"bowiki","title":"\u0f66\u0f7a\u0f44\u0f0b\u0f42\u0f7a\u0f0d","badges":[],"url":"https://bo.wikipedia.org/wiki/%E0%BD%A6%E0%BD%BA%E0%BD%84%E0%BC%8B%E0%BD%82%E0%BD%BA%E0%BC%8D"},"bpywiki":{"site":"bpywiki","title":"\u09a8\u0982\u09b8\u09be","badges":[],"url":"https://bpy.wikipedia.org/wiki/%E0%A6%A8%E0%A6%82%E0%A6%B8%E0%A6%BE"},"brwiki":{"site":"brwiki","title":"Leon (loen)","badges":[],"url":"https://br.wikipedia.org/wiki/Leon_(loen)"},"bswiki":{"site":"bswiki","title":"Lav","badges":[],"url":"https://bs.wikipedia.org/wiki/Lav"},"bswikiquote":{"site":"bswikiquote","title":"Lav","badges":[],"url":"https://bs.wikiquote.org/wiki/Lav"},"bxrwiki":{"site":"bxrwiki","title":"\u0410\u0440\u0441\u0430\u043b\u0430\u043d","badges":[],"url":"https://bxr.wikipedia.org/wiki/%D0%90%D1%80%D1%81%D0%B0%D0%BB%D0%B0%D0%BD"},"cawiki":{"site":"cawiki","title":"Lle\u00f3","badges":["Q17437796"],"url":"https://ca.wikipedia.org/wiki/Lle%C3%B3"},"cawikiquote":{"site":"cawikiquote","title":"Lle\u00f3","badges":[],"url":"https://ca.wikiquote.org/wiki/Lle%C3%B3"},"cdowiki":{"site":"cdowiki","title":"S\u0103i (m\u00e0-ku\u014f d\u00f4ng-\u016dk)","badges":[],"url":"https://cdo.wikipedia.org/wiki/S%C4%83i_(m%C3%A0-ku%C5%8F_d%C3%B4ng-%C5%ADk)"},"cebwiki":{"site":"cebwiki","title":"Panthera leo","badges":[],"url":"https://ceb.wikipedia.org/wiki/Panthera_leo"},"cewiki":{"site":"cewiki","title":"\u041b\u043e\u043c","badges":[],"url":"https://ce.wikipedia.org/wiki/%D0%9B%D0%BE%D0%BC"},"chrwiki":{"site":"chrwiki","title":"\u13e2\u13d3\u13e5 \u13a4\u13c3\u13d5\u13be","badges":[],"url":"https://chr.wikipedia.org/wiki/%E1%8F%A2%E1%8F%93%E1%8F%A5_%E1%8E%A4%E1%8F%83%E1%8F%95%E1%8E%BE"},"chywiki":{"site":"chywiki","title":"P\u00e9hpe'\u00e9nan\u00f3se'hame","badges":[],"url":"https://chy.wikipedia.org/wiki/P%C3%A9hpe%27%C3%A9nan%C3%B3se%27hame"},"ckbwiki":{"site":"ckbwiki","title":"\u0634\u06ce\u0631","badges":[],"url":"https://ckb.wikipedia.org/wiki/%D8%B4%DB%8E%D8%B1"},"commonswiki":{"site":"commonswiki","title":"Panthera leo","badges":[],"url":"https://commons.wikimedia.org/wiki/Panthera_leo"},"cowiki":{"site":"cowiki","title":"Lionu","badges":[],"url":"https://co.wikipedia.org/wiki/Lionu"},"csbwiki":{"site":"csbwiki","title":"Lew","badges":[],"url":"https://csb.wikipedia.org/wiki/Lew"},"cswiki":{"site":"cswiki","title":"Lev","badges":[],"url":"https://cs.wikipedia.org/wiki/Lev"},"cswikiquote":{"site":"cswikiquote","title":"Lev","badges":[],"url":"https://cs.wikiquote.org/wiki/Lev"},"cuwiki":{"site":"cuwiki","title":"\u041b\u044c\u0432\u044a","badges":[],"url":"https://cu.wikipedia.org/wiki/%D0%9B%D1%8C%D0%B2%D1%8A"},"cvwiki":{"site":"cvwiki","title":"\u0410\u0440\u0103\u0441\u043b\u0430\u043d","badges":[],"url":"https://cv.wikipedia.org/wiki/%D0%90%D1%80%C4%83%D1%81%D0%BB%D0%B0%D0%BD"},"cywiki":{"site":"cywiki","title":"Llew","badges":[],"url":"https://cy.wikipedia.org/wiki/Llew"},"dagwiki":{"site":"dagwiki","title":"Gbu\u0263inli","badges":[],"url":"https://dag.wikipedia.org/wiki/Gbu%C9%A3inli"},"dawiki":{"site":"dawiki","title":"L\u00f8ve","badges":["Q17559452"],"url":"https://da.wikipedia.org/wiki/L%C3%B8ve"},"dewiki":{"site":"dewiki","title":"L\u00f6we","badges":["Q17437796"],"url":"https://de.wikipedia.org/wiki/L%C3%B6we"},"dewikiquote":{"site":"dewikiquote","title":"L\u00f6we","badges":[],"url":"https://de.wikiquote.org/wiki/L%C3%B6we"},"dinwiki":{"site":"dinwiki","title":"K\u00f6r","badges":[],"url":"https://din.wikipedia.org/wiki/K%C3%B6r"},"diqwiki":{"site":"diqwiki","title":"\u015e\u00ear","badges":[],"url":"https://diq.wikipedia.org/wiki/%C5%9E%C3%AAr"},"dsbwiki":{"site":"dsbwiki","title":"Law","badges":[],"url":"https://dsb.wikipedia.org/wiki/Law"},"eewiki":{"site":"eewiki","title":"Dzata","badges":[],"url":"https://ee.wikipedia.org/wiki/Dzata"},"elwiki":{"site":"elwiki","title":"\u039b\u03b9\u03bf\u03bd\u03c4\u03ac\u03c1\u03b9","badges":[],"url":"https://el.wikipedia.org/wiki/%CE%9B%CE%B9%CE%BF%CE%BD%CF%84%CE%AC%CF%81%CE%B9"},"enwiki":{"site":"enwiki","title":"Lion","badges":["Q17437796"],"url":"https://en.wikipedia.org/wiki/Lion"},"enwikiquote":{"site":"enwikiquote","title":"Lions","badges":[],"url":"https://en.wikiquote.org/wiki/Lions"},"eowiki":{"site":"eowiki","title":"Leono","badges":[],"url":"https://eo.wikipedia.org/wiki/Leono"},"eowikiquote":{"site":"eowikiquote","title":"Leono","badges":[],"url":"https://eo.wikiquote.org/wiki/Leono"},"eswiki":{"site":"eswiki","title":"Panthera leo","badges":["Q17437796"],"url":"https://es.wikipedia.org/wiki/Panthera_leo"},"eswikiquote":{"site":"eswikiquote","title":"Le\u00f3n","badges":[],"url":"https://es.wikiquote.org/wiki/Le%C3%B3n"},"etwiki":{"site":"etwiki","title":"L\u00f5vi","badges":[],"url":"https://et.wikipedia.org/wiki/L%C3%B5vi"},"etwikiquote":{"site":"etwikiquote","title":"L\u00f5vi","badges":[],"url":"https://et.wikiquote.org/wiki/L%C3%B5vi"},"euwiki":{"site":"euwiki","title":"Lehoi","badges":[],"url":"https://eu.wikipedia.org/wiki/Lehoi"},"extwiki":{"site":"extwiki","title":"Li\u00f3n (animal)","badges":[],"url":"https://ext.wikipedia.org/wiki/Li%C3%B3n_(animal)"},"fawiki":{"site":"fawiki","title":"\u0634\u06cc\u0631 (\u06af\u0631\u0628\u0647\u200c\u0633\u0627\u0646)","badges":["Q17437796"],"url":"https://fa.wikipedia.org/wiki/%D8%B4%DB%8C%D8%B1_(%DA%AF%D8%B1%D8%A8%D9%87%E2%80%8C%D8%B3%D8%A7%D9%86)"},"fawikiquote":{"site":"fawikiquote","title":"\u0634\u06cc\u0631","badges":[],"url":"https://fa.wikiquote.org/wiki/%D8%B4%DB%8C%D8%B1"},"fiu_vrowiki":{"site":"fiu_vrowiki","title":"L\u00f5vi","badges":[],"url":"https://fiu-vro.wikipedia.org/wiki/L%C3%B5vi"},"fiwiki":{"site":"fiwiki","title":"Leijona","badges":["Q17437796"],"url":"https://fi.wikipedia.org/wiki/Leijona"},"fowiki":{"site":"fowiki","title":"Leyva","badges":[],"url":"https://fo.wikipedia.org/wiki/Leyva"},"frrwiki":{"site":"frrwiki","title":"L\u00f6\u00f6w","badges":[],"url":"https://frr.wikipedia.org/wiki/L%C3%B6%C3%B6w"},"frwiki":{"site":"frwiki","title":"Lion","badges":["Q17437796"],"url":"https://fr.wikipedia.org/wiki/Lion"},"frwikiquote":{"site":"frwikiquote","title":"Lion","badges":[],"url":"https://fr.wikiquote.org/wiki/Lion"},"gagwiki":{"site":"gagwiki","title":"Aslan","badges":[],"url":"https://gag.wikipedia.org/wiki/Aslan"},"gawiki":{"site":"gawiki","title":"Leon","badges":[],"url":"https://ga.wikipedia.org/wiki/Leon"},"gdwiki":{"site":"gdwiki","title":"Le\u00f2mhann","badges":[],"url":"https://gd.wikipedia.org/wiki/Le%C3%B2mhann"},"glwiki":{"site":"glwiki","title":"Le\u00f3n","badges":[],"url":"https://gl.wikipedia.org/wiki/Le%C3%B3n"},"gnwiki":{"site":"gnwiki","title":"Le\u00f5","badges":[],"url":"https://gn.wikipedia.org/wiki/Le%C3%B5"},"gotwiki":{"site":"gotwiki","title":"\ud800\udf3b\ud800\udf39\ud800\udf45\ud800\udf30","badges":[],"url":"https://got.wikipedia.org/wiki/%F0%90%8C%BB%F0%90%8C%B9%F0%90%8D%85%F0%90%8C%B0"},"guwiki":{"site":"guwiki","title":"\u0a8f\u0ab6\u0abf\u0aaf\u0abe\u0a87 \u0ab8\u0abf\u0a82\u0ab9","badges":[],"url":"https://gu.wikipedia.org/wiki/%E0%AA%8F%E0%AA%B6%E0%AA%BF%E0%AA%AF%E0%AA%BE%E0%AA%87_%E0%AA%B8%E0%AA%BF%E0%AA%82%E0%AA%B9"},"hakwiki":{"site":"hakwiki","title":"S\u1e73\u0302-\u00e9","badges":[],"url":"https://hak.wikipedia.org/wiki/S%E1%B9%B3%CC%82-%C3%A9"},"hawiki":{"site":"hawiki","title":"Zaki","badges":[],"url":"https://ha.wikipedia.org/wiki/Zaki"},"hawwiki":{"site":"hawwiki","title":"Liona","badges":[],"url":"https://haw.wikipedia.org/wiki/Liona"},"hewiki":{"site":"hewiki","title":"\u05d0\u05e8\u05d9\u05d4","badges":[],"url":"https://he.wikipedia.org/wiki/%D7%90%D7%A8%D7%99%D7%94"},"hewikiquote":{"site":"hewikiquote","title":"\u05d0\u05e8\u05d9\u05d4","badges":[],"url":"https://he.wikiquote.org/wiki/%D7%90%D7%A8%D7%99%D7%94"},"hifwiki":{"site":"hifwiki","title":"Ser","badges":[],"url":"https://hif.wikipedia.org/wiki/Ser"},"hiwiki":{"site":"hiwiki","title":"\u0938\u093f\u0902\u0939 (\u092a\u0936\u0941)","badges":[],"url":"https://hi.wikipedia.org/wiki/%E0%A4%B8%E0%A4%BF%E0%A4%82%E0%A4%B9_(%E0%A4%AA%E0%A4%B6%E0%A5%81)"},"hrwiki":{"site":"hrwiki","title":"Lav","badges":[],"url":"https://hr.wikipedia.org/wiki/Lav"},"hrwikiquote":{"site":"hrwikiquote","title":"Lav","badges":[],"url":"https://hr.wikiquote.org/wiki/Lav"},"hsbwiki":{"site":"hsbwiki","title":"Law","badges":[],"url":"https://hsb.wikipedia.org/wiki/Law"},"htwiki":{"site":"htwiki","title":"Lyon","badges":[],"url":"https://ht.wikipedia.org/wiki/Lyon"},"huwiki":{"site":"huwiki","title":"Oroszl\u00e1n","badges":[],"url":"https://hu.wikipedia.org/wiki/Oroszl%C3%A1n"},"hywiki":{"site":"hywiki","title":"\u0531\u057c\u0575\u0578\u0582\u056e","badges":[],"url":"https://hy.wikipedia.org/wiki/%D4%B1%D5%BC%D5%B5%D5%B8%D6%82%D5%AE"},"hywikiquote":{"site":"hywikiquote","title":"\u0531\u057c\u0575\u0578\u0582\u056e","badges":[],"url":"https://hy.wikiquote.org/wiki/%D4%B1%D5%BC%D5%B5%D5%B8%D6%82%D5%AE"},"hywwiki":{"site":"hywwiki","title":"\u0531\u057c\u056b\u0582\u056e","badges":[],"url":"https://hyw.wikipedia.org/wiki/%D4%B1%D5%BC%D5%AB%D6%82%D5%AE"},"iawiki":{"site":"iawiki","title":"Leon","badges":[],"url":"https://ia.wikipedia.org/wiki/Leon"},"idwiki":{"site":"idwiki","title":"Singa","badges":[],"url":"https://id.wikipedia.org/wiki/Singa"},"igwiki":{"site":"igwiki","title":"Od\u00fam","badges":[],"url":"https://ig.wikipedia.org/wiki/Od%C3%BAm"},"ilowiki":{"site":"ilowiki","title":"Leon","badges":[],"url":"https://ilo.wikipedia.org/wiki/Leon"},"inhwiki":{"site":"inhwiki","title":"\u041b\u043e\u043c","badges":[],"url":"https://inh.wikipedia.org/wiki/%D0%9B%D0%BE%D0%BC"},"iowiki":{"site":"iowiki","title":"Leono (mamifero)","badges":[],"url":"https://io.wikipedia.org/wiki/Leono_(mamifero)"},"iswiki":{"site":"iswiki","title":"Lj\u00f3n","badges":[],"url":"https://is.wikipedia.org/wiki/Lj%C3%B3n"},"itwiki":{"site":"itwiki","title":"Panthera leo","badges":[],"url":"https://it.wikipedia.org/wiki/Panthera_leo"},"itwikiquote":{"site":"itwikiquote","title":"Leone","badges":[],"url":"https://it.wikiquote.org/wiki/Leone"},"jawiki":{"site":"jawiki","title":"\u30e9\u30a4\u30aa\u30f3","badges":[],"url":"https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%82%AA%E3%83%B3"},"jawikiquote":{"site":"jawikiquote","title":"\u7345\u5b50","badges":[],"url":"https://ja.wikiquote.org/wiki/%E7%8D%85%E5%AD%90"},"jbowiki":{"site":"jbowiki","title":"cinfo","badges":[],"url":"https://jbo.wikipedia.org/wiki/cinfo"},"jvwiki":{"site":"jvwiki","title":"Singa","badges":[],"url":"https://jv.wikipedia.org/wiki/Singa"},"kabwiki":{"site":"kabwiki","title":"Izem","badges":[],"url":"https://kab.wikipedia.org/wiki/Izem"},"kawiki":{"site":"kawiki","title":"\u10da\u10dd\u10db\u10d8","badges":[],"url":"https://ka.wikipedia.org/wiki/%E1%83%9A%E1%83%9D%E1%83%9B%E1%83%98"},"kbdwiki":{"site":"kbdwiki","title":"\u0425\u044c\u044d\u0449","badges":[],"url":"https://kbd.wikipedia.org/wiki/%D0%A5%D1%8C%D1%8D%D1%89"},"kbpwiki":{"site":"kbpwiki","title":"T\u0254\u0254y\u028b\u028b","badges":[],"url":"https://kbp.wikipedia.org/wiki/T%C9%94%C9%94y%CA%8B%CA%8B"},"kgwiki":{"site":"kgwiki","title":"Nkosi","badges":[],"url":"https://kg.wikipedia.org/wiki/Nkosi"},"kkwiki":{"site":"kkwiki","title":"\u0410\u0440\u044b\u0441\u0442\u0430\u043d","badges":[],"url":"https://kk.wikipedia.org/wiki/%D0%90%D1%80%D1%8B%D1%81%D1%82%D0%B0%D0%BD"},"knwiki":{"site":"knwiki","title":"\u0cb8\u0cbf\u0c82\u0cb9","badges":[],"url":"https://kn.wikipedia.org/wiki/%E0%B2%B8%E0%B2%BF%E0%B2%82%E0%B2%B9"},"kowiki":{"site":"kowiki","title":"\uc0ac\uc790","badges":[],"url":"https://ko.wikipedia.org/wiki/%EC%82%AC%EC%9E%90"},"kowikiquote":{"site":"kowikiquote","title":"\uc0ac\uc790","badges":[],"url":"https://ko.wikiquote.org/wiki/%EC%82%AC%EC%9E%90"},"kswiki":{"site":"kswiki","title":"\u067e\u0627\u062f\u064e\u0631 \u0633\u0655\u06c1\u06c1","badges":[],"url":"https://ks.wikipedia.org/wiki/%D9%BE%D8%A7%D8%AF%D9%8E%D8%B1_%D8%B3%D9%95%DB%81%DB%81"},"kuwiki":{"site":"kuwiki","title":"\u015e\u00ear","badges":[],"url":"https://ku.wikipedia.org/wiki/%C5%9E%C3%AAr"},"kwwiki":{"site":"kwwiki","title":"Lew","badges":[],"url":"https://kw.wikipedia.org/wiki/Lew"},"kywiki":{"site":"kywiki","title":"\u0410\u0440\u0441\u0442\u0430\u043d","badges":[],"url":"https://ky.wikipedia.org/wiki/%D0%90%D1%80%D1%81%D1%82%D0%B0%D0%BD"},"lawiki":{"site":"lawiki","title":"Leo","badges":[],"url":"https://la.wikipedia.org/wiki/Leo"},"lawikiquote":{"site":"lawikiquote","title":"Leo","badges":[],"url":"https://la.wikiquote.org/wiki/Leo"},"lbewiki":{"site":"lbewiki","title":"\u0410\u0441\u043b\u0430\u043d","badges":[],"url":"https://lbe.wikipedia.org/wiki/%D0%90%D1%81%D0%BB%D0%B0%D0%BD"},"lbwiki":{"site":"lbwiki","title":"L\u00e9iw","badges":[],"url":"https://lb.wikipedia.org/wiki/L%C3%A9iw"},"lezwiki":{"site":"lezwiki","title":"\u0410\u0441\u043b\u0430\u043d","badges":[],"url":"https://lez.wikipedia.org/wiki/%D0%90%D1%81%D0%BB%D0%B0%D0%BD"},"lfnwiki":{"site":"lfnwiki","title":"Leon","badges":[],"url":"https://lfn.wikipedia.org/wiki/Leon"},"lijwiki":{"site":"lijwiki","title":"Lion (bestia)","badges":[],"url":"https://lij.wikipedia.org/wiki/Lion_(bestia)"},"liwiki":{"site":"liwiki","title":"Liew","badges":["Q17437796"],"url":"https://li.wikipedia.org/wiki/Liew"},"lldwiki":{"site":"lldwiki","title":"Lion","badges":[],"url":"https://lld.wikipedia.org/wiki/Lion"},"lmowiki":{"site":"lmowiki","title":"Panthera leo","badges":[],"url":"https://lmo.wikipedia.org/wiki/Panthera_leo"},"lnwiki":{"site":"lnwiki","title":"Nk\u0254\u0301si","badges":[],"url":"https://ln.wikipedia.org/wiki/Nk%C9%94%CC%81si"},"ltgwiki":{"site":"ltgwiki","title":"\u013bovs","badges":[],"url":"https://ltg.wikipedia.org/wiki/%C4%BBovs"},"ltwiki":{"site":"ltwiki","title":"Li\u016btas","badges":[],"url":"https://lt.wikipedia.org/wiki/Li%C5%ABtas"},"ltwikiquote":{"site":"ltwikiquote","title":"Li\u016btas","badges":[],"url":"https://lt.wikiquote.org/wiki/Li%C5%ABtas"},"lvwiki":{"site":"lvwiki","title":"Lauva","badges":["Q17437796"],"url":"https://lv.wikipedia.org/wiki/Lauva"},"mdfwiki":{"site":"mdfwiki","title":"\u041e\u0440\u043a\u0441\u043e\u0444\u0442\u0430","badges":["Q17437796"],"url":"https://mdf.wikipedia.org/wiki/%D0%9E%D1%80%D0%BA%D1%81%D0%BE%D1%84%D1%82%D0%B0"},"mgwiki":{"site":"mgwiki","title":"Liona","badges":[],"url":"https://mg.wikipedia.org/wiki/Liona"},"mhrwiki":{"site":"mhrwiki","title":"\u0410\u0440\u044b\u0441\u043b\u0430\u043d","badges":[],"url":"https://mhr.wikipedia.org/wiki/%D0%90%D1%80%D1%8B%D1%81%D0%BB%D0%B0%D0%BD"},"mkwiki":{"site":"mkwiki","title":"\u041b\u0430\u0432","badges":[],"url":"https://mk.wikipedia.org/wiki/%D0%9B%D0%B0%D0%B2"},"mlwiki":{"site":"mlwiki","title":"\u0d38\u0d3f\u0d02\u0d39\u0d02","badges":[],"url":"https://ml.wikipedia.org/wiki/%E0%B4%B8%E0%B4%BF%E0%B4%82%E0%B4%B9%E0%B4%82"},"mniwiki":{"site":"mniwiki","title":"\uabc5\uabe3\uabe1\uabc1\uabe5","badges":[],"url":"https://mni.wikipedia.org/wiki/%EA%AF%85%EA%AF%A3%EA%AF%A1%EA%AF%81%EA%AF%A5"},"mnwiki":{"site":"mnwiki","title":"\u0410\u0440\u0441\u043b\u0430\u043d","badges":[],"url":"https://mn.wikipedia.org/wiki/%D0%90%D1%80%D1%81%D0%BB%D0%B0%D0%BD"},"mrjwiki":{"site":"mrjwiki","title":"\u0410\u0440\u044b\u0441\u043b\u0430\u043d","badges":[],"url":"https://mrj.wikipedia.org/wiki/%D0%90%D1%80%D1%8B%D1%81%D0%BB%D0%B0%D0%BD"},"mrwiki":{"site":"mrwiki","title":"\u0938\u093f\u0902\u0939","badges":[],"url":"https://mr.wikipedia.org/wiki/%E0%A4%B8%E0%A4%BF%E0%A4%82%E0%A4%B9"},"mswiki":{"site":"mswiki","title":"Singa","badges":["Q17437796"],"url":"https://ms.wikipedia.org/wiki/Singa"},"mtwiki":{"site":"mtwiki","title":"Iljun","badges":[],"url":"https://mt.wikipedia.org/wiki/Iljun"},"mywiki":{"site":"mywiki","title":"\u1001\u103c\u1004\u103a\u1039\u101e\u1031\u1037","badges":[],"url":"https://my.wikipedia.org/wiki/%E1%80%81%E1%80%BC%E1%80%84%E1%80%BA%E1%80%B9%E1%80%9E%E1%80%B1%E1%80%B7"},"newiki":{"site":"newiki","title":"\u0938\u093f\u0902\u0939","badges":[],"url":"https://ne.wikipedia.org/wiki/%E0%A4%B8%E0%A4%BF%E0%A4%82%E0%A4%B9"},"newwiki":{"site":"newwiki","title":"\u0938\u093f\u0902\u0939","badges":[],"url":"https://new.wikipedia.org/wiki/%E0%A4%B8%E0%A4%BF%E0%A4%82%E0%A4%B9"},"nlwiki":{"site":"nlwiki","title":"Leeuw (dier)","badges":[],"url":"https://nl.wikipedia.org/wiki/Leeuw_(dier)"},"nnwiki":{"site":"nnwiki","title":"L\u00f8ve","badges":[],"url":"https://nn.wikipedia.org/wiki/L%C3%B8ve"},"nowiki":{"site":"nowiki","title":"L\u00f8ve","badges":[],"url":"https://no.wikipedia.org/wiki/L%C3%B8ve"},"nrmwiki":{"site":"nrmwiki","title":"Lion","badges":[],"url":"https://nrm.wikipedia.org/wiki/Lion"},"nsowiki":{"site":"nsowiki","title":"Tau","badges":[],"url":"https://nso.wikipedia.org/wiki/Tau"},"nvwiki":{"site":"nvwiki","title":"N\u00e1shd\u00f3\u00edtsoh bitsiij\u012f\u02bc dadit\u0142\u02bcoo\u00edg\u00ed\u00ed","badges":[],"url":"https://nv.wikipedia.org/wiki/N%C3%A1shd%C3%B3%C3%ADtsoh_bitsiij%C4%AF%CA%BC_dadit%C5%82%CA%BCoo%C3%ADg%C3%AD%C3%AD"},"ocwiki":{"site":"ocwiki","title":"Panthera leo","badges":[],"url":"https://oc.wikipedia.org/wiki/Panthera_leo"},"orwiki":{"site":"orwiki","title":"\u0b38\u0b3f\u0b02\u0b39","badges":[],"url":"https://or.wikipedia.org/wiki/%E0%AC%B8%E0%AC%BF%E0%AC%82%E0%AC%B9"},"oswiki":{"site":"oswiki","title":"\u0426\u043e\u043c\u0430\u0445\u044a","badges":[],"url":"https://os.wikipedia.org/wiki/%D0%A6%D0%BE%D0%BC%D0%B0%D1%85%D1%8A"},"pamwiki":{"site":"pamwiki","title":"Leon (animal)","badges":["Q17437796"],"url":"https://pam.wikipedia.org/wiki/Leon_(animal)"},"pawiki":{"site":"pawiki","title":"\u0a2c\u0a71\u0a2c\u0a30 \u0a38\u0a3c\u0a47\u0a30","badges":[],"url":"https://pa.wikipedia.org/wiki/%E0%A8%AC%E0%A9%B1%E0%A8%AC%E0%A8%B0_%E0%A8%B8%E0%A8%BC%E0%A9%87%E0%A8%B0"},"pcdwiki":{"site":"pcdwiki","title":"Lion","badges":[],"url":"https://pcd.wikipedia.org/wiki/Lion"},"plwiki":{"site":"plwiki","title":"Lew afryka\u0144ski","badges":["Q17437796"],"url":"https://pl.wikipedia.org/wiki/Lew_afryka%C5%84ski"},"plwikiquote":{"site":"plwikiquote","title":"Lew","badges":[],"url":"https://pl.wikiquote.org/wiki/Lew"},"pmswiki":{"site":"pmswiki","title":"Lion","badges":[],"url":"https://pms.wikipedia.org/wiki/Lion"},"pnbwiki":{"site":"pnbwiki","title":"\u0628\u0628\u0631 \u0634\u06cc\u0631","badges":[],"url":"https://pnb.wikipedia.org/wiki/%D8%A8%D8%A8%D8%B1_%D8%B4%DB%8C%D8%B1"},"pswiki":{"site":"pswiki","title":"\u0632\u0645\u0631\u06cc","badges":[],"url":"https://ps.wikipedia.org/wiki/%D8%B2%D9%85%D8%B1%DB%8C"},"ptwiki":{"site":"ptwiki","title":"Le\u00e3o","badges":[],"url":"https://pt.wikipedia.org/wiki/Le%C3%A3o"},"ptwikiquote":{"site":"ptwikiquote","title":"Le\u00e3o","badges":[],"url":"https://pt.wikiquote.org/wiki/Le%C3%A3o"},"quwiki":{"site":"quwiki","title":"Liyun","badges":[],"url":"https://qu.wikipedia.org/wiki/Liyun"},"rmwiki":{"site":"rmwiki","title":"Liun","badges":[],"url":"https://rm.wikipedia.org/wiki/Liun"},"rnwiki":{"site":"rnwiki","title":"Intare","badges":[],"url":"https://rn.wikipedia.org/wiki/Intare"},"rowiki":{"site":"rowiki","title":"Leu","badges":[],"url":"https://ro.wikipedia.org/wiki/Leu"},"ruewiki":{"site":"ruewiki","title":"\u041b\u0435\u0432","badges":[],"url":"https://rue.wikipedia.org/wiki/%D0%9B%D0%B5%D0%B2"},"ruwiki":{"site":"ruwiki","title":"\u041b\u0435\u0432","badges":["Q17437798"],"url":"https://ru.wikipedia.org/wiki/%D0%9B%D0%B5%D0%B2"},"ruwikinews":{"site":"ruwikinews","title":"\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f:\u041b\u044c\u0432\u044b","badges":[],"url":"https://ru.wikinews.org/wiki/%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:%D0%9B%D1%8C%D0%B2%D1%8B"},"rwwiki":{"site":"rwwiki","title":"Intare","badges":[],"url":"https://rw.wikipedia.org/wiki/Intare"},"sahwiki":{"site":"sahwiki","title":"\u0425\u0430\u0445\u0430\u0439","badges":[],"url":"https://sah.wikipedia.org/wiki/%D0%A5%D0%B0%D1%85%D0%B0%D0%B9"},"satwiki":{"site":"satwiki","title":"\u1c61\u1c5f\u1c74\u1c5f\u1c60\u1c69\u1c5e","badges":[],"url":"https://sat.wikipedia.org/wiki/%E1%B1%A1%E1%B1%9F%E1%B1%B4%E1%B1%9F%E1%B1%A0%E1%B1%A9%E1%B1%9E"},"sawiki":{"site":"sawiki","title":"\u0938\u093f\u0902\u0939\u0903 \u092a\u0936\u0941\u0903","badges":[],"url":"https://sa.wikipedia.org/wiki/%E0%A4%B8%E0%A4%BF%E0%A4%82%E0%A4%B9%E0%A4%83_%E0%A4%AA%E0%A4%B6%E0%A5%81%E0%A4%83"},"scnwiki":{"site":"scnwiki","title":"Panthera leo","badges":[],"url":"https://scn.wikipedia.org/wiki/Panthera_leo"},"scowiki":{"site":"scowiki","title":"Lion","badges":["Q17437796"],"url":"https://sco.wikipedia.org/wiki/Lion"},"sdwiki":{"site":"sdwiki","title":"\u0628\u0628\u0631 \u0634\u064a\u0646\u0647\u0646","badges":[],"url":"https://sd.wikipedia.org/wiki/%D8%A8%D8%A8%D8%B1_%D8%B4%D9%8A%D9%86%D9%87%D9%86"},"sewiki":{"site":"sewiki","title":"Ledjon","badges":[],"url":"https://se.wikipedia.org/wiki/Ledjon"},"shiwiki":{"site":"shiwiki","title":"Agrzam","badges":[],"url":"https://shi.wikipedia.org/wiki/Agrzam"},"shnwiki":{"site":"shnwiki","title":"\u101e\u1062\u1004\u103a\u1087\u101e\u102e\u1088","badges":[],"url":"https://shn.wikipedia.org/wiki/%E1%80%9E%E1%81%A2%E1%80%84%E1%80%BA%E1%82%87%E1%80%9E%E1%80%AE%E1%82%88"},"shwiki":{"site":"shwiki","title":"Lav","badges":[],"url":"https://sh.wikipedia.org/wiki/Lav"},"simplewiki":{"site":"simplewiki","title":"Lion","badges":[],"url":"https://simple.wikipedia.org/wiki/Lion"},"siwiki":{"site":"siwiki","title":"\u0dc3\u0dd2\u0d82\u0dc4\u0dba\u0dcf","badges":[],"url":"https://si.wikipedia.org/wiki/%E0%B7%83%E0%B7%92%E0%B6%82%E0%B7%84%E0%B6%BA%E0%B7%8F"},"skwiki":{"site":"skwiki","title":"Lev p\u00fa\u0161\u0165ov\u00fd","badges":[],"url":"https://sk.wikipedia.org/wiki/Lev_p%C3%BA%C5%A1%C5%A5ov%C3%BD"},"skwikiquote":{"site":"skwikiquote","title":"Lev","badges":[],"url":"https://sk.wikiquote.org/wiki/Lev"},"slwiki":{"site":"slwiki","title":"Lev","badges":[],"url":"https://sl.wikipedia.org/wiki/Lev"},"smwiki":{"site":"smwiki","title":"Leona","badges":[],"url":"https://sm.wikipedia.org/wiki/Leona"},"snwiki":{"site":"snwiki","title":"Shumba","badges":[],"url":"https://sn.wikipedia.org/wiki/Shumba"},"sowiki":{"site":"sowiki","title":"Libaax","badges":[],"url":"https://so.wikipedia.org/wiki/Libaax"},"specieswiki":{"site":"specieswiki","title":"Panthera leo","badges":[],"url":"https://species.wikimedia.org/wiki/Panthera_leo"},"sqwiki":{"site":"sqwiki","title":"Luani","badges":[],"url":"https://sq.wikipedia.org/wiki/Luani"},"srwiki":{"site":"srwiki","title":"\u041b\u0430\u0432","badges":[],"url":"https://sr.wikipedia.org/wiki/%D0%9B%D0%B0%D0%B2"},"sswiki":{"site":"sswiki","title":"Libhubesi","badges":[],"url":"https://ss.wikipedia.org/wiki/Libhubesi"},"stqwiki":{"site":"stqwiki","title":"Leeuwe","badges":[],"url":"https://stq.wikipedia.org/wiki/Leeuwe"},"stwiki":{"site":"stwiki","title":"Tau","badges":[],"url":"https://st.wikipedia.org/wiki/Tau"},"suwiki":{"site":"suwiki","title":"Singa","badges":[],"url":"https://su.wikipedia.org/wiki/Singa"},"svwiki":{"site":"svwiki","title":"Lejon","badges":[],"url":"https://sv.wikipedia.org/wiki/Lejon"},"swwiki":{"site":"swwiki","title":"Simba","badges":[],"url":"https://sw.wikipedia.org/wiki/Simba"},"szlwiki":{"site":"szlwiki","title":"Lew","badges":[],"url":"https://szl.wikipedia.org/wiki/Lew"},"tawiki":{"site":"tawiki","title":"\u0b9a\u0bbf\u0b99\u0bcd\u0b95\u0bae\u0bcd","badges":[],"url":"https://ta.wikipedia.org/wiki/%E0%AE%9A%E0%AE%BF%E0%AE%99%E0%AF%8D%E0%AE%95%E0%AE%AE%E0%AF%8D"},"tcywiki":{"site":"tcywiki","title":"\u0cb8\u0cbf\u0c82\u0cb9","badges":[],"url":"https://tcy.wikipedia.org/wiki/%E0%B2%B8%E0%B2%BF%E0%B2%82%E0%B2%B9"},"tewiki":{"site":"tewiki","title":"\u0c38\u0c3f\u0c02\u0c39\u0c02","badges":[],"url":"https://te.wikipedia.org/wiki/%E0%B0%B8%E0%B0%BF%E0%B0%82%E0%B0%B9%E0%B0%82"},"tgwiki":{"site":"tgwiki","title":"\u0428\u0435\u0440","badges":[],"url":"https://tg.wikipedia.org/wiki/%D0%A8%D0%B5%D1%80"},"thwiki":{"site":"thwiki","title":"\u0e2a\u0e34\u0e07\u0e42\u0e15","badges":[],"url":"https://th.wikipedia.org/wiki/%E0%B8%AA%E0%B8%B4%E0%B8%87%E0%B9%82%E0%B8%95"},"tiwiki":{"site":"tiwiki","title":"\u12a3\u1295\u1260\u1233","badges":[],"url":"https://ti.wikipedia.org/wiki/%E1%8A%A3%E1%8A%95%E1%89%A0%E1%88%B3"},"tkwiki":{"site":"tkwiki","title":"\u00ddolbars","badges":[],"url":"https://tk.wikipedia.org/wiki/%C3%9Dolbars"},"tlwiki":{"site":"tlwiki","title":"Leon","badges":[],"url":"https://tl.wikipedia.org/wiki/Leon"},"trwiki":{"site":"trwiki","title":"Aslan","badges":[],"url":"https://tr.wikipedia.org/wiki/Aslan"},"ttwiki":{"site":"ttwiki","title":"\u0410\u0440\u044b\u0441\u043b\u0430\u043d","badges":[],"url":"https://tt.wikipedia.org/wiki/%D0%90%D1%80%D1%8B%D1%81%D0%BB%D0%B0%D0%BD"},"tumwiki":{"site":"tumwiki","title":"Nkhalamu","badges":[],"url":"https://tum.wikipedia.org/wiki/Nkhalamu"},"udmwiki":{"site":"udmwiki","title":"\u0410\u0440\u044b\u0441\u043b\u0430\u043d","badges":[],"url":"https://udm.wikipedia.org/wiki/%D0%90%D1%80%D1%8B%D1%81%D0%BB%D0%B0%D0%BD"},"ugwiki":{"site":"ugwiki","title":"\u0634\u0649\u0631","badges":[],"url":"https://ug.wikipedia.org/wiki/%D8%B4%D9%89%D8%B1"},"ukwiki":{"site":"ukwiki","title":"\u041b\u0435\u0432","badges":[],"url":"https://uk.wikipedia.org/wiki/%D0%9B%D0%B5%D0%B2"},"ukwikiquote":{"site":"ukwikiquote","title":"\u041b\u0435\u0432","badges":[],"url":"https://uk.wikiquote.org/wiki/%D0%9B%D0%B5%D0%B2"},"urwiki":{"site":"urwiki","title":"\u0628\u0628\u0631 \u0634\u06cc\u0631","badges":["Q17437796"],"url":"https://ur.wikipedia.org/wiki/%D8%A8%D8%A8%D8%B1_%D8%B4%DB%8C%D8%B1"},"uzwiki":{"site":"uzwiki","title":"Arslon","badges":[],"url":"https://uz.wikipedia.org/wiki/Arslon"},"vecwiki":{"site":"vecwiki","title":"Leon","badges":[],"url":"https://vec.wikipedia.org/wiki/Leon"},"vepwiki":{"site":"vepwiki","title":"Lev","badges":[],"url":"https://vep.wikipedia.org/wiki/Lev"},"viwiki":{"site":"viwiki","title":"S\u01b0 t\u1eed","badges":[],"url":"https://vi.wikipedia.org/wiki/S%C6%B0_t%E1%BB%AD"},"vlswiki":{"site":"vlswiki","title":"L\u00eaeuw (b\u00eaeste)","badges":[],"url":"https://vls.wikipedia.org/wiki/L%C3%AAeuw_(b%C3%AAeste)"},"warwiki":{"site":"warwiki","title":"Leon","badges":[],"url":"https://war.wikipedia.org/wiki/Leon"},"wowiki":{"site":"wowiki","title":"Gaynde","badges":[],"url":"https://wo.wikipedia.org/wiki/Gaynde"},"wuuwiki":{"site":"wuuwiki","title":"\u72ee","badges":[],"url":"https://wuu.wikipedia.org/wiki/%E7%8B%AE"},"xalwiki":{"site":"xalwiki","title":"\u0410\u0440\u0441\u043b\u04a3","badges":[],"url":"https://xal.wikipedia.org/wiki/%D0%90%D1%80%D1%81%D0%BB%D2%A3"},"xhwiki":{"site":"xhwiki","title":"Ingonyama","badges":[],"url":"https://xh.wikipedia.org/wiki/Ingonyama"},"xmfwiki":{"site":"xmfwiki","title":"\u10dc\u10ef\u10d8\u10da\u10dd","badges":[],"url":"https://xmf.wikipedia.org/wiki/%E1%83%9C%E1%83%AF%E1%83%98%E1%83%9A%E1%83%9D"},"yiwiki":{"site":"yiwiki","title":"\u05dc\u05d9\u05d9\u05d1","badges":[],"url":"https://yi.wikipedia.org/wiki/%D7%9C%D7%99%D7%99%D7%91"},"yowiki":{"site":"yowiki","title":"K\u00ecn\u00ec\u00fan","badges":[],"url":"https://yo.wikipedia.org/wiki/K%C3%ACn%C3%AC%C3%BAn"},"zawiki":{"site":"zawiki","title":"Saeceij","badges":[],"url":"https://za.wikipedia.org/wiki/Saeceij"},"zh_min_nanwiki":{"site":"zh_min_nanwiki","title":"Sai","badges":[],"url":"https://zh-min-nan.wikipedia.org/wiki/Sai"},"zh_yuewiki":{"site":"zh_yuewiki","title":"\u7345\u5b50","badges":["Q17437796"],"url":"https://zh-yue.wikipedia.org/wiki/%E7%8D%85%E5%AD%90"},"zhwiki":{"site":"zhwiki","title":"\u72ee","badges":[],"url":"https://zh.wikipedia.org/wiki/%E7%8B%AE"},"zuwiki":{"site":"zuwiki","title":"Ibhubesi","badges":[],"url":"https://zu.wikipedia.org/wiki/Ibhubesi"}}}}} } \ No newline at end of file From 54bc4f24da8080eeeb35bd30a5a01b25aaa408c4 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Thu, 7 Oct 2021 22:16:11 +0200 Subject: [PATCH 09/26] Better handling if wikipage is missing --- UI/WikipediaBox.ts | 33 ++++++++++++++++++++++++--------- UI/i18n/Translation.ts | 8 ++++++++ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/UI/WikipediaBox.ts b/UI/WikipediaBox.ts index 5c3554aeb..8be82478e 100644 --- a/UI/WikipediaBox.ts +++ b/UI/WikipediaBox.ts @@ -12,6 +12,7 @@ import Wikidata, {WikidataResponse} from "../Logic/Web/Wikidata"; import Locale from "./i18n/Locale"; import Link from "./Base/Link"; import {TabbedComponent} from "./Base/TabbedComponent"; +import {Translation} from "./i18n/Translation"; export default class WikipediaBox extends Combine { @@ -75,7 +76,7 @@ export default class WikipediaBox extends Combine { const wp = Translations.t.general.wikipedia; - const wikiLink: UIEventSource<[string, string] | "loading" | "failed" | "no page"> = + const wikiLink: UIEventSource<[string, string, WikidataResponse] | "loading" | "failed" | ["no page", WikidataResponse]> = Wikidata.LoadWikidataEntry(wikidataId) .map(maybewikidata => { if (maybewikidata === undefined) { @@ -87,7 +88,7 @@ export default class WikipediaBox extends Combine { } const wikidata = maybewikidata["success"] if (wikidata.wikisites.size === 0) { - return "no page" + return ["no page", wikidata] } const preferredLanguage = [Locale.language.data, "en", Array.from(wikidata.wikisites.keys())[0]] @@ -99,7 +100,7 @@ export default class WikipediaBox extends Combine { pagetitle = wikidata.wikisites.get(language) i++; } while (pagetitle === undefined) - return [pagetitle, language] + return [pagetitle, language, wikidata] }, [Locale.language]) @@ -112,12 +113,15 @@ export default class WikipediaBox extends Combine { if (status === "failed") { return wp.failed.Clone().SetClass("alert p-4") } - if (status == "no page") { - return wp.noWikipediaPage.Clone() + if (status[0] == "no page") { + const [_, wd] = <[string, WikidataResponse]> status + return new Combine([ + Translation.fromMap(wd.descriptions) , + wp.noWikipediaPage.Clone().SetClass("subtle")]).SetClass("flex flex-col p-4") } - const [pagetitle, language] = status - return WikipediaBox.createContents(pagetitle, language) + const [pagetitle, language, wd] = <[string, string, WikidataResponse]> status + return WikipediaBox.createContents(pagetitle, language, wd) }) ).SetClass("overflow-auto normal-background rounded-lg") @@ -125,7 +129,11 @@ export default class WikipediaBox extends Combine { const titleElement = new VariableUiElement(wikiLink.map(state => { if (typeof state !== "string") { - const [pagetitle, language] = state + const [pagetitle, _] = state + if(pagetitle === "no page"){ + const wd = state[1] + return new Title( Translation.fromMap(wd.labels),3) + } return new Title(pagetitle, 3) } //return new Title(Translations.t.general.wikipedia.wikipediaboxTitle.Clone(), 2) @@ -136,6 +144,13 @@ export default class WikipediaBox extends Combine { const linkElement = new VariableUiElement(wikiLink.map(state => { if (typeof state !== "string") { const [pagetitle, language] = state + if(pagetitle === "no page"){ + const wd = state[1] + return new Link(Svg.pop_out_ui().SetStyle("width: 1.2rem").SetClass("block "), + "https://www.wikidata.org/wiki/"+wd.id + , true) + } + const url = `https://${language}.wikipedia.org/wiki/${pagetitle}` return new Link(Svg.pop_out_ui().SetStyle("width: 1.2rem").SetClass("block "), url, true) } @@ -157,7 +172,7 @@ export default class WikipediaBox extends Combine { * @param language * @private */ - private static createContents(pagename: string, language: string): BaseUIElement { + private static createContents(pagename: string, language: string, wikidata: WikidataResponse): BaseUIElement { const htmlContent = Wikipedia.GetArticle({ pageName: pagename, language: language diff --git a/UI/i18n/Translation.ts b/UI/i18n/Translation.ts index 15bff437a..fd9b1dacd 100644 --- a/UI/i18n/Translation.ts +++ b/UI/i18n/Translation.ts @@ -214,4 +214,12 @@ export class Translation extends BaseUIElement { } return allTranslations } + + static fromMap(transl: Map) { + const translations = {} + transl.forEach((value, key) => { + translations[key] = value + }) + return new Translation(translations); + } } \ No newline at end of file From b5a2ee1757fa2966a4f433c8526f63fe6cba01f9 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Fri, 8 Oct 2021 04:33:39 +0200 Subject: [PATCH 10/26] Add a wikidata search box --- Logic/ImageProviders/AllImageProviders.ts | 8 +- .../ImageProviders/WikimediaImageProvider.ts | 32 +- Logic/UIEventSource.ts | 31 +- Logic/Web/Wikidata.ts | 94 +- .../Json/TagRenderingConfigJson.ts | 2 +- UI/Base/Combine.ts | 5 + UI/Image/ImageUploadFlow.ts | 16 +- UI/Input/ValidatedTextField.ts | 52 +- UI/SpecialVisualizations.ts | 8 +- UI/Wikipedia/WikidataPreviewBox.ts | 80 + UI/Wikipedia/WikidataSearchBox.ts | 119 + UI/{ => Wikipedia}/WikipediaBox.ts | 33 +- .../charging_station/charging_station.json | 6964 ++++++++--------- assets/tagRenderings/questions.json | 3 +- assets/themes/etymology.json | 128 +- css/index-tailwind-output.css | 82 +- index.css | 4 + langs/en.json | 6 +- langs/themes/en.json | 18 + langs/themes/nl.json | 18 + test.ts | 28 +- 21 files changed, 4141 insertions(+), 3590 deletions(-) create mode 100644 UI/Wikipedia/WikidataPreviewBox.ts create mode 100644 UI/Wikipedia/WikidataSearchBox.ts rename UI/{ => Wikipedia}/WikipediaBox.ts (89%) diff --git a/Logic/ImageProviders/AllImageProviders.ts b/Logic/ImageProviders/AllImageProviders.ts index b56fae6f3..5382832d2 100644 --- a/Logic/ImageProviders/AllImageProviders.ts +++ b/Logic/ImageProviders/AllImageProviders.ts @@ -26,19 +26,19 @@ export default class AllImageProviders { private static _cache: Map> = new Map>() public static LoadImagesFor(tags: UIEventSource, tagKey?: string): UIEventSource { - const id = tags.data.id - if (id === undefined) { + if (tags.data.id === undefined) { return undefined; } - const cached = this._cache.get(tags.data.id) + const cacheKey = tags.data.id+tagKey + const cached = this._cache.get(cacheKey) if (cached !== undefined) { return cached } const source = new UIEventSource([]) - this._cache.set(id, source) + this._cache.set(cacheKey, source) const allSources = [] for (const imageProvider of AllImageProviders.ImageAttributionSource) { diff --git a/Logic/ImageProviders/WikimediaImageProvider.ts b/Logic/ImageProviders/WikimediaImageProvider.ts index 3dc6fca08..ea122f491 100644 --- a/Logic/ImageProviders/WikimediaImageProvider.ts +++ b/Logic/ImageProviders/WikimediaImageProvider.ts @@ -44,7 +44,7 @@ export class WikimediaImageProvider extends ImageProvider { } - private PrepareUrl(value: string): string { + private static PrepareUrl(value: string): string { if (value.toLowerCase().startsWith("https://commons.wikimedia.org/wiki/")) { return value; @@ -97,18 +97,18 @@ export class WikimediaImageProvider extends ImageProvider { } - private async UrlForImage(image: string): Promise { + private UrlForImage(image: string): ProvidedImage { if (!image.startsWith("File:")) { image = "File:" + image } - return {url: this.PrepareUrl(image), key: undefined, provider: this} + return {url: WikimediaImageProvider.PrepareUrl(image), key: undefined, provider: this} } - private startsWithCommonsPrefix(value: string){ + private static startsWithCommonsPrefix(value: string): boolean{ return WikimediaImageProvider.commonsPrefixes.some(prefix => value.startsWith(prefix)) } - private removeCommonsPrefix(value: string){ + private static removeCommonsPrefix(value: string): string{ if(value.startsWith("https://upload.wikimedia.org/")){ value = value.substring(value.lastIndexOf("/") + 1) value = decodeURIComponent(value) @@ -130,26 +130,38 @@ export class WikimediaImageProvider extends ImageProvider { return value; } + public PrepUrl(value: string): ProvidedImage { + const hasCommonsPrefix = WikimediaImageProvider.startsWithCommonsPrefix(value) + value = WikimediaImageProvider.removeCommonsPrefix(value) + + if (value.startsWith("File:")) { + return this.UrlForImage(value) + } + + // We do a last effort and assume this is a file + return this.UrlForImage("File:" + value) + } + public async ExtractUrls(key: string, value: string): Promise[]> { - const hasCommonsPrefix = this.startsWithCommonsPrefix(value) + const hasCommonsPrefix = WikimediaImageProvider.startsWithCommonsPrefix(value) if(key !== undefined && key !== this.commons_key && !hasCommonsPrefix){ return [] } - value = this.removeCommonsPrefix(value) + value = WikimediaImageProvider.removeCommonsPrefix(value) if (value.startsWith("Category:")) { const urls = await Wikimedia.GetCategoryContents(value) - return urls.filter(url => url.startsWith("File:")).map(image => this.UrlForImage(image)) + return urls.filter(url => url.startsWith("File:")).map(image => Promise.resolve(this.UrlForImage(image))) } if (value.startsWith("File:")) { - return [this.UrlForImage(value)] + return [Promise.resolve(this.UrlForImage(value))] } if (value.startsWith("http")) { // PRobably an error return [] } // We do a last effort and assume this is a file - return [this.UrlForImage("File:" + value)] + return [Promise.resolve(this.UrlForImage("File:" + value))] } diff --git a/Logic/UIEventSource.ts b/Logic/UIEventSource.ts index 55770bb71..4c7f3bad6 100644 --- a/Logic/UIEventSource.ts +++ b/Logic/UIEventSource.ts @@ -75,6 +75,27 @@ export class UIEventSource { promise?.catch(err => console.warn("Promise failed:", err)) return src } + + public AsPromise(): Promise{ + const self = this; + return new Promise((resolve, reject) => { + if(self.data !== undefined){ + resolve(self.data) + }else{ + self.addCallbackD(data => { + resolve(data) + return true; // return true to unregister as we only need to be called once + }) + } + }) + } + + public WaitForPromise(promise: Promise, onFail: ((any) => void)): UIEventSource { + const self = this; + promise?.then(d => self.setData(d)) + promise?.catch(err =>onFail(err)) + return this + } /** * Converts a promise into a UIVentsource, sets the UIEVentSource when the result is calculated. @@ -195,16 +216,20 @@ export class UIEventSource { const sink = new UIEventSource(undefined) const seenEventSources = new Set>(); mapped.addCallbackAndRun(newEventSource => { - - if (newEventSource === undefined) { + if (newEventSource === null) { + sink.setData(null) + } else if (newEventSource === undefined) { sink.setData(undefined) - } else if (!seenEventSources.has(newEventSource)) { + }else if (!seenEventSources.has(newEventSource)) { seenEventSources.add(newEventSource) newEventSource.addCallbackAndRun(resultData => { if (mapped.data === newEventSource) { sink.setData(resultData); } }) + }else{ + // Already seen, so we don't have to add a callback, just update the value + sink.setData(newEventSource.data) } }) diff --git a/Logic/Web/Wikidata.ts b/Logic/Web/Wikidata.ts index b05ba9cc1..e77dcc2ee 100644 --- a/Logic/Web/Wikidata.ts +++ b/Logic/Web/Wikidata.ts @@ -12,6 +12,11 @@ export interface WikidataResponse { commons: string } +export interface WikidataSearchoptions { + lang?: "en" | string, + maxCount?: 20 | number +} + /** * Utility functions around wikidata */ @@ -47,10 +52,14 @@ export default class Wikidata { const claimsList: any[] = entity.claims[claimId] const values = new Set() for (const claim of claimsList) { - const value = claim.mainsnak?.datavalue?.value; - if(value !== undefined){ - values.add(value) + let value = claim.mainsnak?.datavalue?.value; + if (value === undefined) { + continue; } + if(value.id !== undefined){ + value = value.id + } + values.add(value) } claims.set(claimId, values); } @@ -77,6 +86,82 @@ export default class Wikidata { return src; } + public static async search( + search: string, + options?:WikidataSearchoptions, + page = 1 + ): Promise<{ + id: string, + label: string, + description: string + }[]> { + const maxCount = options?.maxCount ?? 20 + let pageCount = Math.min(maxCount,50) + const start = page * pageCount - pageCount; + const lang = (options?.lang ?? "en") + const url = + "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + + search + + "&language=" + + lang + + "&limit="+pageCount+"&continue=" + + start + + "&format=json&uselang=" + + lang + + "&type=item&origin=*"+ + "&props=" ;// props= removes some unused values in the result + const response = await Utils.downloadJson(url) + + const result : any[] = response.search + + if(result.length < pageCount){ + // No next page + return result; + } + if(result.length < maxCount){ + const newOptions = {...options} + newOptions.maxCount = maxCount - result.length + result.push(...await Wikidata.search(search, + newOptions, + page + 1 + )) + } + + return result; + } + + public static async searchAndFetch( + search: string, + options?:WikidataSearchoptions +) : Promise + { + const maxCount = options.maxCount + // We provide some padding to filter away invalid values + options.maxCount = Math.ceil((options.maxCount ?? 20) * 1.5) + const searchResults = await Wikidata.search(search, options) + const maybeResponses = await Promise.all(searchResults.map(async r => { + try{ + return await Wikidata.LoadWikidataEntry(r.id).AsPromise() + }catch(e){ + console.error(e) + return undefined; + } + })) + const responses = maybeResponses + .map(r => r["success"]) + .filter(wd => { + if(wd === undefined){ + return false; + } + if(wd.claims.get("P31" /*Instance of*/)?.has("Q4167410"/* Wikimedia Disambiguation page*/)){ + return false; + } + return true; + }) + responses.splice(maxCount, responses.length - maxCount) + return responses + } + private static ExtractKey(value: string | number) : number{ if (typeof value === "number") { return value @@ -99,6 +184,7 @@ export default class Wikidata { return n; } + /** * Loads a wikidata page * @returns the entity of the given value @@ -109,7 +195,7 @@ export default class Wikidata { console.warn("Could not extract a wikidata entry from", value) return undefined; } - console.log("Requesting wikidata with id", id) + const url = "https://www.wikidata.org/wiki/Special:EntityData/Q" + id + ".json"; const response = await Utils.downloadJson(url) return Wikidata.ParseResponse(response.entities["Q" + id]) diff --git a/Models/ThemeConfig/Json/TagRenderingConfigJson.ts b/Models/ThemeConfig/Json/TagRenderingConfigJson.ts index 0965a24b6..532690af7 100644 --- a/Models/ThemeConfig/Json/TagRenderingConfigJson.ts +++ b/Models/ThemeConfig/Json/TagRenderingConfigJson.ts @@ -52,7 +52,7 @@ export interface TagRenderingConfigJson { * Extra parameters to initialize the input helper arguments. * For semantics, see the 'SpecialInputElements.md' */ - helperArgs?: (string | number | boolean)[]; + helperArgs?: (string | number | boolean | any)[]; /** * If a value is added with the textfield, these extra tag is addded. * Useful to add a 'fixme=freeform textfield used - to be checked' diff --git a/UI/Base/Combine.ts b/UI/Base/Combine.ts index 3731c8bc9..2c64779a7 100644 --- a/UI/Base/Combine.ts +++ b/UI/Base/Combine.ts @@ -30,10 +30,15 @@ export default class Combine extends BaseUIElement { if (subEl === undefined || subEl === null) { continue; } + try{ + const subHtml = subEl.ConstructElement() if (subHtml !== undefined) { el.appendChild(subHtml) } + }catch(e){ + console.error("Could not generate subelement in combine due to ", e) + } } } catch (e) { const domExc = e as DOMException diff --git a/UI/Image/ImageUploadFlow.ts b/UI/Image/ImageUploadFlow.ts index 2a79417bc..a8ed6bb64 100644 --- a/UI/Image/ImageUploadFlow.ts +++ b/UI/Image/ImageUploadFlow.ts @@ -12,10 +12,11 @@ import ImgurUploader from "../../Logic/ImageProviders/ImgurUploader"; import UploadFlowStateUI from "../BigComponents/UploadFlowStateUI"; import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction"; import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; +import {FixedUiElement} from "../Base/FixedUiElement"; export class ImageUploadFlow extends Toggle { - constructor(tagsSource: UIEventSource, imagePrefix: string = "image") { + constructor(tagsSource: UIEventSource, imagePrefix: string = "image", text: string = undefined) { const uploader = new ImgurUploader(url => { // A file was uploaded - we add it to the tags of the object @@ -43,10 +44,17 @@ export class ImageUploadFlow extends Toggle { const licensePicker = new LicensePicker() const t = Translations.t.image; + + let labelContent : BaseUIElement + if(text === undefined) { + labelContent = Translations.t.image.addPicture.Clone().SetClass("block align-middle mt-1 ml-3 text-4xl ") + }else{ + labelContent = new FixedUiElement(text).SetClass("block align-middle mt-1 ml-3 text-2xl ") + } const label = new Combine([ - Svg.camera_plus_ui().SetClass("block w-12 h-12 p-1"), - Translations.t.image.addPicture.Clone().SetClass("block align-middle mt-1 ml-3") - ]).SetClass("p-2 border-4 border-black rounded-full text-4xl font-bold h-full align-middle w-full flex justify-center") + Svg.camera_plus_ui().SetClass("block w-12 h-12 p-1 text-4xl "), + labelContent + ]).SetClass("p-2 border-4 border-black rounded-full font-bold h-full align-middle w-full flex justify-center") const fileSelector = new FileSelectorButton(label) fileSelector.GetValue().addCallback(filelist => { diff --git a/UI/Input/ValidatedTextField.ts b/UI/Input/ValidatedTextField.ts index b054350f7..7218d590e 100644 --- a/UI/Input/ValidatedTextField.ts +++ b/UI/Input/ValidatedTextField.ts @@ -16,6 +16,7 @@ import LengthInput from "./LengthInput"; import {GeoOperations} from "../../Logic/GeoOperations"; import {Unit} from "../../Models/Unit"; import {FixedInputElement} from "./FixedInputElement"; +import WikidataSearchBox from "../Wikipedia/WikidataSearchBox"; interface TextFieldDef { name: string, @@ -147,7 +148,7 @@ export default class ValidatedTextField { ), ValidatedTextField.tp( "wikidata", - "A wikidata identifier, e.g. Q42", + "A wikidata identifier, e.g. Q42. Input helper arguments: [ key: the value of this tag will initialize search (default: name), options: { removePrefixes: string[], removePostfixes: string[] } these prefixes and postfixes will be removed from the initial search value]", (str) => { if (str === undefined) { return false; @@ -163,7 +164,40 @@ export default class ValidatedTextField { str = str.substr(wd.length) } return str.toUpperCase(); - }), + }, + (currentValue, inputHelperOptions) => { + const args = inputHelperOptions.args + const searchKey = args[0] ?? "name" + + let searchFor = inputHelperOptions.feature?.properties[searchKey]?.toLowerCase() + + const options = args[1] + if (searchFor !== undefined && options !== undefined) { + const prefixes = options["removePrefixes"] + const postfixes = options["removePostfixes"] + + for (const postfix of postfixes ?? []) { + if (searchFor.endsWith(postfix)) { + searchFor = searchFor.substring(0, searchFor.length - postfix.length) + break; + } + } + + for (const prefix of prefixes ?? []) { + if (searchFor.startsWith(prefix)) { + searchFor = searchFor.substring(prefix.length) + break; + } + } + + } + + return new WikidataSearchBox({ + value: currentValue, + searchText: new UIEventSource(searchFor) + }) + } + ), ValidatedTextField.tp( "int", @@ -361,13 +395,13 @@ export default class ValidatedTextField { // This implies: // We have to create a dropdown with applicable denominations, and fuse those values const unit = options.unit - - + + const isSingular = input.GetValue().map(str => str?.trim() === "1") const unitDropDown = unit.denominations.length === 1 ? - new FixedInputElement( unit.denominations[0].getToggledHuman(isSingular), unit.denominations[0]) + new FixedInputElement(unit.denominations[0].getToggledHuman(isSingular), unit.denominations[0]) : new DropDown("", unit.denominations.map(denom => { return { @@ -378,17 +412,17 @@ export default class ValidatedTextField { ) unitDropDown.GetValue().setData(unit.defaultDenom) unitDropDown.SetClass("w-min") - - const fixedDenom = unit.denominations.length === 1 ? unit.denominations[0] : undefined + + const fixedDenom = unit.denominations.length === 1 ? unit.denominations[0] : undefined input = new CombinedInputElement( input, unitDropDown, // combine the value from the textfield and the dropdown into the resulting value that should go into OSM (text, denom) => { - if(denom === undefined){ + if (denom === undefined) { return text } - return denom?.canonicalValue(text, true) + return denom?.canonicalValue(text, true) }, (valueWithDenom: string) => { // Take the value from OSM and feed it into the textfield and the dropdown diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index 3444bd5f2..954a88bed 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -26,7 +26,7 @@ import StaticFeatureSource from "../Logic/FeatureSource/Sources/StaticFeatureSou import ShowDataMultiLayer from "./ShowDataLayer/ShowDataMultiLayer"; import Minimap from "./Base/Minimap"; import AllImageProviders from "../Logic/ImageProviders/AllImageProviders"; -import WikipediaBox from "./WikipediaBox"; +import WikipediaBox from "./Wikipedia/WikipediaBox"; export interface SpecialVisualization { funcName: string, @@ -83,9 +83,13 @@ export default class SpecialVisualizations { name: "image-key", doc: "Image tag to add the URL to (or image-tag:0, image-tag:1 when multiple images are added)", defaultValue: "image" + },{ + name:"label", + doc:"The text to show on the button", + defaultValue: "Add image" }], constr: (state: State, tags, args) => { - return new ImageUploadFlow(tags, args[0]) + return new ImageUploadFlow(tags, args[0], args[1]) } }, { diff --git a/UI/Wikipedia/WikidataPreviewBox.ts b/UI/Wikipedia/WikidataPreviewBox.ts new file mode 100644 index 000000000..650b76327 --- /dev/null +++ b/UI/Wikipedia/WikidataPreviewBox.ts @@ -0,0 +1,80 @@ +import {VariableUiElement} from "../Base/VariableUIElement"; +import {UIEventSource} from "../../Logic/UIEventSource"; +import Wikidata, {WikidataResponse} from "../../Logic/Web/Wikidata"; +import {Translation} from "../i18n/Translation"; +import {FixedUiElement} from "../Base/FixedUiElement"; +import Loading from "../Base/Loading"; +import {Transform} from "stream"; +import Translations from "../i18n/Translations"; +import Combine from "../Base/Combine"; +import Img from "../Base/Img"; +import {WikimediaImageProvider} from "../../Logic/ImageProviders/WikimediaImageProvider"; +import Link from "../Base/Link"; +import Svg from "../../Svg"; +import BaseUIElement from "../BaseUIElement"; + +export default class WikidataPreviewBox extends VariableUiElement { + + constructor(wikidataId : UIEventSource) { + let inited = false; + const wikidata = wikidataId + .stabilized(250) + .bind(id => { + if (id === undefined || id === "" || id === "Q") { + return null; + } + inited = true; + return Wikidata.LoadWikidataEntry(id) + }) + + super(wikidata.map(maybeWikidata => { + if(maybeWikidata === null || !inited){ + return undefined; + } + + if(maybeWikidata === undefined){ + return new Loading(Translations.t.general.loading) + } + + if (maybeWikidata["error"] !== undefined) { + return new FixedUiElement(maybeWikidata["error"]).SetClass("alert") + } + const wikidata = maybeWikidata["success"] + return WikidataPreviewBox.WikidataResponsePreview(wikidata) + })) + + } + + public static WikidataResponsePreview(wikidata: WikidataResponse): BaseUIElement{ + let link = new Link( + new Combine([ + wikidata.id, + Svg.wikidata_ui().SetStyle("width: 2.5rem").SetClass("block") + ]).SetClass("flex"), + "https://wikidata.org/wiki/"+wikidata.id ,true) + + let info = new Combine( [ + new Combine([Translation.fromMap(wikidata.labels).SetClass("font-bold"), + link]).SetClass("flex justify-between"), + Translation.fromMap(wikidata.descriptions) + ]).SetClass("flex flex-col link-underline") + + + let imageUrl = undefined + if(wikidata.claims.get("P18")?.size > 0){ + imageUrl = Array.from(wikidata.claims.get("P18"))[0] + } + + + if(imageUrl){ + imageUrl = WikimediaImageProvider.singleton.PrepUrl(imageUrl).url + info = new Combine([ new Img(imageUrl).SetStyle("max-width: 5rem; width: unset; height: 4rem").SetClass("rounded-xl mr-2"), + info.SetClass("w-full")]).SetClass("flex") + } + + info.SetClass("p-2 w-full") + + return info + } + +} \ No newline at end of file diff --git a/UI/Wikipedia/WikidataSearchBox.ts b/UI/Wikipedia/WikidataSearchBox.ts new file mode 100644 index 000000000..dce60c02e --- /dev/null +++ b/UI/Wikipedia/WikidataSearchBox.ts @@ -0,0 +1,119 @@ +import Combine from "../Base/Combine"; +import {InputElement} from "../Input/InputElement"; +import {TextField} from "../Input/TextField"; +import Translations from "../i18n/Translations"; +import {UIEventSource} from "../../Logic/UIEventSource"; +import Wikidata, {WikidataResponse} from "../../Logic/Web/Wikidata"; +import Locale from "../i18n/Locale"; +import {VariableUiElement} from "../Base/VariableUIElement"; +import {FixedUiElement} from "../Base/FixedUiElement"; +import WikidataPreviewBox from "./WikidataPreviewBox"; +import Title from "../Base/Title"; +import WikipediaBox from "./WikipediaBox"; +import Svg from "../../Svg"; +import Link from "../Base/Link"; + +export default class WikidataSearchBox extends InputElement { + + private readonly wikidataId: UIEventSource + private readonly searchText: UIEventSource + + constructor(options?: { + searchText?: UIEventSource, + value?: UIEventSource + }) { + super(); + this.searchText = options?.searchText + this.wikidataId = options?.value ?? new UIEventSource(undefined); + } + + GetValue(): UIEventSource { + return this.wikidataId; + } + + protected InnerConstructElement(): HTMLElement { + + const searchField = new TextField({ + placeholder: Translations.t.general.wikipedia.searchWikidata, + value: this.searchText, + inputStyle: "width: calc(100% - 0.5rem); border: 1px solid black" + + }) + const selectedWikidataId = this.wikidataId + + const lastSearchResults = new UIEventSource([]) + const searchFailMessage = new UIEventSource(undefined) + searchField.GetValue().addCallbackAndRunD(searchText => { + if (searchText.length < 3) { + return; + } + searchFailMessage.setData(undefined) + lastSearchResults.WaitForPromise( + Wikidata.searchAndFetch(searchText, { + lang: Locale.language.data, + maxCount: 5 + } + ), err => searchFailMessage.setData(err)) + + }) + + + const previews = new VariableUiElement(lastSearchResults.map(searchResults => { + if (searchFailMessage.data !== undefined) { + return new Combine([Translations.t.general.wikipedia.failed.Clone().SetClass("alert"), searchFailMessage.data]) + } + + if(searchResults.length === 0){ + return Translations.t.general.wikipedia.noResults.Subs({search: searchField.GetValue().data ?? ""}) + } + + if (searchResults.length === 0) { + return Translations.t.general.wikipedia.doSearch + } + + return new Combine(searchResults.map(wikidataresponse => { + const el = WikidataPreviewBox.WikidataResponsePreview(wikidataresponse).SetClass("rounded-xl p-1 sm:p-2 md:p-3 m-px border-2 sm:border-4 transition-colors") + el.onClick(() => { + selectedWikidataId.setData(wikidataresponse.id) + }) + selectedWikidataId.addCallbackAndRunD(selected => { + if (selected === wikidataresponse.id) { + el.SetClass("subtle-background border-attention") + } else { + el.RemoveClass("subtle-background") + el.RemoveClass("border-attention") + } + }) + return el; + + })).SetClass("flex flex-col") + + }, [searchFailMessage])) + + // + const full = new Combine([ + new Title(Translations.t.general.wikipedia.searchWikidata, 3).SetClass("m-2"), + new Combine([ + Svg.search_ui().SetStyle("width: 1.5rem"), + searchField.SetClass("m-2 w-full")]).SetClass("flex"), + previews + ]).SetClass("flex flex-col border-2 border-black rounded-xl m-2 p-2") + + return new Combine([ + new VariableUiElement(selectedWikidataId.map(wid => { + if (wid === undefined) { + return undefined + } + return new WikipediaBox([wid]); + })).SetStyle("max-height:12.5rem"), + full + ]).ConstructElement(); + } + + IsSelected: UIEventSource = new UIEventSource(false); + + IsValid(t: string): boolean { + return t.startsWith("Q") && !isNaN(Number(t.substring(1))); + } + +} \ No newline at end of file diff --git a/UI/WikipediaBox.ts b/UI/Wikipedia/WikipediaBox.ts similarity index 89% rename from UI/WikipediaBox.ts rename to UI/Wikipedia/WikipediaBox.ts index 8be82478e..0dc059ac0 100644 --- a/UI/WikipediaBox.ts +++ b/UI/Wikipedia/WikipediaBox.ts @@ -1,18 +1,19 @@ -import {UIEventSource} from "../Logic/UIEventSource"; -import {VariableUiElement} from "./Base/VariableUIElement"; -import Wikipedia from "../Logic/Web/Wikipedia"; -import Loading from "./Base/Loading"; -import {FixedUiElement} from "./Base/FixedUiElement"; -import Combine from "./Base/Combine"; -import BaseUIElement from "./BaseUIElement"; -import Title from "./Base/Title"; -import Translations from "./i18n/Translations"; -import Svg from "../Svg"; -import Wikidata, {WikidataResponse} from "../Logic/Web/Wikidata"; -import Locale from "./i18n/Locale"; -import Link from "./Base/Link"; -import {TabbedComponent} from "./Base/TabbedComponent"; -import {Translation} from "./i18n/Translation"; +import BaseUIElement from "../BaseUIElement"; +import Locale from "../i18n/Locale"; +import {VariableUiElement} from "../Base/VariableUIElement"; +import {Translation} from "../i18n/Translation"; +import Svg from "../../Svg"; +import Combine from "../Base/Combine"; +import Title from "../Base/Title"; +import Wikipedia from "../../Logic/Web/Wikipedia"; +import Wikidata, {WikidataResponse} from "../../Logic/Web/Wikidata"; +import {TabbedComponent} from "../Base/TabbedComponent"; +import {UIEventSource} from "../../Logic/UIEventSource"; +import Loading from "../Base/Loading"; +import {FixedUiElement} from "../Base/FixedUiElement"; +import Translations from "../i18n/Translations"; +import Link from "../Base/Link"; +import WikidataPreviewBox from "./WikidataPreviewBox"; export default class WikipediaBox extends Combine { @@ -116,7 +117,7 @@ export default class WikipediaBox extends Combine { if (status[0] == "no page") { const [_, wd] = <[string, WikidataResponse]> status return new Combine([ - Translation.fromMap(wd.descriptions) , + WikidataPreviewBox.WikidataResponsePreview(wd), wp.noWikipediaPage.Clone().SetClass("subtle")]).SetClass("flex flex-col p-4") } diff --git a/assets/layers/charging_station/charging_station.json b/assets/layers/charging_station/charging_station.json index 49636eba5..fb457f800 100644 --- a/assets/layers/charging_station/charging_station.json +++ b/assets/layers/charging_station/charging_station.json @@ -1,3519 +1,3519 @@ { - "id": "charging_station", - "name": { - "en": "Charging stations", - "it": "Stazioni di ricarica", - "ja": "充電ステーション", - "nb_NO": "Ladestasjoner", - "ru": "Зарядные станции", - "zh_Hant": "充電站" - }, - "minzoom": 10, - "source": { - "osmTags": { - "or": [ - "amenity=charging_station", - "disused:amenity=charging_station", - "planned:amenity=charging_station", - "construction:amenity=charging_station" - ] - } - }, - "title": { - "render": { - "en": "Charging station", - "it": "Stazione di ricarica", - "ja": "充電ステーション", - "nb_NO": "Ladestasjon", - "ru": "Зарядная станция", - "zh_Hant": "充電站" - } - }, - "description": { - "en": "A charging station", - "it": "Una stazione di ricarica", - "ja": "充電ステーション", - "nb_NO": "En ladestasjon", - "ru": "Зарядная станция", - "zh_Hant": "充電站" - }, - "calculatedTags": [ - "motorcar=feat.properties.motorcar ?? feat.properties.car" - ], - "tagRenderings": [ - "images", - { - "id": "Type", - "question": { - "en": "Which vehicles are allowed to charge here?" - }, - "multiAnswer": true, - "mappings": [ - { - "if": "bicycle=yes", - "ifnot": "bicycle=no", - "then": { - "en": "bicycles can be charged here" - } - }, - { - "if": "motorcar=yes", - "extraTags": "car=", - "ifnot": { - "and": [ - "car=", - "motorcar=no" - ] - }, - "then": { - "en": "Cars can be charged here" - } - }, - { - "if": "scooter=yes", - "ifnot": "scooter=no", - "then": { - "en": "Scooters can be charged here" - } - }, - { - "if": "hgv=yes", - "ifnot": "hgv=no", - "then": { - "en": "Heavy good vehicles (such as trucks) can be charged here" - } - }, - { - "if": "bus=yes", - "ifnot": "bus=no", - "then": { - "en": "Buses can be charged here" - } - } - ] + "id": "charging_station", + "name": { + "en": "Charging stations", + "it": "Stazioni di ricarica", + "ja": "充電ステーション", + "nb_NO": "Ladestasjoner", + "ru": "Зарядные станции", + "zh_Hant": "充電站" }, - { - "id": "access", - "question": { - "en": "Who is allowed to use this charging station?" - }, - "render": { - "en": "Access is {access}" - }, - "freeform": { - "key": "access", - "addExtraTags": [ - "fixme=Freeform field used for access - doublecheck the value" - ] - }, - "mappings": [ - { - "if": "access=yes", - "then": "Anyone can use this charging station (payment might be needed)" - }, - { - "if": { + "minzoom": 10, + "source": { + "osmTags": { "or": [ - "access=permissive", - "access=public" + "amenity=charging_station", + "disused:amenity=charging_station", + "planned:amenity=charging_station", + "construction:amenity=charging_station" ] - }, - "then": "Anyone can use this charging station (payment might be needed)", - "hideInAnswer": true - }, - { - "if": "access=customers", - "then": "Only customers of the place this station belongs to can use this charging station
E.g. a charging station operated by hotel which is only usable by their guests " - }, - { - "if": "access=private", - "then": "Not accessible to the general public (e.g. only accessible to the owners, employees, ...)" } - ] }, - { - "id": "capacity", - "render": { - "en": "{capacity} vehicles can be charged here at the same time", - "nl": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" - }, - "question": { - "en": "How much vehicles can be charged here at the same time?", - "nl": "Hoeveel voertuigen kunnen hier opgeladen worden?" - }, - "freeform": { - "key": "capacity", - "type": "pnat" - } + "title": { + "render": { + "en": "Charging station", + "it": "Stazione di ricarica", + "ja": "充電ステーション", + "nb_NO": "Ladestasjon", + "ru": "Зарядная станция", + "zh_Hant": "充電站" + } }, - { - "id": "Available_charging_stations (generated)", - "question": { - "en": "Which charging stations are available here?" - }, - "multiAnswer": true, - "mappings": [ + "description": { + "en": "A charging station", + "it": "Una stazione di ricarica", + "ja": "充電ステーション", + "nb_NO": "En ladestasjon", + "ru": "Зарядная станция", + "zh_Hant": "充電站" + }, + "calculatedTags": [ + "motorcar=feat.properties.motorcar ?? feat.properties.car" + ], + "tagRenderings": [ + "images", { - "if": "socket:schuko=1", - "ifnot": "socket:schuko=", - "then": { - "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
", - "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
" - }, - "hideInAnswer": { - "or": [ - "_country!=be", - "_country!=fr", - "_country!=ma", - "_country!=tn", - "_country!=pl", - "_country!=cs", - "_country!=sk", - "_country!=mo" + "id": "Type", + "question": { + "en": "Which vehicles are allowed to charge here?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "bicycle=yes", + "ifnot": "bicycle=no", + "then": { + "en": "bicycles can be charged here" + } + }, + { + "if": "motorcar=yes", + "extraTags": "car=", + "ifnot": { + "and": [ + "car=", + "motorcar=no" + ] + }, + "then": { + "en": "Cars can be charged here" + } + }, + { + "if": "scooter=yes", + "ifnot": "scooter=no", + "then": { + "en": "Scooters can be charged here" + } + }, + { + "if": "hgv=yes", + "ifnot": "hgv=no", + "then": { + "en": "Heavy good vehicles (such as trucks) can be charged here" + } + }, + { + "if": "bus=yes", + "ifnot": "bus=no", + "then": { + "en": "Buses can be charged here" + } + } ] - } }, { - "if": { - "and": [ - "socket:schuko~*", - "socket:schuko!=1" - ] - }, - "then": { - "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
", - "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
" - }, - "hideInAnswer": true - }, - { - "if": "socket:typee=1", - "ifnot": "socket:typee=", - "then": { - "en": "
European wall plug with ground pin (CEE7/4 type E)
", - "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
" - } - }, - { - "if": { - "and": [ - "socket:typee~*", - "socket:typee!=1" - ] - }, - "then": { - "en": "
European wall plug with ground pin (CEE7/4 type E)
", - "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
" - }, - "hideInAnswer": true - }, - { - "if": "socket:chademo=1", - "ifnot": "socket:chademo=", - "then": { - "en": "
Chademo
", - "nl": "
Chademo
" - }, - "hideInAnswer": { - "or": [ - { - "and": [ - "car=no", - "motorcar=no", - "hgv=no", - "bus=no" + "id": "access", + "question": { + "en": "Who is allowed to use this charging station?" + }, + "render": { + "en": "Access is {access}" + }, + "freeform": { + "key": "access", + "addExtraTags": [ + "fixme=Freeform field used for access - doublecheck the value" ] - }, - { - "and": [ - { - "or": [ - "bicycle=yes", - "scooter=yes" - ] - }, - "car!=yes", - "motorcar!=yes", - "hgv!=yes", - "bus!=yes" - ] - } + }, + "mappings": [ + { + "if": "access=yes", + "then": "Anyone can use this charging station (payment might be needed)" + }, + { + "if": { + "or": [ + "access=permissive", + "access=public" + ] + }, + "then": "Anyone can use this charging station (payment might be needed)", + "hideInAnswer": true + }, + { + "if": "access=customers", + "then": "Only customers of the place this station belongs to can use this charging station
E.g. a charging station operated by hotel which is only usable by their guests " + }, + { + "if": "access=private", + "then": "Not accessible to the general public (e.g. only accessible to the owners, employees, ...)" + } ] - } }, { - "if": { - "and": [ - "socket:chademo~*", - "socket:chademo!=1" - ] - }, - "then": { - "en": "
Chademo
", - "nl": "
Chademo
" - }, - "hideInAnswer": true - }, - { - "if": "socket:type1_cable=1", - "ifnot": "socket:type1_cable=", - "then": { - "en": "
Type 1 with cable (J1772)
", - "nl": "
Type 1 met kabel (J1772)
" - }, - "hideInAnswer": { - "or": [ - { - "and": [ - "car=no", - "motorcar=no", - "hgv=no", - "bus=no" - ] - }, - { - "and": [ - { - "or": [ - "bicycle=yes", - "scooter=yes" - ] - }, - "car!=yes", - "motorcar!=yes", - "hgv!=yes", - "bus!=yes" - ] - } - ] - } - }, - { - "if": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=1" - ] - }, - "then": { - "en": "
Type 1 with cable (J1772)
", - "nl": "
Type 1 met kabel (J1772)
" - }, - "hideInAnswer": true - }, - { - "if": "socket:type1=1", - "ifnot": "socket:type1=", - "then": { - "en": "
Type 1 without cable (J1772)
", - "nl": "
Type 1 zonder kabel (J1772)
" - }, - "hideInAnswer": { - "or": [ - { - "and": [ - "car=no", - "motorcar=no", - "hgv=no", - "bus=no" - ] - }, - { - "and": [ - { - "or": [ - "bicycle=yes", - "scooter=yes" - ] - }, - "car!=yes", - "motorcar!=yes", - "hgv!=yes", - "bus!=yes" - ] - } - ] - } - }, - { - "if": { - "and": [ - "socket:type1~*", - "socket:type1!=1" - ] - }, - "then": { - "en": "
Type 1 without cable (J1772)
", - "nl": "
Type 1 zonder kabel (J1772)
" - }, - "hideInAnswer": true - }, - { - "if": "socket:type1_combo=1", - "ifnot": "socket:type1_combo=", - "then": { - "en": "
Type 1 CCS (aka Type 1 Combo)
", - "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
" - }, - "hideInAnswer": { - "or": [ - { - "and": [ - "car=no", - "motorcar=no", - "hgv=no", - "bus=no" - ] - }, - { - "and": [ - { - "or": [ - "bicycle=yes", - "scooter=yes" - ] - }, - "car!=yes", - "motorcar!=yes", - "hgv!=yes", - "bus!=yes" - ] - } - ] - } - }, - { - "if": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=1" - ] - }, - "then": { - "en": "
Type 1 CCS (aka Type 1 Combo)
", - "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
" - }, - "hideInAnswer": true - }, - { - "if": "socket:tesla_supercharger=1", - "ifnot": "socket:tesla_supercharger=", - "then": { - "en": "
Tesla Supercharger
", - "nl": "
Tesla Supercharger
" - }, - "hideInAnswer": { - "or": [ - { - "and": [ - "car=no", - "motorcar=no", - "hgv=no", - "bus=no" - ] - }, - { - "and": [ - { - "or": [ - "bicycle=yes", - "scooter=yes" - ] - }, - "car!=yes", - "motorcar!=yes", - "hgv!=yes", - "bus!=yes" - ] - } - ] - } - }, - { - "if": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=1" - ] - }, - "then": { - "en": "
Tesla Supercharger
", - "nl": "
Tesla Supercharger
" - }, - "hideInAnswer": true - }, - { - "if": "socket:type2=1", - "ifnot": "socket:type2=", - "then": { - "en": "
Type 2 (mennekes)
", - "nl": "
Type 2 (mennekes)
" - }, - "hideInAnswer": { - "or": [ - { - "and": [ - "car=no", - "motorcar=no", - "hgv=no", - "bus=no" - ] - }, - { - "and": [ - { - "or": [ - "bicycle=yes", - "scooter=yes" - ] - }, - "car!=yes", - "motorcar!=yes", - "hgv!=yes", - "bus!=yes" - ] - } - ] - } - }, - { - "if": { - "and": [ - "socket:type2~*", - "socket:type2!=1" - ] - }, - "then": { - "en": "
Type 2 (mennekes)
", - "nl": "
Type 2 (mennekes)
" - }, - "hideInAnswer": true - }, - { - "if": "socket:type2_combo=1", - "ifnot": "socket:type2_combo=", - "then": { - "en": "
Type 2 CCS (mennekes)
", - "nl": "
Type 2 CCS (mennekes)
" - }, - "hideInAnswer": { - "or": [ - { - "and": [ - "car=no", - "motorcar=no", - "hgv=no", - "bus=no" - ] - }, - { - "and": [ - { - "or": [ - "bicycle=yes", - "scooter=yes" - ] - }, - "car!=yes", - "motorcar!=yes", - "hgv!=yes", - "bus!=yes" - ] - } - ] - } - }, - { - "if": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=1" - ] - }, - "then": { - "en": "
Type 2 CCS (mennekes)
", - "nl": "
Type 2 CCS (mennekes)
" - }, - "hideInAnswer": true - }, - { - "if": "socket:type2_cable=1", - "ifnot": "socket:type2_cable=", - "then": { - "en": "
Type 2 with cable (mennekes)
", - "nl": "
Type 2 met kabel (J1772)
" - }, - "hideInAnswer": { - "or": [ - { - "and": [ - "car=no", - "motorcar=no", - "hgv=no", - "bus=no" - ] - }, - { - "and": [ - { - "or": [ - "bicycle=yes", - "scooter=yes" - ] - }, - "car!=yes", - "motorcar!=yes", - "hgv!=yes", - "bus!=yes" - ] - } - ] - } - }, - { - "if": { - "and": [ - "socket:type2_cable~*", - "socket:type2_cable!=1" - ] - }, - "then": { - "en": "
Type 2 with cable (mennekes)
", - "nl": "
Type 2 met kabel (J1772)
" - }, - "hideInAnswer": true - }, - { - "if": "socket:tesla_supercharger_ccs=1", - "ifnot": "socket:tesla_supercharger_ccs=", - "then": { - "en": "
Tesla Supercharger CCS (a branded type2_css)
", - "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
" - }, - "hideInAnswer": { - "or": [ - { - "and": [ - "car=no", - "motorcar=no", - "hgv=no", - "bus=no" - ] - }, - { - "and": [ - { - "or": [ - "bicycle=yes", - "scooter=yes" - ] - }, - "car!=yes", - "motorcar!=yes", - "hgv!=yes", - "bus!=yes" - ] - } - ] - } - }, - { - "if": { - "and": [ - "socket:tesla_supercharger_ccs~*", - "socket:tesla_supercharger_ccs!=1" - ] - }, - "then": { - "en": "
Tesla Supercharger CCS (a branded type2_css)
", - "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
" - }, - "hideInAnswer": true - }, - { - "if": "socket:tesla_destination=1", - "ifnot": "socket:tesla_destination=", - "then": { - "en": "
Tesla Supercharger (destination)
", - "nl": "
Tesla Supercharger (destination)
" - }, - "hideInAnswer": { - "or": [ - { - "and": [ - "car=no", - "motorcar=no", - "hgv=no", - "bus=no" - ] - }, - { - "and": [ - { - "or": [ - "bicycle=yes", - "scooter=yes" - ] - }, - "car!=yes", - "motorcar!=yes", - "hgv!=yes", - "bus!=yes" - ] - }, - { - "or": [ - "_country!=us" - ] - } - ] - } - }, - { - "if": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=1" - ] - }, - "then": { - "en": "
Tesla Supercharger (destination)
", - "nl": "
Tesla Supercharger (destination)
" - }, - "hideInAnswer": true - }, - { - "if": "socket:tesla_destination=1", - "ifnot": "socket:tesla_destination=", - "then": { - "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
", - "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
" - }, - "hideInAnswer": { - "or": [ - { - "and": [ - "car=no", - "motorcar=no", - "hgv=no", - "bus=no" - ] - }, - { - "and": [ - { - "or": [ - "bicycle=yes", - "scooter=yes" - ] - }, - "car!=yes", - "motorcar!=yes", - "hgv!=yes", - "bus!=yes" - ] - }, - { - "or": [ - "_country=us" - ] - } - ] - } - }, - { - "if": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=1" - ] - }, - "then": { - "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
", - "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
" - }, - "hideInAnswer": true - }, - { - "if": "socket:USB-A=1", - "ifnot": "socket:USB-A=", - "then": { - "en": "
USB to charge phones and small electronics
", - "nl": "
USB om GSMs en kleine electronica op te laden
" - } - }, - { - "if": { - "and": [ - "socket:USB-A~*", - "socket:USB-A!=1" - ] - }, - "then": { - "en": "
USB to charge phones and small electronics
", - "nl": "
USB om GSMs en kleine electronica op te laden
" - }, - "hideInAnswer": true - }, - { - "if": "socket:bosch_3pin=1", - "ifnot": "socket:bosch_3pin=", - "then": { - "en": "
Bosch Active Connect with cable
", - "nl": "
Bosch Active Connect aan een kabel
" - }, - "hideInAnswer": { - "or": [ - { - "and": [ - "bicycle=no" - ] - }, - { - "and": [ - { - "or": [ - "car=yes", - "motorcar=yes", - "hgv=yes", - "bus=yes" - ] - }, - "bicycle!=yes" - ] - } - ] - } - }, - { - "if": { - "and": [ - "socket:bosch_3pin~*", - "socket:bosch_3pin!=1" - ] - }, - "then": { - "en": "
Bosch Active Connect with cable
", - "nl": "
Bosch Active Connect aan een kabel
" - }, - "hideInAnswer": true - } - ] - }, - { - "id": "plugs-0", - "question": { - "en": "How much plugs of type
Schuko wall plug without ground pin (CEE7/4 type F)
are available here?", - "nl": "Hoeveel stekkers van type
Schuko stekker zonder aardingspin (CEE7/4 type F)
heeft dit oplaadpunt?" - }, - "render": { - "en": "There are {socket:schuko} plugs of type
Schuko wall plug without ground pin (CEE7/4 type F)
available here", - "nl": "Hier zijn {socket:schuko} stekkers van het type
Schuko stekker zonder aardingspin (CEE7/4 type F)
" - }, - "freeform": { - "key": "socket:schuko", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "id": "voltage-0", - "question": { - "en": "What voltage do the plugs with
Schuko wall plug without ground pin (CEE7/4 type F)
offer?", - "nl": "Welke spanning levert de stekker van type
Schuko stekker zonder aardingspin (CEE7/4 type F)
" - }, - "render": { - "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
outputs {socket:schuko:voltage} volt", - "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
heeft een spanning van {socket:schuko:voltage} volt" - }, - "freeform": { - "key": "socket:schuko:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:schuko:voltage=230 V", - "then": { - "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
outputs 230 volt", - "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
heeft een spanning van 230 volt" - } - } - ], - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "id": "current-0", - "question": { - "en": "What current do the plugs with
Schuko wall plug without ground pin (CEE7/4 type F)
offer?", - "nl": "Welke stroom levert de stekker van type
Schuko stekker zonder aardingspin (CEE7/4 type F)
?" - }, - "render": { - "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
outputs at most {socket:schuko:current}A", - "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
levert een stroom van maximaal {socket:schuko:current}A" - }, - "freeform": { - "key": "socket:schuko:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:schuko:current=16 A", - "then": { - "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
outputs at most 16 A", - "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
levert een stroom van maximaal 16 A" - } - } - ], - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "id": "power-output-0", - "question": { - "en": "What power output does a single plug of type
Schuko wall plug without ground pin (CEE7/4 type F)
offer?", - "nl": "Welk vermogen levert een enkele stekker van type
Schuko stekker zonder aardingspin (CEE7/4 type F)
?" - }, - "render": { - "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
outputs at most {socket:schuko:output}", - "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
levert een vermogen van maximaal {socket:schuko:output}" - }, - "freeform": { - "key": "socket:schuko:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:schuko:output=3.6 kw", - "then": { - "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
outputs at most 3.6 kw", - "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
levert een vermogen van maximaal 3.6 kw" - } - } - ], - "condition": { - "and": [ - "socket:schuko~*", - "socket:schuko!=0" - ] - } - }, - { - "id": "plugs-1", - "question": { - "en": "How much plugs of type
European wall plug with ground pin (CEE7/4 type E)
are available here?", - "nl": "Hoeveel stekkers van type
Europese stekker met aardingspin (CEE7/4 type E)
heeft dit oplaadpunt?" - }, - "render": { - "en": "There are {socket:typee} plugs of type
European wall plug with ground pin (CEE7/4 type E)
available here", - "nl": "Hier zijn {socket:typee} stekkers van het type
Europese stekker met aardingspin (CEE7/4 type E)
" - }, - "freeform": { - "key": "socket:typee", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "id": "voltage-1", - "question": { - "en": "What voltage do the plugs with
European wall plug with ground pin (CEE7/4 type E)
offer?", - "nl": "Welke spanning levert de stekker van type
Europese stekker met aardingspin (CEE7/4 type E)
" - }, - "render": { - "en": "
European wall plug with ground pin (CEE7/4 type E)
outputs {socket:typee:voltage} volt", - "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
heeft een spanning van {socket:typee:voltage} volt" - }, - "freeform": { - "key": "socket:typee:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:typee:voltage=230 V", - "then": { - "en": "
European wall plug with ground pin (CEE7/4 type E)
outputs 230 volt", - "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
heeft een spanning van 230 volt" - } - } - ], - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "id": "current-1", - "question": { - "en": "What current do the plugs with
European wall plug with ground pin (CEE7/4 type E)
offer?", - "nl": "Welke stroom levert de stekker van type
Europese stekker met aardingspin (CEE7/4 type E)
?" - }, - "render": { - "en": "
European wall plug with ground pin (CEE7/4 type E)
outputs at most {socket:typee:current}A", - "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
levert een stroom van maximaal {socket:typee:current}A" - }, - "freeform": { - "key": "socket:typee:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:typee:current=16 A", - "then": { - "en": "
European wall plug with ground pin (CEE7/4 type E)
outputs at most 16 A", - "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
levert een stroom van maximaal 16 A" - } - } - ], - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "id": "power-output-1", - "question": { - "en": "What power output does a single plug of type
European wall plug with ground pin (CEE7/4 type E)
offer?", - "nl": "Welk vermogen levert een enkele stekker van type
Europese stekker met aardingspin (CEE7/4 type E)
?" - }, - "render": { - "en": "
European wall plug with ground pin (CEE7/4 type E)
outputs at most {socket:typee:output}", - "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
levert een vermogen van maximaal {socket:typee:output}" - }, - "freeform": { - "key": "socket:typee:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:typee:output=3 kw", - "then": { - "en": "
European wall plug with ground pin (CEE7/4 type E)
outputs at most 3 kw", - "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
levert een vermogen van maximaal 3 kw" - } - }, - { - "if": "socket:socket:typee:output=22 kw", - "then": { - "en": "
European wall plug with ground pin (CEE7/4 type E)
outputs at most 22 kw", - "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
levert een vermogen van maximaal 22 kw" - } - } - ], - "condition": { - "and": [ - "socket:typee~*", - "socket:typee!=0" - ] - } - }, - { - "id": "plugs-2", - "question": { - "en": "How much plugs of type
Chademo
are available here?", - "nl": "Hoeveel stekkers van type
Chademo
heeft dit oplaadpunt?" - }, - "render": { - "en": "There are {socket:chademo} plugs of type
Chademo
available here", - "nl": "Hier zijn {socket:chademo} stekkers van het type
Chademo
" - }, - "freeform": { - "key": "socket:chademo", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "id": "voltage-2", - "question": { - "en": "What voltage do the plugs with
Chademo
offer?", - "nl": "Welke spanning levert de stekker van type
Chademo
" - }, - "render": { - "en": "
Chademo
outputs {socket:chademo:voltage} volt", - "nl": "
Chademo
heeft een spanning van {socket:chademo:voltage} volt" - }, - "freeform": { - "key": "socket:chademo:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:chademo:voltage=500 V", - "then": { - "en": "
Chademo
outputs 500 volt", - "nl": "
Chademo
heeft een spanning van 500 volt" - } - } - ], - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "id": "current-2", - "question": { - "en": "What current do the plugs with
Chademo
offer?", - "nl": "Welke stroom levert de stekker van type
Chademo
?" - }, - "render": { - "en": "
Chademo
outputs at most {socket:chademo:current}A", - "nl": "
Chademo
levert een stroom van maximaal {socket:chademo:current}A" - }, - "freeform": { - "key": "socket:chademo:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:chademo:current=120 A", - "then": { - "en": "
Chademo
outputs at most 120 A", - "nl": "
Chademo
levert een stroom van maximaal 120 A" - } - } - ], - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "id": "power-output-2", - "question": { - "en": "What power output does a single plug of type
Chademo
offer?", - "nl": "Welk vermogen levert een enkele stekker van type
Chademo
?" - }, - "render": { - "en": "
Chademo
outputs at most {socket:chademo:output}", - "nl": "
Chademo
levert een vermogen van maximaal {socket:chademo:output}" - }, - "freeform": { - "key": "socket:chademo:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:chademo:output=50 kw", - "then": { - "en": "
Chademo
outputs at most 50 kw", - "nl": "
Chademo
levert een vermogen van maximaal 50 kw" - } - } - ], - "condition": { - "and": [ - "socket:chademo~*", - "socket:chademo!=0" - ] - } - }, - { - "id": "plugs-3", - "question": { - "en": "How much plugs of type
Type 1 with cable (J1772)
are available here?", - "nl": "Hoeveel stekkers van type
Type 1 met kabel (J1772)
heeft dit oplaadpunt?" - }, - "render": { - "en": "There are {socket:type1_cable} plugs of type
Type 1 with cable (J1772)
available here", - "nl": "Hier zijn {socket:type1_cable} stekkers van het type
Type 1 met kabel (J1772)
" - }, - "freeform": { - "key": "socket:type1_cable", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "id": "voltage-3", - "question": { - "en": "What voltage do the plugs with
Type 1 with cable (J1772)
offer?", - "nl": "Welke spanning levert de stekker van type
Type 1 met kabel (J1772)
" - }, - "render": { - "en": "
Type 1 with cable (J1772)
outputs {socket:type1_cable:voltage} volt", - "nl": "
Type 1 met kabel (J1772)
heeft een spanning van {socket:type1_cable:voltage} volt" - }, - "freeform": { - "key": "socket:type1_cable:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_cable:voltage=200 V", - "then": { - "en": "
Type 1 with cable (J1772)
outputs 200 volt", - "nl": "
Type 1 met kabel (J1772)
heeft een spanning van 200 volt" - } - }, - { - "if": "socket:socket:type1_cable:voltage=240 V", - "then": { - "en": "
Type 1 with cable (J1772)
outputs 240 volt", - "nl": "
Type 1 met kabel (J1772)
heeft een spanning van 240 volt" - } - } - ], - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "id": "current-3", - "question": { - "en": "What current do the plugs with
Type 1 with cable (J1772)
offer?", - "nl": "Welke stroom levert de stekker van type
Type 1 met kabel (J1772)
?" - }, - "render": { - "en": "
Type 1 with cable (J1772)
outputs at most {socket:type1_cable:current}A", - "nl": "
Type 1 met kabel (J1772)
levert een stroom van maximaal {socket:type1_cable:current}A" - }, - "freeform": { - "key": "socket:type1_cable:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_cable:current=32 A", - "then": { - "en": "
Type 1 with cable (J1772)
outputs at most 32 A", - "nl": "
Type 1 met kabel (J1772)
levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "id": "power-output-3", - "question": { - "en": "What power output does a single plug of type
Type 1 with cable (J1772)
offer?", - "nl": "Welk vermogen levert een enkele stekker van type
Type 1 met kabel (J1772)
?" - }, - "render": { - "en": "
Type 1 with cable (J1772)
outputs at most {socket:type1_cable:output}", - "nl": "
Type 1 met kabel (J1772)
levert een vermogen van maximaal {socket:type1_cable:output}" - }, - "freeform": { - "key": "socket:type1_cable:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_cable:output=3.7 kw", - "then": { - "en": "
Type 1 with cable (J1772)
outputs at most 3.7 kw", - "nl": "
Type 1 met kabel (J1772)
levert een vermogen van maximaal 3.7 kw" - } - }, - { - "if": "socket:socket:type1_cable:output=7 kw", - "then": { - "en": "
Type 1 with cable (J1772)
outputs at most 7 kw", - "nl": "
Type 1 met kabel (J1772)
levert een vermogen van maximaal 7 kw" - } - } - ], - "condition": { - "and": [ - "socket:type1_cable~*", - "socket:type1_cable!=0" - ] - } - }, - { - "id": "plugs-4", - "question": { - "en": "How much plugs of type
Type 1 without cable (J1772)
are available here?", - "nl": "Hoeveel stekkers van type
Type 1 zonder kabel (J1772)
heeft dit oplaadpunt?" - }, - "render": { - "en": "There are {socket:type1} plugs of type
Type 1 without cable (J1772)
available here", - "nl": "Hier zijn {socket:type1} stekkers van het type
Type 1 zonder kabel (J1772)
" - }, - "freeform": { - "key": "socket:type1", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "id": "voltage-4", - "question": { - "en": "What voltage do the plugs with
Type 1 without cable (J1772)
offer?", - "nl": "Welke spanning levert de stekker van type
Type 1 zonder kabel (J1772)
" - }, - "render": { - "en": "
Type 1 without cable (J1772)
outputs {socket:type1:voltage} volt", - "nl": "
Type 1 zonder kabel (J1772)
heeft een spanning van {socket:type1:voltage} volt" - }, - "freeform": { - "key": "socket:type1:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1:voltage=200 V", - "then": { - "en": "
Type 1 without cable (J1772)
outputs 200 volt", - "nl": "
Type 1 zonder kabel (J1772)
heeft een spanning van 200 volt" - } - }, - { - "if": "socket:socket:type1:voltage=240 V", - "then": { - "en": "
Type 1 without cable (J1772)
outputs 240 volt", - "nl": "
Type 1 zonder kabel (J1772)
heeft een spanning van 240 volt" - } - } - ], - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "id": "current-4", - "question": { - "en": "What current do the plugs with
Type 1 without cable (J1772)
offer?", - "nl": "Welke stroom levert de stekker van type
Type 1 zonder kabel (J1772)
?" - }, - "render": { - "en": "
Type 1 without cable (J1772)
outputs at most {socket:type1:current}A", - "nl": "
Type 1 zonder kabel (J1772)
levert een stroom van maximaal {socket:type1:current}A" - }, - "freeform": { - "key": "socket:type1:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1:current=32 A", - "then": { - "en": "
Type 1 without cable (J1772)
outputs at most 32 A", - "nl": "
Type 1 zonder kabel (J1772)
levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "id": "power-output-4", - "question": { - "en": "What power output does a single plug of type
Type 1 without cable (J1772)
offer?", - "nl": "Welk vermogen levert een enkele stekker van type
Type 1 zonder kabel (J1772)
?" - }, - "render": { - "en": "
Type 1 without cable (J1772)
outputs at most {socket:type1:output}", - "nl": "
Type 1 zonder kabel (J1772)
levert een vermogen van maximaal {socket:type1:output}" - }, - "freeform": { - "key": "socket:type1:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1:output=3.7 kw", - "then": { - "en": "
Type 1 without cable (J1772)
outputs at most 3.7 kw", - "nl": "
Type 1 zonder kabel (J1772)
levert een vermogen van maximaal 3.7 kw" - } - }, - { - "if": "socket:socket:type1:output=6.6 kw", - "then": { - "en": "
Type 1 without cable (J1772)
outputs at most 6.6 kw", - "nl": "
Type 1 zonder kabel (J1772)
levert een vermogen van maximaal 6.6 kw" - } - }, - { - "if": "socket:socket:type1:output=7 kw", - "then": { - "en": "
Type 1 without cable (J1772)
outputs at most 7 kw", - "nl": "
Type 1 zonder kabel (J1772)
levert een vermogen van maximaal 7 kw" - } - }, - { - "if": "socket:socket:type1:output=7.2 kw", - "then": { - "en": "
Type 1 without cable (J1772)
outputs at most 7.2 kw", - "nl": "
Type 1 zonder kabel (J1772)
levert een vermogen van maximaal 7.2 kw" - } - } - ], - "condition": { - "and": [ - "socket:type1~*", - "socket:type1!=0" - ] - } - }, - { - "id": "plugs-5", - "question": { - "en": "How much plugs of type
Type 1 CCS (aka Type 1 Combo)
are available here?", - "nl": "Hoeveel stekkers van type
Type 1 CCS (ook gekend als Type 1 Combo)
heeft dit oplaadpunt?" - }, - "render": { - "en": "There are {socket:type1_combo} plugs of type
Type 1 CCS (aka Type 1 Combo)
available here", - "nl": "Hier zijn {socket:type1_combo} stekkers van het type
Type 1 CCS (ook gekend als Type 1 Combo)
" - }, - "freeform": { - "key": "socket:type1_combo", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "id": "voltage-5", - "question": { - "en": "What voltage do the plugs with
Type 1 CCS (aka Type 1 Combo)
offer?", - "nl": "Welke spanning levert de stekker van type
Type 1 CCS (ook gekend als Type 1 Combo)
" - }, - "render": { - "en": "
Type 1 CCS (aka Type 1 Combo)
outputs {socket:type1_combo:voltage} volt", - "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
heeft een spanning van {socket:type1_combo:voltage} volt" - }, - "freeform": { - "key": "socket:type1_combo:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_combo:voltage=400 V", - "then": { - "en": "
Type 1 CCS (aka Type 1 Combo)
outputs 400 volt", - "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
heeft een spanning van 400 volt" - } - }, - { - "if": "socket:socket:type1_combo:voltage=1000 V", - "then": { - "en": "
Type 1 CCS (aka Type 1 Combo)
outputs 1000 volt", - "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
heeft een spanning van 1000 volt" - } - } - ], - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "id": "current-5", - "question": { - "en": "What current do the plugs with
Type 1 CCS (aka Type 1 Combo)
offer?", - "nl": "Welke stroom levert de stekker van type
Type 1 CCS (ook gekend als Type 1 Combo)
?" - }, - "render": { - "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most {socket:type1_combo:current}A", - "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een stroom van maximaal {socket:type1_combo:current}A" - }, - "freeform": { - "key": "socket:type1_combo:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_combo:current=50 A", - "then": { - "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most 50 A", - "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een stroom van maximaal 50 A" - } - }, - { - "if": "socket:socket:type1_combo:current=125 A", - "then": { - "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most 125 A", - "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een stroom van maximaal 125 A" - } - } - ], - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "id": "power-output-5", - "question": { - "en": "What power output does a single plug of type
Type 1 CCS (aka Type 1 Combo)
offer?", - "nl": "Welk vermogen levert een enkele stekker van type
Type 1 CCS (ook gekend als Type 1 Combo)
?" - }, - "render": { - "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most {socket:type1_combo:output}", - "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een vermogen van maximaal {socket:type1_combo:output}" - }, - "freeform": { - "key": "socket:type1_combo:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type1_combo:output=50 kw", - "then": { - "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most 50 kw", - "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een vermogen van maximaal 50 kw" - } - }, - { - "if": "socket:socket:type1_combo:output=62.5 kw", - "then": { - "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most 62.5 kw", - "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een vermogen van maximaal 62.5 kw" - } - }, - { - "if": "socket:socket:type1_combo:output=150 kw", - "then": { - "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most 150 kw", - "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een vermogen van maximaal 150 kw" - } - }, - { - "if": "socket:socket:type1_combo:output=350 kw", - "then": { - "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most 350 kw", - "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een vermogen van maximaal 350 kw" - } - } - ], - "condition": { - "and": [ - "socket:type1_combo~*", - "socket:type1_combo!=0" - ] - } - }, - { - "id": "plugs-6", - "question": { - "en": "How much plugs of type
Tesla Supercharger
are available here?", - "nl": "Hoeveel stekkers van type
Tesla Supercharger
heeft dit oplaadpunt?" - }, - "render": { - "en": "There are {socket:tesla_supercharger} plugs of type
Tesla Supercharger
available here", - "nl": "Hier zijn {socket:tesla_supercharger} stekkers van het type
Tesla Supercharger
" - }, - "freeform": { - "key": "socket:tesla_supercharger", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "id": "voltage-6", - "question": { - "en": "What voltage do the plugs with
Tesla Supercharger
offer?", - "nl": "Welke spanning levert de stekker van type
Tesla Supercharger
" - }, - "render": { - "en": "
Tesla Supercharger
outputs {socket:tesla_supercharger:voltage} volt", - "nl": "
Tesla Supercharger
heeft een spanning van {socket:tesla_supercharger:voltage} volt" - }, - "freeform": { - "key": "socket:tesla_supercharger:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger:voltage=480 V", - "then": { - "en": "
Tesla Supercharger
outputs 480 volt", - "nl": "
Tesla Supercharger
heeft een spanning van 480 volt" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "id": "current-6", - "question": { - "en": "What current do the plugs with
Tesla Supercharger
offer?", - "nl": "Welke stroom levert de stekker van type
Tesla Supercharger
?" - }, - "render": { - "en": "
Tesla Supercharger
outputs at most {socket:tesla_supercharger:current}A", - "nl": "
Tesla Supercharger
levert een stroom van maximaal {socket:tesla_supercharger:current}A" - }, - "freeform": { - "key": "socket:tesla_supercharger:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger:current=125 A", - "then": { - "en": "
Tesla Supercharger
outputs at most 125 A", - "nl": "
Tesla Supercharger
levert een stroom van maximaal 125 A" - } - }, - { - "if": "socket:socket:tesla_supercharger:current=350 A", - "then": { - "en": "
Tesla Supercharger
outputs at most 350 A", - "nl": "
Tesla Supercharger
levert een stroom van maximaal 350 A" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "id": "power-output-6", - "question": { - "en": "What power output does a single plug of type
Tesla Supercharger
offer?", - "nl": "Welk vermogen levert een enkele stekker van type
Tesla Supercharger
?" - }, - "render": { - "en": "
Tesla Supercharger
outputs at most {socket:tesla_supercharger:output}", - "nl": "
Tesla Supercharger
levert een vermogen van maximaal {socket:tesla_supercharger:output}" - }, - "freeform": { - "key": "socket:tesla_supercharger:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger:output=120 kw", - "then": { - "en": "
Tesla Supercharger
outputs at most 120 kw", - "nl": "
Tesla Supercharger
levert een vermogen van maximaal 120 kw" - } - }, - { - "if": "socket:socket:tesla_supercharger:output=150 kw", - "then": { - "en": "
Tesla Supercharger
outputs at most 150 kw", - "nl": "
Tesla Supercharger
levert een vermogen van maximaal 150 kw" - } - }, - { - "if": "socket:socket:tesla_supercharger:output=250 kw", - "then": { - "en": "
Tesla Supercharger
outputs at most 250 kw", - "nl": "
Tesla Supercharger
levert een vermogen van maximaal 250 kw" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger~*", - "socket:tesla_supercharger!=0" - ] - } - }, - { - "id": "plugs-7", - "question": { - "en": "How much plugs of type
Type 2 (mennekes)
are available here?", - "nl": "Hoeveel stekkers van type
Type 2 (mennekes)
heeft dit oplaadpunt?" - }, - "render": { - "en": "There are {socket:type2} plugs of type
Type 2 (mennekes)
available here", - "nl": "Hier zijn {socket:type2} stekkers van het type
Type 2 (mennekes)
" - }, - "freeform": { - "key": "socket:type2", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "id": "voltage-7", - "question": { - "en": "What voltage do the plugs with
Type 2 (mennekes)
offer?", - "nl": "Welke spanning levert de stekker van type
Type 2 (mennekes)
" - }, - "render": { - "en": "
Type 2 (mennekes)
outputs {socket:type2:voltage} volt", - "nl": "
Type 2 (mennekes)
heeft een spanning van {socket:type2:voltage} volt" - }, - "freeform": { - "key": "socket:type2:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2:voltage=230 V", - "then": { - "en": "
Type 2 (mennekes)
outputs 230 volt", - "nl": "
Type 2 (mennekes)
heeft een spanning van 230 volt" - } - }, - { - "if": "socket:socket:type2:voltage=400 V", - "then": { - "en": "
Type 2 (mennekes)
outputs 400 volt", - "nl": "
Type 2 (mennekes)
heeft een spanning van 400 volt" - } - } - ], - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "id": "current-7", - "question": { - "en": "What current do the plugs with
Type 2 (mennekes)
offer?", - "nl": "Welke stroom levert de stekker van type
Type 2 (mennekes)
?" - }, - "render": { - "en": "
Type 2 (mennekes)
outputs at most {socket:type2:current}A", - "nl": "
Type 2 (mennekes)
levert een stroom van maximaal {socket:type2:current}A" - }, - "freeform": { - "key": "socket:type2:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2:current=16 A", - "then": { - "en": "
Type 2 (mennekes)
outputs at most 16 A", - "nl": "
Type 2 (mennekes)
levert een stroom van maximaal 16 A" - } - }, - { - "if": "socket:socket:type2:current=32 A", - "then": { - "en": "
Type 2 (mennekes)
outputs at most 32 A", - "nl": "
Type 2 (mennekes)
levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "id": "power-output-7", - "question": { - "en": "What power output does a single plug of type
Type 2 (mennekes)
offer?", - "nl": "Welk vermogen levert een enkele stekker van type
Type 2 (mennekes)
?" - }, - "render": { - "en": "
Type 2 (mennekes)
outputs at most {socket:type2:output}", - "nl": "
Type 2 (mennekes)
levert een vermogen van maximaal {socket:type2:output}" - }, - "freeform": { - "key": "socket:type2:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2:output=11 kw", - "then": { - "en": "
Type 2 (mennekes)
outputs at most 11 kw", - "nl": "
Type 2 (mennekes)
levert een vermogen van maximaal 11 kw" - } - }, - { - "if": "socket:socket:type2:output=22 kw", - "then": { - "en": "
Type 2 (mennekes)
outputs at most 22 kw", - "nl": "
Type 2 (mennekes)
levert een vermogen van maximaal 22 kw" - } - } - ], - "condition": { - "and": [ - "socket:type2~*", - "socket:type2!=0" - ] - } - }, - { - "id": "plugs-8", - "question": { - "en": "How much plugs of type
Type 2 CCS (mennekes)
are available here?", - "nl": "Hoeveel stekkers van type
Type 2 CCS (mennekes)
heeft dit oplaadpunt?" - }, - "render": { - "en": "There are {socket:type2_combo} plugs of type
Type 2 CCS (mennekes)
available here", - "nl": "Hier zijn {socket:type2_combo} stekkers van het type
Type 2 CCS (mennekes)
" - }, - "freeform": { - "key": "socket:type2_combo", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "id": "voltage-8", - "question": { - "en": "What voltage do the plugs with
Type 2 CCS (mennekes)
offer?", - "nl": "Welke spanning levert de stekker van type
Type 2 CCS (mennekes)
" - }, - "render": { - "en": "
Type 2 CCS (mennekes)
outputs {socket:type2_combo:voltage} volt", - "nl": "
Type 2 CCS (mennekes)
heeft een spanning van {socket:type2_combo:voltage} volt" - }, - "freeform": { - "key": "socket:type2_combo:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_combo:voltage=500 V", - "then": { - "en": "
Type 2 CCS (mennekes)
outputs 500 volt", - "nl": "
Type 2 CCS (mennekes)
heeft een spanning van 500 volt" - } - }, - { - "if": "socket:socket:type2_combo:voltage=920 V", - "then": { - "en": "
Type 2 CCS (mennekes)
outputs 920 volt", - "nl": "
Type 2 CCS (mennekes)
heeft een spanning van 920 volt" - } - } - ], - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "id": "current-8", - "question": { - "en": "What current do the plugs with
Type 2 CCS (mennekes)
offer?", - "nl": "Welke stroom levert de stekker van type
Type 2 CCS (mennekes)
?" - }, - "render": { - "en": "
Type 2 CCS (mennekes)
outputs at most {socket:type2_combo:current}A", - "nl": "
Type 2 CCS (mennekes)
levert een stroom van maximaal {socket:type2_combo:current}A" - }, - "freeform": { - "key": "socket:type2_combo:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_combo:current=125 A", - "then": { - "en": "
Type 2 CCS (mennekes)
outputs at most 125 A", - "nl": "
Type 2 CCS (mennekes)
levert een stroom van maximaal 125 A" - } - }, - { - "if": "socket:socket:type2_combo:current=350 A", - "then": { - "en": "
Type 2 CCS (mennekes)
outputs at most 350 A", - "nl": "
Type 2 CCS (mennekes)
levert een stroom van maximaal 350 A" - } - } - ], - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "id": "power-output-8", - "question": { - "en": "What power output does a single plug of type
Type 2 CCS (mennekes)
offer?", - "nl": "Welk vermogen levert een enkele stekker van type
Type 2 CCS (mennekes)
?" - }, - "render": { - "en": "
Type 2 CCS (mennekes)
outputs at most {socket:type2_combo:output}", - "nl": "
Type 2 CCS (mennekes)
levert een vermogen van maximaal {socket:type2_combo:output}" - }, - "freeform": { - "key": "socket:type2_combo:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_combo:output=50 kw", - "then": { - "en": "
Type 2 CCS (mennekes)
outputs at most 50 kw", - "nl": "
Type 2 CCS (mennekes)
levert een vermogen van maximaal 50 kw" - } - } - ], - "condition": { - "and": [ - "socket:type2_combo~*", - "socket:type2_combo!=0" - ] - } - }, - { - "id": "plugs-9", - "question": { - "en": "How much plugs of type
Type 2 with cable (mennekes)
are available here?", - "nl": "Hoeveel stekkers van type
Type 2 met kabel (J1772)
heeft dit oplaadpunt?" - }, - "render": { - "en": "There are {socket:type2_cable} plugs of type
Type 2 with cable (mennekes)
available here", - "nl": "Hier zijn {socket:type2_cable} stekkers van het type
Type 2 met kabel (J1772)
" - }, - "freeform": { - "key": "socket:type2_cable", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:type2_cable~*", - "socket:type2_cable!=0" - ] - } - }, - { - "id": "voltage-9", - "question": { - "en": "What voltage do the plugs with
Type 2 with cable (mennekes)
offer?", - "nl": "Welke spanning levert de stekker van type
Type 2 met kabel (J1772)
" - }, - "render": { - "en": "
Type 2 with cable (mennekes)
outputs {socket:type2_cable:voltage} volt", - "nl": "
Type 2 met kabel (J1772)
heeft een spanning van {socket:type2_cable:voltage} volt" - }, - "freeform": { - "key": "socket:type2_cable:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_cable:voltage=230 V", - "then": { - "en": "
Type 2 with cable (mennekes)
outputs 230 volt", - "nl": "
Type 2 met kabel (J1772)
heeft een spanning van 230 volt" - } - }, - { - "if": "socket:socket:type2_cable:voltage=400 V", - "then": { - "en": "
Type 2 with cable (mennekes)
outputs 400 volt", - "nl": "
Type 2 met kabel (J1772)
heeft een spanning van 400 volt" - } - } - ], - "condition": { - "and": [ - "socket:type2_cable~*", - "socket:type2_cable!=0" - ] - } - }, - { - "id": "current-9", - "question": { - "en": "What current do the plugs with
Type 2 with cable (mennekes)
offer?", - "nl": "Welke stroom levert de stekker van type
Type 2 met kabel (J1772)
?" - }, - "render": { - "en": "
Type 2 with cable (mennekes)
outputs at most {socket:type2_cable:current}A", - "nl": "
Type 2 met kabel (J1772)
levert een stroom van maximaal {socket:type2_cable:current}A" - }, - "freeform": { - "key": "socket:type2_cable:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_cable:current=16 A", - "then": { - "en": "
Type 2 with cable (mennekes)
outputs at most 16 A", - "nl": "
Type 2 met kabel (J1772)
levert een stroom van maximaal 16 A" - } - }, - { - "if": "socket:socket:type2_cable:current=32 A", - "then": { - "en": "
Type 2 with cable (mennekes)
outputs at most 32 A", - "nl": "
Type 2 met kabel (J1772)
levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:type2_cable~*", - "socket:type2_cable!=0" - ] - } - }, - { - "id": "power-output-9", - "question": { - "en": "What power output does a single plug of type
Type 2 with cable (mennekes)
offer?", - "nl": "Welk vermogen levert een enkele stekker van type
Type 2 met kabel (J1772)
?" - }, - "render": { - "en": "
Type 2 with cable (mennekes)
outputs at most {socket:type2_cable:output}", - "nl": "
Type 2 met kabel (J1772)
levert een vermogen van maximaal {socket:type2_cable:output}" - }, - "freeform": { - "key": "socket:type2_cable:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:type2_cable:output=11 kw", - "then": { - "en": "
Type 2 with cable (mennekes)
outputs at most 11 kw", - "nl": "
Type 2 met kabel (J1772)
levert een vermogen van maximaal 11 kw" - } - }, - { - "if": "socket:socket:type2_cable:output=22 kw", - "then": { - "en": "
Type 2 with cable (mennekes)
outputs at most 22 kw", - "nl": "
Type 2 met kabel (J1772)
levert een vermogen van maximaal 22 kw" - } - } - ], - "condition": { - "and": [ - "socket:type2_cable~*", - "socket:type2_cable!=0" - ] - } - }, - { - "id": "plugs-10", - "question": { - "en": "How much plugs of type
Tesla Supercharger CCS (a branded type2_css)
are available here?", - "nl": "Hoeveel stekkers van type
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
heeft dit oplaadpunt?" - }, - "render": { - "en": "There are {socket:tesla_supercharger_ccs} plugs of type
Tesla Supercharger CCS (a branded type2_css)
available here", - "nl": "Hier zijn {socket:tesla_supercharger_ccs} stekkers van het type
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
" - }, - "freeform": { - "key": "socket:tesla_supercharger_ccs", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:tesla_supercharger_ccs~*", - "socket:tesla_supercharger_ccs!=0" - ] - } - }, - { - "id": "voltage-10", - "question": { - "en": "What voltage do the plugs with
Tesla Supercharger CCS (a branded type2_css)
offer?", - "nl": "Welke spanning levert de stekker van type
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
" - }, - "render": { - "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs {socket:tesla_supercharger_ccs:voltage} volt", - "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" - }, - "freeform": { - "key": "socket:tesla_supercharger_ccs:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger_ccs:voltage=500 V", - "then": { - "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs 500 volt", - "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
heeft een spanning van 500 volt" - } - }, - { - "if": "socket:socket:tesla_supercharger_ccs:voltage=920 V", - "then": { - "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs 920 volt", - "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
heeft een spanning van 920 volt" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger_ccs~*", - "socket:tesla_supercharger_ccs!=0" - ] - } - }, - { - "id": "current-10", - "question": { - "en": "What current do the plugs with
Tesla Supercharger CCS (a branded type2_css)
offer?", - "nl": "Welke stroom levert de stekker van type
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
?" - }, - "render": { - "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs at most {socket:tesla_supercharger_ccs:current}A", - "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" - }, - "freeform": { - "key": "socket:tesla_supercharger_ccs:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger_ccs:current=125 A", - "then": { - "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs at most 125 A", - "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
levert een stroom van maximaal 125 A" - } - }, - { - "if": "socket:socket:tesla_supercharger_ccs:current=350 A", - "then": { - "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs at most 350 A", - "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
levert een stroom van maximaal 350 A" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger_ccs~*", - "socket:tesla_supercharger_ccs!=0" - ] - } - }, - { - "id": "power-output-10", - "question": { - "en": "What power output does a single plug of type
Tesla Supercharger CCS (a branded type2_css)
offer?", - "nl": "Welk vermogen levert een enkele stekker van type
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
?" - }, - "render": { - "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs at most {socket:tesla_supercharger_ccs:output}", - "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" - }, - "freeform": { - "key": "socket:tesla_supercharger_ccs:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_supercharger_ccs:output=50 kw", - "then": { - "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs at most 50 kw", - "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
levert een vermogen van maximaal 50 kw" - } - } - ], - "condition": { - "and": [ - "socket:tesla_supercharger_ccs~*", - "socket:tesla_supercharger_ccs!=0" - ] - } - }, - { - "id": "plugs-11", - "question": { - "en": "How much plugs of type
Tesla Supercharger (destination)
are available here?", - "nl": "Hoeveel stekkers van type
Tesla Supercharger (destination)
heeft dit oplaadpunt?" - }, - "render": { - "en": "There are {socket:tesla_destination} plugs of type
Tesla Supercharger (destination)
available here", - "nl": "Hier zijn {socket:tesla_destination} stekkers van het type
Tesla Supercharger (destination)
" - }, - "freeform": { - "key": "socket:tesla_destination", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "id": "voltage-11", - "question": { - "en": "What voltage do the plugs with
Tesla Supercharger (destination)
offer?", - "nl": "Welke spanning levert de stekker van type
Tesla Supercharger (destination)
" - }, - "render": { - "en": "
Tesla Supercharger (destination)
outputs {socket:tesla_destination:voltage} volt", - "nl": "
Tesla Supercharger (destination)
heeft een spanning van {socket:tesla_destination:voltage} volt" - }, - "freeform": { - "key": "socket:tesla_destination:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_destination:voltage=480 V", - "then": { - "en": "
Tesla Supercharger (destination)
outputs 480 volt", - "nl": "
Tesla Supercharger (destination)
heeft een spanning van 480 volt" - } - } - ], - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "id": "current-11", - "question": { - "en": "What current do the plugs with
Tesla Supercharger (destination)
offer?", - "nl": "Welke stroom levert de stekker van type
Tesla Supercharger (destination)
?" - }, - "render": { - "en": "
Tesla Supercharger (destination)
outputs at most {socket:tesla_destination:current}A", - "nl": "
Tesla Supercharger (destination)
levert een stroom van maximaal {socket:tesla_destination:current}A" - }, - "freeform": { - "key": "socket:tesla_destination:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_destination:current=125 A", - "then": { - "en": "
Tesla Supercharger (destination)
outputs at most 125 A", - "nl": "
Tesla Supercharger (destination)
levert een stroom van maximaal 125 A" - } - }, - { - "if": "socket:socket:tesla_destination:current=350 A", - "then": { - "en": "
Tesla Supercharger (destination)
outputs at most 350 A", - "nl": "
Tesla Supercharger (destination)
levert een stroom van maximaal 350 A" - } - } - ], - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "id": "power-output-11", - "question": { - "en": "What power output does a single plug of type
Tesla Supercharger (destination)
offer?", - "nl": "Welk vermogen levert een enkele stekker van type
Tesla Supercharger (destination)
?" - }, - "render": { - "en": "
Tesla Supercharger (destination)
outputs at most {socket:tesla_destination:output}", - "nl": "
Tesla Supercharger (destination)
levert een vermogen van maximaal {socket:tesla_destination:output}" - }, - "freeform": { - "key": "socket:tesla_destination:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_destination:output=120 kw", - "then": { - "en": "
Tesla Supercharger (destination)
outputs at most 120 kw", - "nl": "
Tesla Supercharger (destination)
levert een vermogen van maximaal 120 kw" - } - }, - { - "if": "socket:socket:tesla_destination:output=150 kw", - "then": { - "en": "
Tesla Supercharger (destination)
outputs at most 150 kw", - "nl": "
Tesla Supercharger (destination)
levert een vermogen van maximaal 150 kw" - } - }, - { - "if": "socket:socket:tesla_destination:output=250 kw", - "then": { - "en": "
Tesla Supercharger (destination)
outputs at most 250 kw", - "nl": "
Tesla Supercharger (destination)
levert een vermogen van maximaal 250 kw" - } - } - ], - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "id": "plugs-12", - "question": { - "en": "How much plugs of type
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
are available here?", - "nl": "Hoeveel stekkers van type
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
heeft dit oplaadpunt?" - }, - "render": { - "en": "There are {socket:tesla_destination} plugs of type
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
available here", - "nl": "Hier zijn {socket:tesla_destination} stekkers van het type
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
" - }, - "freeform": { - "key": "socket:tesla_destination", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "id": "voltage-12", - "question": { - "en": "What voltage do the plugs with
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
offer?", - "nl": "Welke spanning levert de stekker van type
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
" - }, - "render": { - "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs {socket:tesla_destination:voltage} volt", - "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
heeft een spanning van {socket:tesla_destination:voltage} volt" - }, - "freeform": { - "key": "socket:tesla_destination:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_destination:voltage=230 V", - "then": { - "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs 230 volt", - "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
heeft een spanning van 230 volt" - } - }, - { - "if": "socket:socket:tesla_destination:voltage=400 V", - "then": { - "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs 400 volt", - "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
heeft een spanning van 400 volt" - } - } - ], - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "id": "current-12", - "question": { - "en": "What current do the plugs with
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
offer?", - "nl": "Welke stroom levert de stekker van type
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
?" - }, - "render": { - "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most {socket:tesla_destination:current}A", - "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
levert een stroom van maximaal {socket:tesla_destination:current}A" - }, - "freeform": { - "key": "socket:tesla_destination:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_destination:current=16 A", - "then": { - "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most 16 A", - "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
levert een stroom van maximaal 16 A" - } - }, - { - "if": "socket:socket:tesla_destination:current=32 A", - "then": { - "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most 32 A", - "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
levert een stroom van maximaal 32 A" - } - } - ], - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "id": "power-output-12", - "question": { - "en": "What power output does a single plug of type
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
offer?", - "nl": "Welk vermogen levert een enkele stekker van type
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
?" - }, - "render": { - "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most {socket:tesla_destination:output}", - "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
levert een vermogen van maximaal {socket:tesla_destination:output}" - }, - "freeform": { - "key": "socket:tesla_destination:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:tesla_destination:output=11 kw", - "then": { - "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most 11 kw", - "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
levert een vermogen van maximaal 11 kw" - } - }, - { - "if": "socket:socket:tesla_destination:output=22 kw", - "then": { - "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most 22 kw", - "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
levert een vermogen van maximaal 22 kw" - } - } - ], - "condition": { - "and": [ - "socket:tesla_destination~*", - "socket:tesla_destination!=0" - ] - } - }, - { - "id": "plugs-13", - "question": { - "en": "How much plugs of type
USB to charge phones and small electronics
are available here?", - "nl": "Hoeveel stekkers van type
USB om GSMs en kleine electronica op te laden
heeft dit oplaadpunt?" - }, - "render": { - "en": "There are {socket:USB-A} plugs of type
USB to charge phones and small electronics
available here", - "nl": "Hier zijn {socket:USB-A} stekkers van het type
USB om GSMs en kleine electronica op te laden
" - }, - "freeform": { - "key": "socket:USB-A", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:USB-A~*", - "socket:USB-A!=0" - ] - } - }, - { - "id": "voltage-13", - "question": { - "en": "What voltage do the plugs with
USB to charge phones and small electronics
offer?", - "nl": "Welke spanning levert de stekker van type
USB om GSMs en kleine electronica op te laden
" - }, - "render": { - "en": "
USB to charge phones and small electronics
outputs {socket:USB-A:voltage} volt", - "nl": "
USB om GSMs en kleine electronica op te laden
heeft een spanning van {socket:USB-A:voltage} volt" - }, - "freeform": { - "key": "socket:USB-A:voltage", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:USB-A:voltage=5 V", - "then": { - "en": "
USB to charge phones and small electronics
outputs 5 volt", - "nl": "
USB om GSMs en kleine electronica op te laden
heeft een spanning van 5 volt" - } - } - ], - "condition": { - "and": [ - "socket:USB-A~*", - "socket:USB-A!=0" - ] - } - }, - { - "id": "current-13", - "question": { - "en": "What current do the plugs with
USB to charge phones and small electronics
offer?", - "nl": "Welke stroom levert de stekker van type
USB om GSMs en kleine electronica op te laden
?" - }, - "render": { - "en": "
USB to charge phones and small electronics
outputs at most {socket:USB-A:current}A", - "nl": "
USB om GSMs en kleine electronica op te laden
levert een stroom van maximaal {socket:USB-A:current}A" - }, - "freeform": { - "key": "socket:USB-A:current", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:USB-A:current=1 A", - "then": { - "en": "
USB to charge phones and small electronics
outputs at most 1 A", - "nl": "
USB om GSMs en kleine electronica op te laden
levert een stroom van maximaal 1 A" - } - }, - { - "if": "socket:socket:USB-A:current=2 A", - "then": { - "en": "
USB to charge phones and small electronics
outputs at most 2 A", - "nl": "
USB om GSMs en kleine electronica op te laden
levert een stroom van maximaal 2 A" - } - } - ], - "condition": { - "and": [ - "socket:USB-A~*", - "socket:USB-A!=0" - ] - } - }, - { - "id": "power-output-13", - "question": { - "en": "What power output does a single plug of type
USB to charge phones and small electronics
offer?", - "nl": "Welk vermogen levert een enkele stekker van type
USB om GSMs en kleine electronica op te laden
?" - }, - "render": { - "en": "
USB to charge phones and small electronics
outputs at most {socket:USB-A:output}", - "nl": "
USB om GSMs en kleine electronica op te laden
levert een vermogen van maximaal {socket:USB-A:output}" - }, - "freeform": { - "key": "socket:USB-A:output", - "type": "pfloat" - }, - "mappings": [ - { - "if": "socket:socket:USB-A:output=5w", - "then": { - "en": "
USB to charge phones and small electronics
outputs at most 5w", - "nl": "
USB om GSMs en kleine electronica op te laden
levert een vermogen van maximaal 5w" - } - }, - { - "if": "socket:socket:USB-A:output=10w", - "then": { - "en": "
USB to charge phones and small electronics
outputs at most 10w", - "nl": "
USB om GSMs en kleine electronica op te laden
levert een vermogen van maximaal 10w" - } - } - ], - "condition": { - "and": [ - "socket:USB-A~*", - "socket:USB-A!=0" - ] - } - }, - { - "id": "plugs-14", - "question": { - "en": "How much plugs of type
Bosch Active Connect with cable
are available here?", - "nl": "Hoeveel stekkers van type
Bosch Active Connect aan een kabel
heeft dit oplaadpunt?" - }, - "render": { - "en": "There are {socket:bosch_3pin} plugs of type
Bosch Active Connect with cable
available here", - "nl": "Hier zijn {socket:bosch_3pin} stekkers van het type
Bosch Active Connect aan een kabel
" - }, - "freeform": { - "key": "socket:bosch_3pin", - "type": "pnat" - }, - "condition": { - "and": [ - "socket:bosch_3pin~*", - "socket:bosch_3pin!=0" - ] - } - }, - { - "id": "voltage-14", - "question": { - "en": "What voltage do the plugs with
Bosch Active Connect with cable
offer?", - "nl": "Welke spanning levert de stekker van type
Bosch Active Connect aan een kabel
" - }, - "render": { - "en": "
Bosch Active Connect with cable
outputs {socket:bosch_3pin:voltage} volt", - "nl": "
Bosch Active Connect aan een kabel
heeft een spanning van {socket:bosch_3pin:voltage} volt" - }, - "freeform": { - "key": "socket:bosch_3pin:voltage", - "type": "pfloat" - }, - "mappings": [], - "condition": { - "and": [ - "socket:bosch_3pin~*", - "socket:bosch_3pin!=0" - ] - } - }, - { - "id": "current-14", - "question": { - "en": "What current do the plugs with
Bosch Active Connect with cable
offer?", - "nl": "Welke stroom levert de stekker van type
Bosch Active Connect aan een kabel
?" - }, - "render": { - "en": "
Bosch Active Connect with cable
outputs at most {socket:bosch_3pin:current}A", - "nl": "
Bosch Active Connect aan een kabel
levert een stroom van maximaal {socket:bosch_3pin:current}A" - }, - "freeform": { - "key": "socket:bosch_3pin:current", - "type": "pfloat" - }, - "mappings": [], - "condition": { - "and": [ - "socket:bosch_3pin~*", - "socket:bosch_3pin!=0" - ] - } - }, - { - "id": "power-output-14", - "question": { - "en": "What power output does a single plug of type
Bosch Active Connect with cable
offer?", - "nl": "Welk vermogen levert een enkele stekker van type
Bosch Active Connect aan een kabel
?" - }, - "render": { - "en": "
Bosch Active Connect with cable
outputs at most {socket:bosch_3pin:output}", - "nl": "
Bosch Active Connect aan een kabel
levert een vermogen van maximaal {socket:bosch_3pin:output}" - }, - "freeform": { - "key": "socket:bosch_3pin:output", - "type": "pfloat" - }, - "mappings": [], - "condition": { - "and": [ - "socket:bosch_3pin~*", - "socket:bosch_3pin!=0" - ] - } - }, - { - "id": "Authentication", - "question": { - "en": "What kind of authentication is available at the charging station?", - "it": "Quali sono gli orari di apertura di questa stazione di ricarica?", - "ja": "この充電ステーションはいつオープンしますか?", - "nb_NO": "Når åpnet denne ladestasjonen?", - "ru": "В какое время работает эта зарядная станция?", - "zh_Hant": "何時是充電站開放使用的時間?" - }, - "multiAnswer": true, - "mappings": [ - { - "if": "authentication:membership_card=yes", - "ifnot": "authentication:membership_card=no", - "then": { - "en": "Authentication by a membership card" - } - }, - { - "if": "authentication:app=yes", - "ifnot": "authentication:app=no", - "then": { - "en": "Authentication by an app" - } - }, - { - "if": "authentication:phone_call=yes", - "ifnot": "authentication:phone_call=no", - "then": { - "en": "Authentication via phone call is available" - } - }, - { - "if": "authentication:short_message=yes", - "ifnot": "authentication:short_message=no", - "then": { - "en": "Authentication via phone call is available" - } - }, - { - "if": "authentication:nfc=yes", - "ifnot": "authentication:nfc=no", - "then": { - "en": "Authentication via NFC is available" - } - }, - { - "if": "authentication:money_card=yes", - "ifnot": "authentication:money_card=no", - "then": { - "en": "Authentication via Money Card is available" - } - }, - { - "if": "authentication:debit_card=yes", - "ifnot": "authentication:debit_card=no", - "then": { - "en": "Authentication via debit card is available" - } - }, - { - "if": "authentication:none=yes", - "ifnot": "authentication:none=no", - "then": { - "en": "No authentication is needed" - } - } - ] - }, - { - "id": "Auth phone", - "render": { - "en": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}", - "it": "{network}", - "ja": "{network}", - "nb_NO": "{network}", - "ru": "{network}", - "zh_Hant": "{network}" - }, - "question": { - "en": "What's the phone number for authentication call or SMS?", - "it": "A quale rete appartiene questa stazione di ricarica?", - "ja": "この充電ステーションの運営チェーンはどこですか?", - "ru": "К какой сети относится эта станция?", - "zh_Hant": "充電站所屬的網路是?" - }, - "freeform": { - "key": "authentication:phone_call:number", - "type": "phone" - }, - "condition": { - "or": [ - "authentication:phone_call=yes", - "authentication:short_message=yes" - ] - }, - "it": { - "0": { - "then": "Non appartiene a una rete" - } - }, - "ja": { - "0": { - "then": "大規模な運営チェーンの一部ではない" - } - }, - "ru": { - "0": { - "then": "Не является частью более крупной сети" - } - }, - "zh_Hant": { - "0": { - "then": "不屬於大型網路" - } - } - }, - { - "id": "OH", - "render": "{opening_hours_table(opening_hours)}", - "freeform": { - "key": "opening_hours", - "type": "opening_hours" - }, - "question": { - "en": "When is this charging station opened?" - }, - "mappings": [ - { - "if": "opening_hours=24/7", - "then": { - "en": "24/7 opened (including holidays)" - } - } - ] - }, - { - "id": "fee/charge", - "question": { - "en": "How much does one have to pay to use this charging station?", - "nl": "Hoeveel kost het gebruik van dit oplaadpunt?" - }, - "freeform": { - "key": "charge", - "addExtraTags": [ - "fee=yes" - ] - }, - "render": { - "en": "Using this charging station costs {charge}", - "nl": "Dit oplaadpunt gebruiken kost {charge}" - }, - "mappings": [ - { - "if": { - "and": [ - "fee=no", - "charge=" - ] - }, - "then": { - "nl": "Gratis te gebruiken", - "en": "Free to use" - } - } - ] - }, - { - "id": "payment-options", - "builtin": "payment-options", - "override": { - "condition": { - "or": [ - "fee=yes", - "charge~*" - ] - }, - "mappings+": [ - { - "if": "payment:app=yes", - "ifnot": "payment:app=no", - "then": { - "en": "Payment is done using a dedicated app", - "nl": "Betalen via een app van het netwerk" + "id": "capacity", + "render": { + "en": "{capacity} vehicles can be charged here at the same time", + "nl": "{capacity} voertuigen kunnen hier op hetzelfde moment opgeladen worden" + }, + "question": { + "en": "How much vehicles can be charged here at the same time?", + "nl": "Hoeveel voertuigen kunnen hier opgeladen worden?" + }, + "freeform": { + "key": "capacity", + "type": "pnat" } - }, - { - "if": "payment:membership_card=yes", - "ifnot": "payment:membership_card=no", - "then": { - "en": "Payment is done using a membership card", - "nl": "Betalen via een lidkaart van het netwerk" + }, + { + "id": "Available_charging_stations (generated)", + "question": { + "en": "Which charging stations are available here?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "socket:schuko=1", + "ifnot": "socket:schuko=", + "then": { + "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
", + "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
" + }, + "hideInAnswer": { + "or": [ + "_country!=be", + "_country!=fr", + "_country!=ma", + "_country!=tn", + "_country!=pl", + "_country!=cs", + "_country!=sk", + "_country!=mo" + ] + } + }, + { + "if": { + "and": [ + "socket:schuko~*", + "socket:schuko!=1" + ] + }, + "then": { + "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
", + "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
" + }, + "hideInAnswer": true + }, + { + "if": "socket:typee=1", + "ifnot": "socket:typee=", + "then": { + "en": "
European wall plug with ground pin (CEE7/4 type E)
", + "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
" + } + }, + { + "if": { + "and": [ + "socket:typee~*", + "socket:typee!=1" + ] + }, + "then": { + "en": "
European wall plug with ground pin (CEE7/4 type E)
", + "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
" + }, + "hideInAnswer": true + }, + { + "if": "socket:chademo=1", + "ifnot": "socket:chademo=", + "then": { + "en": "
Chademo
", + "nl": "
Chademo
" + }, + "hideInAnswer": { + "or": [ + { + "and": [ + "car=no", + "motorcar=no", + "hgv=no", + "bus=no" + ] + }, + { + "and": [ + { + "or": [ + "bicycle=yes", + "scooter=yes" + ] + }, + "car!=yes", + "motorcar!=yes", + "hgv!=yes", + "bus!=yes" + ] + } + ] + } + }, + { + "if": { + "and": [ + "socket:chademo~*", + "socket:chademo!=1" + ] + }, + "then": { + "en": "
Chademo
", + "nl": "
Chademo
" + }, + "hideInAnswer": true + }, + { + "if": "socket:type1_cable=1", + "ifnot": "socket:type1_cable=", + "then": { + "en": "
Type 1 with cable (J1772)
", + "nl": "
Type 1 met kabel (J1772)
" + }, + "hideInAnswer": { + "or": [ + { + "and": [ + "car=no", + "motorcar=no", + "hgv=no", + "bus=no" + ] + }, + { + "and": [ + { + "or": [ + "bicycle=yes", + "scooter=yes" + ] + }, + "car!=yes", + "motorcar!=yes", + "hgv!=yes", + "bus!=yes" + ] + } + ] + } + }, + { + "if": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=1" + ] + }, + "then": { + "en": "
Type 1 with cable (J1772)
", + "nl": "
Type 1 met kabel (J1772)
" + }, + "hideInAnswer": true + }, + { + "if": "socket:type1=1", + "ifnot": "socket:type1=", + "then": { + "en": "
Type 1 without cable (J1772)
", + "nl": "
Type 1 zonder kabel (J1772)
" + }, + "hideInAnswer": { + "or": [ + { + "and": [ + "car=no", + "motorcar=no", + "hgv=no", + "bus=no" + ] + }, + { + "and": [ + { + "or": [ + "bicycle=yes", + "scooter=yes" + ] + }, + "car!=yes", + "motorcar!=yes", + "hgv!=yes", + "bus!=yes" + ] + } + ] + } + }, + { + "if": { + "and": [ + "socket:type1~*", + "socket:type1!=1" + ] + }, + "then": { + "en": "
Type 1 without cable (J1772)
", + "nl": "
Type 1 zonder kabel (J1772)
" + }, + "hideInAnswer": true + }, + { + "if": "socket:type1_combo=1", + "ifnot": "socket:type1_combo=", + "then": { + "en": "
Type 1 CCS (aka Type 1 Combo)
", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
" + }, + "hideInAnswer": { + "or": [ + { + "and": [ + "car=no", + "motorcar=no", + "hgv=no", + "bus=no" + ] + }, + { + "and": [ + { + "or": [ + "bicycle=yes", + "scooter=yes" + ] + }, + "car!=yes", + "motorcar!=yes", + "hgv!=yes", + "bus!=yes" + ] + } + ] + } + }, + { + "if": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=1" + ] + }, + "then": { + "en": "
Type 1 CCS (aka Type 1 Combo)
", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
" + }, + "hideInAnswer": true + }, + { + "if": "socket:tesla_supercharger=1", + "ifnot": "socket:tesla_supercharger=", + "then": { + "en": "
Tesla Supercharger
", + "nl": "
Tesla Supercharger
" + }, + "hideInAnswer": { + "or": [ + { + "and": [ + "car=no", + "motorcar=no", + "hgv=no", + "bus=no" + ] + }, + { + "and": [ + { + "or": [ + "bicycle=yes", + "scooter=yes" + ] + }, + "car!=yes", + "motorcar!=yes", + "hgv!=yes", + "bus!=yes" + ] + } + ] + } + }, + { + "if": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=1" + ] + }, + "then": { + "en": "
Tesla Supercharger
", + "nl": "
Tesla Supercharger
" + }, + "hideInAnswer": true + }, + { + "if": "socket:type2=1", + "ifnot": "socket:type2=", + "then": { + "en": "
Type 2 (mennekes)
", + "nl": "
Type 2 (mennekes)
" + }, + "hideInAnswer": { + "or": [ + { + "and": [ + "car=no", + "motorcar=no", + "hgv=no", + "bus=no" + ] + }, + { + "and": [ + { + "or": [ + "bicycle=yes", + "scooter=yes" + ] + }, + "car!=yes", + "motorcar!=yes", + "hgv!=yes", + "bus!=yes" + ] + } + ] + } + }, + { + "if": { + "and": [ + "socket:type2~*", + "socket:type2!=1" + ] + }, + "then": { + "en": "
Type 2 (mennekes)
", + "nl": "
Type 2 (mennekes)
" + }, + "hideInAnswer": true + }, + { + "if": "socket:type2_combo=1", + "ifnot": "socket:type2_combo=", + "then": { + "en": "
Type 2 CCS (mennekes)
", + "nl": "
Type 2 CCS (mennekes)
" + }, + "hideInAnswer": { + "or": [ + { + "and": [ + "car=no", + "motorcar=no", + "hgv=no", + "bus=no" + ] + }, + { + "and": [ + { + "or": [ + "bicycle=yes", + "scooter=yes" + ] + }, + "car!=yes", + "motorcar!=yes", + "hgv!=yes", + "bus!=yes" + ] + } + ] + } + }, + { + "if": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=1" + ] + }, + "then": { + "en": "
Type 2 CCS (mennekes)
", + "nl": "
Type 2 CCS (mennekes)
" + }, + "hideInAnswer": true + }, + { + "if": "socket:type2_cable=1", + "ifnot": "socket:type2_cable=", + "then": { + "en": "
Type 2 with cable (mennekes)
", + "nl": "
Type 2 met kabel (J1772)
" + }, + "hideInAnswer": { + "or": [ + { + "and": [ + "car=no", + "motorcar=no", + "hgv=no", + "bus=no" + ] + }, + { + "and": [ + { + "or": [ + "bicycle=yes", + "scooter=yes" + ] + }, + "car!=yes", + "motorcar!=yes", + "hgv!=yes", + "bus!=yes" + ] + } + ] + } + }, + { + "if": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=1" + ] + }, + "then": { + "en": "
Type 2 with cable (mennekes)
", + "nl": "
Type 2 met kabel (J1772)
" + }, + "hideInAnswer": true + }, + { + "if": "socket:tesla_supercharger_ccs=1", + "ifnot": "socket:tesla_supercharger_ccs=", + "then": { + "en": "
Tesla Supercharger CCS (a branded type2_css)
", + "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
" + }, + "hideInAnswer": { + "or": [ + { + "and": [ + "car=no", + "motorcar=no", + "hgv=no", + "bus=no" + ] + }, + { + "and": [ + { + "or": [ + "bicycle=yes", + "scooter=yes" + ] + }, + "car!=yes", + "motorcar!=yes", + "hgv!=yes", + "bus!=yes" + ] + } + ] + } + }, + { + "if": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=1" + ] + }, + "then": { + "en": "
Tesla Supercharger CCS (a branded type2_css)
", + "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
" + }, + "hideInAnswer": true + }, + { + "if": "socket:tesla_destination=1", + "ifnot": "socket:tesla_destination=", + "then": { + "en": "
Tesla Supercharger (destination)
", + "nl": "
Tesla Supercharger (destination)
" + }, + "hideInAnswer": { + "or": [ + { + "and": [ + "car=no", + "motorcar=no", + "hgv=no", + "bus=no" + ] + }, + { + "and": [ + { + "or": [ + "bicycle=yes", + "scooter=yes" + ] + }, + "car!=yes", + "motorcar!=yes", + "hgv!=yes", + "bus!=yes" + ] + }, + { + "or": [ + "_country!=us" + ] + } + ] + } + }, + { + "if": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=1" + ] + }, + "then": { + "en": "
Tesla Supercharger (destination)
", + "nl": "
Tesla Supercharger (destination)
" + }, + "hideInAnswer": true + }, + { + "if": "socket:tesla_destination=1", + "ifnot": "socket:tesla_destination=", + "then": { + "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
", + "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
" + }, + "hideInAnswer": { + "or": [ + { + "and": [ + "car=no", + "motorcar=no", + "hgv=no", + "bus=no" + ] + }, + { + "and": [ + { + "or": [ + "bicycle=yes", + "scooter=yes" + ] + }, + "car!=yes", + "motorcar!=yes", + "hgv!=yes", + "bus!=yes" + ] + }, + { + "or": [ + "_country=us" + ] + } + ] + } + }, + { + "if": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=1" + ] + }, + "then": { + "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
", + "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
" + }, + "hideInAnswer": true + }, + { + "if": "socket:USB-A=1", + "ifnot": "socket:USB-A=", + "then": { + "en": "
USB to charge phones and small electronics
", + "nl": "
USB om GSMs en kleine electronica op te laden
" + } + }, + { + "if": { + "and": [ + "socket:USB-A~*", + "socket:USB-A!=1" + ] + }, + "then": { + "en": "
USB to charge phones and small electronics
", + "nl": "
USB om GSMs en kleine electronica op te laden
" + }, + "hideInAnswer": true + }, + { + "if": "socket:bosch_3pin=1", + "ifnot": "socket:bosch_3pin=", + "then": { + "en": "
Bosch Active Connect with cable
", + "nl": "
Bosch Active Connect aan een kabel
" + }, + "hideInAnswer": { + "or": [ + { + "and": [ + "bicycle=no" + ] + }, + { + "and": [ + { + "or": [ + "car=yes", + "motorcar=yes", + "hgv=yes", + "bus=yes" + ] + }, + "bicycle!=yes" + ] + } + ] + } + }, + { + "if": { + "and": [ + "socket:bosch_3pin~*", + "socket:bosch_3pin!=1" + ] + }, + "then": { + "en": "
Bosch Active Connect with cable
", + "nl": "
Bosch Active Connect aan een kabel
" + }, + "hideInAnswer": true + } + ] + }, + { + "id": "plugs-0", + "question": { + "en": "How much plugs of type
Schuko wall plug without ground pin (CEE7/4 type F)
are available here?", + "nl": "Hoeveel stekkers van type
Schuko stekker zonder aardingspin (CEE7/4 type F)
heeft dit oplaadpunt?" + }, + "render": { + "en": "There are {socket:schuko} plugs of type
Schuko wall plug without ground pin (CEE7/4 type F)
available here", + "nl": "Hier zijn {socket:schuko} stekkers van het type
Schuko stekker zonder aardingspin (CEE7/4 type F)
" + }, + "freeform": { + "key": "socket:schuko", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "id": "voltage-0", + "question": { + "en": "What voltage do the plugs with
Schuko wall plug without ground pin (CEE7/4 type F)
offer?", + "nl": "Welke spanning levert de stekker van type
Schuko stekker zonder aardingspin (CEE7/4 type F)
" + }, + "render": { + "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
outputs {socket:schuko:voltage} volt", + "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
heeft een spanning van {socket:schuko:voltage} volt" + }, + "freeform": { + "key": "socket:schuko:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:schuko:voltage=230 V", + "then": { + "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
outputs 230 volt", + "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
heeft een spanning van 230 volt" + } + } + ], + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "id": "current-0", + "question": { + "en": "What current do the plugs with
Schuko wall plug without ground pin (CEE7/4 type F)
offer?", + "nl": "Welke stroom levert de stekker van type
Schuko stekker zonder aardingspin (CEE7/4 type F)
?" + }, + "render": { + "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
outputs at most {socket:schuko:current}A", + "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
levert een stroom van maximaal {socket:schuko:current}A" + }, + "freeform": { + "key": "socket:schuko:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:schuko:current=16 A", + "then": { + "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
outputs at most 16 A", + "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
levert een stroom van maximaal 16 A" + } + } + ], + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "id": "power-output-0", + "question": { + "en": "What power output does a single plug of type
Schuko wall plug without ground pin (CEE7/4 type F)
offer?", + "nl": "Welk vermogen levert een enkele stekker van type
Schuko stekker zonder aardingspin (CEE7/4 type F)
?" + }, + "render": { + "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
outputs at most {socket:schuko:output}", + "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
levert een vermogen van maximaal {socket:schuko:output}" + }, + "freeform": { + "key": "socket:schuko:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:schuko:output=3.6 kw", + "then": { + "en": "
Schuko wall plug without ground pin (CEE7/4 type F)
outputs at most 3.6 kw", + "nl": "
Schuko stekker zonder aardingspin (CEE7/4 type F)
levert een vermogen van maximaal 3.6 kw" + } + } + ], + "condition": { + "and": [ + "socket:schuko~*", + "socket:schuko!=0" + ] + } + }, + { + "id": "plugs-1", + "question": { + "en": "How much plugs of type
European wall plug with ground pin (CEE7/4 type E)
are available here?", + "nl": "Hoeveel stekkers van type
Europese stekker met aardingspin (CEE7/4 type E)
heeft dit oplaadpunt?" + }, + "render": { + "en": "There are {socket:typee} plugs of type
European wall plug with ground pin (CEE7/4 type E)
available here", + "nl": "Hier zijn {socket:typee} stekkers van het type
Europese stekker met aardingspin (CEE7/4 type E)
" + }, + "freeform": { + "key": "socket:typee", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "id": "voltage-1", + "question": { + "en": "What voltage do the plugs with
European wall plug with ground pin (CEE7/4 type E)
offer?", + "nl": "Welke spanning levert de stekker van type
Europese stekker met aardingspin (CEE7/4 type E)
" + }, + "render": { + "en": "
European wall plug with ground pin (CEE7/4 type E)
outputs {socket:typee:voltage} volt", + "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
heeft een spanning van {socket:typee:voltage} volt" + }, + "freeform": { + "key": "socket:typee:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:typee:voltage=230 V", + "then": { + "en": "
European wall plug with ground pin (CEE7/4 type E)
outputs 230 volt", + "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
heeft een spanning van 230 volt" + } + } + ], + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "id": "current-1", + "question": { + "en": "What current do the plugs with
European wall plug with ground pin (CEE7/4 type E)
offer?", + "nl": "Welke stroom levert de stekker van type
Europese stekker met aardingspin (CEE7/4 type E)
?" + }, + "render": { + "en": "
European wall plug with ground pin (CEE7/4 type E)
outputs at most {socket:typee:current}A", + "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
levert een stroom van maximaal {socket:typee:current}A" + }, + "freeform": { + "key": "socket:typee:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:typee:current=16 A", + "then": { + "en": "
European wall plug with ground pin (CEE7/4 type E)
outputs at most 16 A", + "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
levert een stroom van maximaal 16 A" + } + } + ], + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "id": "power-output-1", + "question": { + "en": "What power output does a single plug of type
European wall plug with ground pin (CEE7/4 type E)
offer?", + "nl": "Welk vermogen levert een enkele stekker van type
Europese stekker met aardingspin (CEE7/4 type E)
?" + }, + "render": { + "en": "
European wall plug with ground pin (CEE7/4 type E)
outputs at most {socket:typee:output}", + "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
levert een vermogen van maximaal {socket:typee:output}" + }, + "freeform": { + "key": "socket:typee:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:typee:output=3 kw", + "then": { + "en": "
European wall plug with ground pin (CEE7/4 type E)
outputs at most 3 kw", + "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
levert een vermogen van maximaal 3 kw" + } + }, + { + "if": "socket:socket:typee:output=22 kw", + "then": { + "en": "
European wall plug with ground pin (CEE7/4 type E)
outputs at most 22 kw", + "nl": "
Europese stekker met aardingspin (CEE7/4 type E)
levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:typee~*", + "socket:typee!=0" + ] + } + }, + { + "id": "plugs-2", + "question": { + "en": "How much plugs of type
Chademo
are available here?", + "nl": "Hoeveel stekkers van type
Chademo
heeft dit oplaadpunt?" + }, + "render": { + "en": "There are {socket:chademo} plugs of type
Chademo
available here", + "nl": "Hier zijn {socket:chademo} stekkers van het type
Chademo
" + }, + "freeform": { + "key": "socket:chademo", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "id": "voltage-2", + "question": { + "en": "What voltage do the plugs with
Chademo
offer?", + "nl": "Welke spanning levert de stekker van type
Chademo
" + }, + "render": { + "en": "
Chademo
outputs {socket:chademo:voltage} volt", + "nl": "
Chademo
heeft een spanning van {socket:chademo:voltage} volt" + }, + "freeform": { + "key": "socket:chademo:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:chademo:voltage=500 V", + "then": { + "en": "
Chademo
outputs 500 volt", + "nl": "
Chademo
heeft een spanning van 500 volt" + } + } + ], + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "id": "current-2", + "question": { + "en": "What current do the plugs with
Chademo
offer?", + "nl": "Welke stroom levert de stekker van type
Chademo
?" + }, + "render": { + "en": "
Chademo
outputs at most {socket:chademo:current}A", + "nl": "
Chademo
levert een stroom van maximaal {socket:chademo:current}A" + }, + "freeform": { + "key": "socket:chademo:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:chademo:current=120 A", + "then": { + "en": "
Chademo
outputs at most 120 A", + "nl": "
Chademo
levert een stroom van maximaal 120 A" + } + } + ], + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "id": "power-output-2", + "question": { + "en": "What power output does a single plug of type
Chademo
offer?", + "nl": "Welk vermogen levert een enkele stekker van type
Chademo
?" + }, + "render": { + "en": "
Chademo
outputs at most {socket:chademo:output}", + "nl": "
Chademo
levert een vermogen van maximaal {socket:chademo:output}" + }, + "freeform": { + "key": "socket:chademo:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:chademo:output=50 kw", + "then": { + "en": "
Chademo
outputs at most 50 kw", + "nl": "
Chademo
levert een vermogen van maximaal 50 kw" + } + } + ], + "condition": { + "and": [ + "socket:chademo~*", + "socket:chademo!=0" + ] + } + }, + { + "id": "plugs-3", + "question": { + "en": "How much plugs of type
Type 1 with cable (J1772)
are available here?", + "nl": "Hoeveel stekkers van type
Type 1 met kabel (J1772)
heeft dit oplaadpunt?" + }, + "render": { + "en": "There are {socket:type1_cable} plugs of type
Type 1 with cable (J1772)
available here", + "nl": "Hier zijn {socket:type1_cable} stekkers van het type
Type 1 met kabel (J1772)
" + }, + "freeform": { + "key": "socket:type1_cable", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "id": "voltage-3", + "question": { + "en": "What voltage do the plugs with
Type 1 with cable (J1772)
offer?", + "nl": "Welke spanning levert de stekker van type
Type 1 met kabel (J1772)
" + }, + "render": { + "en": "
Type 1 with cable (J1772)
outputs {socket:type1_cable:voltage} volt", + "nl": "
Type 1 met kabel (J1772)
heeft een spanning van {socket:type1_cable:voltage} volt" + }, + "freeform": { + "key": "socket:type1_cable:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_cable:voltage=200 V", + "then": { + "en": "
Type 1 with cable (J1772)
outputs 200 volt", + "nl": "
Type 1 met kabel (J1772)
heeft een spanning van 200 volt" + } + }, + { + "if": "socket:socket:type1_cable:voltage=240 V", + "then": { + "en": "
Type 1 with cable (J1772)
outputs 240 volt", + "nl": "
Type 1 met kabel (J1772)
heeft een spanning van 240 volt" + } + } + ], + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "id": "current-3", + "question": { + "en": "What current do the plugs with
Type 1 with cable (J1772)
offer?", + "nl": "Welke stroom levert de stekker van type
Type 1 met kabel (J1772)
?" + }, + "render": { + "en": "
Type 1 with cable (J1772)
outputs at most {socket:type1_cable:current}A", + "nl": "
Type 1 met kabel (J1772)
levert een stroom van maximaal {socket:type1_cable:current}A" + }, + "freeform": { + "key": "socket:type1_cable:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_cable:current=32 A", + "then": { + "en": "
Type 1 with cable (J1772)
outputs at most 32 A", + "nl": "
Type 1 met kabel (J1772)
levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "id": "power-output-3", + "question": { + "en": "What power output does a single plug of type
Type 1 with cable (J1772)
offer?", + "nl": "Welk vermogen levert een enkele stekker van type
Type 1 met kabel (J1772)
?" + }, + "render": { + "en": "
Type 1 with cable (J1772)
outputs at most {socket:type1_cable:output}", + "nl": "
Type 1 met kabel (J1772)
levert een vermogen van maximaal {socket:type1_cable:output}" + }, + "freeform": { + "key": "socket:type1_cable:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_cable:output=3.7 kw", + "then": { + "en": "
Type 1 with cable (J1772)
outputs at most 3.7 kw", + "nl": "
Type 1 met kabel (J1772)
levert een vermogen van maximaal 3.7 kw" + } + }, + { + "if": "socket:socket:type1_cable:output=7 kw", + "then": { + "en": "
Type 1 with cable (J1772)
outputs at most 7 kw", + "nl": "
Type 1 met kabel (J1772)
levert een vermogen van maximaal 7 kw" + } + } + ], + "condition": { + "and": [ + "socket:type1_cable~*", + "socket:type1_cable!=0" + ] + } + }, + { + "id": "plugs-4", + "question": { + "en": "How much plugs of type
Type 1 without cable (J1772)
are available here?", + "nl": "Hoeveel stekkers van type
Type 1 zonder kabel (J1772)
heeft dit oplaadpunt?" + }, + "render": { + "en": "There are {socket:type1} plugs of type
Type 1 without cable (J1772)
available here", + "nl": "Hier zijn {socket:type1} stekkers van het type
Type 1 zonder kabel (J1772)
" + }, + "freeform": { + "key": "socket:type1", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "id": "voltage-4", + "question": { + "en": "What voltage do the plugs with
Type 1 without cable (J1772)
offer?", + "nl": "Welke spanning levert de stekker van type
Type 1 zonder kabel (J1772)
" + }, + "render": { + "en": "
Type 1 without cable (J1772)
outputs {socket:type1:voltage} volt", + "nl": "
Type 1 zonder kabel (J1772)
heeft een spanning van {socket:type1:voltage} volt" + }, + "freeform": { + "key": "socket:type1:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1:voltage=200 V", + "then": { + "en": "
Type 1 without cable (J1772)
outputs 200 volt", + "nl": "
Type 1 zonder kabel (J1772)
heeft een spanning van 200 volt" + } + }, + { + "if": "socket:socket:type1:voltage=240 V", + "then": { + "en": "
Type 1 without cable (J1772)
outputs 240 volt", + "nl": "
Type 1 zonder kabel (J1772)
heeft een spanning van 240 volt" + } + } + ], + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "id": "current-4", + "question": { + "en": "What current do the plugs with
Type 1 without cable (J1772)
offer?", + "nl": "Welke stroom levert de stekker van type
Type 1 zonder kabel (J1772)
?" + }, + "render": { + "en": "
Type 1 without cable (J1772)
outputs at most {socket:type1:current}A", + "nl": "
Type 1 zonder kabel (J1772)
levert een stroom van maximaal {socket:type1:current}A" + }, + "freeform": { + "key": "socket:type1:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1:current=32 A", + "then": { + "en": "
Type 1 without cable (J1772)
outputs at most 32 A", + "nl": "
Type 1 zonder kabel (J1772)
levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "id": "power-output-4", + "question": { + "en": "What power output does a single plug of type
Type 1 without cable (J1772)
offer?", + "nl": "Welk vermogen levert een enkele stekker van type
Type 1 zonder kabel (J1772)
?" + }, + "render": { + "en": "
Type 1 without cable (J1772)
outputs at most {socket:type1:output}", + "nl": "
Type 1 zonder kabel (J1772)
levert een vermogen van maximaal {socket:type1:output}" + }, + "freeform": { + "key": "socket:type1:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1:output=3.7 kw", + "then": { + "en": "
Type 1 without cable (J1772)
outputs at most 3.7 kw", + "nl": "
Type 1 zonder kabel (J1772)
levert een vermogen van maximaal 3.7 kw" + } + }, + { + "if": "socket:socket:type1:output=6.6 kw", + "then": { + "en": "
Type 1 without cable (J1772)
outputs at most 6.6 kw", + "nl": "
Type 1 zonder kabel (J1772)
levert een vermogen van maximaal 6.6 kw" + } + }, + { + "if": "socket:socket:type1:output=7 kw", + "then": { + "en": "
Type 1 without cable (J1772)
outputs at most 7 kw", + "nl": "
Type 1 zonder kabel (J1772)
levert een vermogen van maximaal 7 kw" + } + }, + { + "if": "socket:socket:type1:output=7.2 kw", + "then": { + "en": "
Type 1 without cable (J1772)
outputs at most 7.2 kw", + "nl": "
Type 1 zonder kabel (J1772)
levert een vermogen van maximaal 7.2 kw" + } + } + ], + "condition": { + "and": [ + "socket:type1~*", + "socket:type1!=0" + ] + } + }, + { + "id": "plugs-5", + "question": { + "en": "How much plugs of type
Type 1 CCS (aka Type 1 Combo)
are available here?", + "nl": "Hoeveel stekkers van type
Type 1 CCS (ook gekend als Type 1 Combo)
heeft dit oplaadpunt?" + }, + "render": { + "en": "There are {socket:type1_combo} plugs of type
Type 1 CCS (aka Type 1 Combo)
available here", + "nl": "Hier zijn {socket:type1_combo} stekkers van het type
Type 1 CCS (ook gekend als Type 1 Combo)
" + }, + "freeform": { + "key": "socket:type1_combo", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "id": "voltage-5", + "question": { + "en": "What voltage do the plugs with
Type 1 CCS (aka Type 1 Combo)
offer?", + "nl": "Welke spanning levert de stekker van type
Type 1 CCS (ook gekend als Type 1 Combo)
" + }, + "render": { + "en": "
Type 1 CCS (aka Type 1 Combo)
outputs {socket:type1_combo:voltage} volt", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
heeft een spanning van {socket:type1_combo:voltage} volt" + }, + "freeform": { + "key": "socket:type1_combo:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_combo:voltage=400 V", + "then": { + "en": "
Type 1 CCS (aka Type 1 Combo)
outputs 400 volt", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
heeft een spanning van 400 volt" + } + }, + { + "if": "socket:socket:type1_combo:voltage=1000 V", + "then": { + "en": "
Type 1 CCS (aka Type 1 Combo)
outputs 1000 volt", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
heeft een spanning van 1000 volt" + } + } + ], + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "id": "current-5", + "question": { + "en": "What current do the plugs with
Type 1 CCS (aka Type 1 Combo)
offer?", + "nl": "Welke stroom levert de stekker van type
Type 1 CCS (ook gekend als Type 1 Combo)
?" + }, + "render": { + "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most {socket:type1_combo:current}A", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een stroom van maximaal {socket:type1_combo:current}A" + }, + "freeform": { + "key": "socket:type1_combo:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_combo:current=50 A", + "then": { + "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most 50 A", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een stroom van maximaal 50 A" + } + }, + { + "if": "socket:socket:type1_combo:current=125 A", + "then": { + "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most 125 A", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een stroom van maximaal 125 A" + } + } + ], + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "id": "power-output-5", + "question": { + "en": "What power output does a single plug of type
Type 1 CCS (aka Type 1 Combo)
offer?", + "nl": "Welk vermogen levert een enkele stekker van type
Type 1 CCS (ook gekend als Type 1 Combo)
?" + }, + "render": { + "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most {socket:type1_combo:output}", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een vermogen van maximaal {socket:type1_combo:output}" + }, + "freeform": { + "key": "socket:type1_combo:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type1_combo:output=50 kw", + "then": { + "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most 50 kw", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een vermogen van maximaal 50 kw" + } + }, + { + "if": "socket:socket:type1_combo:output=62.5 kw", + "then": { + "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most 62.5 kw", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een vermogen van maximaal 62.5 kw" + } + }, + { + "if": "socket:socket:type1_combo:output=150 kw", + "then": { + "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most 150 kw", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een vermogen van maximaal 150 kw" + } + }, + { + "if": "socket:socket:type1_combo:output=350 kw", + "then": { + "en": "
Type 1 CCS (aka Type 1 Combo)
outputs at most 350 kw", + "nl": "
Type 1 CCS (ook gekend als Type 1 Combo)
levert een vermogen van maximaal 350 kw" + } + } + ], + "condition": { + "and": [ + "socket:type1_combo~*", + "socket:type1_combo!=0" + ] + } + }, + { + "id": "plugs-6", + "question": { + "en": "How much plugs of type
Tesla Supercharger
are available here?", + "nl": "Hoeveel stekkers van type
Tesla Supercharger
heeft dit oplaadpunt?" + }, + "render": { + "en": "There are {socket:tesla_supercharger} plugs of type
Tesla Supercharger
available here", + "nl": "Hier zijn {socket:tesla_supercharger} stekkers van het type
Tesla Supercharger
" + }, + "freeform": { + "key": "socket:tesla_supercharger", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "id": "voltage-6", + "question": { + "en": "What voltage do the plugs with
Tesla Supercharger
offer?", + "nl": "Welke spanning levert de stekker van type
Tesla Supercharger
" + }, + "render": { + "en": "
Tesla Supercharger
outputs {socket:tesla_supercharger:voltage} volt", + "nl": "
Tesla Supercharger
heeft een spanning van {socket:tesla_supercharger:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_supercharger:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger:voltage=480 V", + "then": { + "en": "
Tesla Supercharger
outputs 480 volt", + "nl": "
Tesla Supercharger
heeft een spanning van 480 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "id": "current-6", + "question": { + "en": "What current do the plugs with
Tesla Supercharger
offer?", + "nl": "Welke stroom levert de stekker van type
Tesla Supercharger
?" + }, + "render": { + "en": "
Tesla Supercharger
outputs at most {socket:tesla_supercharger:current}A", + "nl": "
Tesla Supercharger
levert een stroom van maximaal {socket:tesla_supercharger:current}A" + }, + "freeform": { + "key": "socket:tesla_supercharger:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger:current=125 A", + "then": { + "en": "
Tesla Supercharger
outputs at most 125 A", + "nl": "
Tesla Supercharger
levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:tesla_supercharger:current=350 A", + "then": { + "en": "
Tesla Supercharger
outputs at most 350 A", + "nl": "
Tesla Supercharger
levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "id": "power-output-6", + "question": { + "en": "What power output does a single plug of type
Tesla Supercharger
offer?", + "nl": "Welk vermogen levert een enkele stekker van type
Tesla Supercharger
?" + }, + "render": { + "en": "
Tesla Supercharger
outputs at most {socket:tesla_supercharger:output}", + "nl": "
Tesla Supercharger
levert een vermogen van maximaal {socket:tesla_supercharger:output}" + }, + "freeform": { + "key": "socket:tesla_supercharger:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger:output=120 kw", + "then": { + "en": "
Tesla Supercharger
outputs at most 120 kw", + "nl": "
Tesla Supercharger
levert een vermogen van maximaal 120 kw" + } + }, + { + "if": "socket:socket:tesla_supercharger:output=150 kw", + "then": { + "en": "
Tesla Supercharger
outputs at most 150 kw", + "nl": "
Tesla Supercharger
levert een vermogen van maximaal 150 kw" + } + }, + { + "if": "socket:socket:tesla_supercharger:output=250 kw", + "then": { + "en": "
Tesla Supercharger
outputs at most 250 kw", + "nl": "
Tesla Supercharger
levert een vermogen van maximaal 250 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger~*", + "socket:tesla_supercharger!=0" + ] + } + }, + { + "id": "plugs-7", + "question": { + "en": "How much plugs of type
Type 2 (mennekes)
are available here?", + "nl": "Hoeveel stekkers van type
Type 2 (mennekes)
heeft dit oplaadpunt?" + }, + "render": { + "en": "There are {socket:type2} plugs of type
Type 2 (mennekes)
available here", + "nl": "Hier zijn {socket:type2} stekkers van het type
Type 2 (mennekes)
" + }, + "freeform": { + "key": "socket:type2", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "id": "voltage-7", + "question": { + "en": "What voltage do the plugs with
Type 2 (mennekes)
offer?", + "nl": "Welke spanning levert de stekker van type
Type 2 (mennekes)
" + }, + "render": { + "en": "
Type 2 (mennekes)
outputs {socket:type2:voltage} volt", + "nl": "
Type 2 (mennekes)
heeft een spanning van {socket:type2:voltage} volt" + }, + "freeform": { + "key": "socket:type2:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2:voltage=230 V", + "then": { + "en": "
Type 2 (mennekes)
outputs 230 volt", + "nl": "
Type 2 (mennekes)
heeft een spanning van 230 volt" + } + }, + { + "if": "socket:socket:type2:voltage=400 V", + "then": { + "en": "
Type 2 (mennekes)
outputs 400 volt", + "nl": "
Type 2 (mennekes)
heeft een spanning van 400 volt" + } + } + ], + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "id": "current-7", + "question": { + "en": "What current do the plugs with
Type 2 (mennekes)
offer?", + "nl": "Welke stroom levert de stekker van type
Type 2 (mennekes)
?" + }, + "render": { + "en": "
Type 2 (mennekes)
outputs at most {socket:type2:current}A", + "nl": "
Type 2 (mennekes)
levert een stroom van maximaal {socket:type2:current}A" + }, + "freeform": { + "key": "socket:type2:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2:current=16 A", + "then": { + "en": "
Type 2 (mennekes)
outputs at most 16 A", + "nl": "
Type 2 (mennekes)
levert een stroom van maximaal 16 A" + } + }, + { + "if": "socket:socket:type2:current=32 A", + "then": { + "en": "
Type 2 (mennekes)
outputs at most 32 A", + "nl": "
Type 2 (mennekes)
levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "id": "power-output-7", + "question": { + "en": "What power output does a single plug of type
Type 2 (mennekes)
offer?", + "nl": "Welk vermogen levert een enkele stekker van type
Type 2 (mennekes)
?" + }, + "render": { + "en": "
Type 2 (mennekes)
outputs at most {socket:type2:output}", + "nl": "
Type 2 (mennekes)
levert een vermogen van maximaal {socket:type2:output}" + }, + "freeform": { + "key": "socket:type2:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2:output=11 kw", + "then": { + "en": "
Type 2 (mennekes)
outputs at most 11 kw", + "nl": "
Type 2 (mennekes)
levert een vermogen van maximaal 11 kw" + } + }, + { + "if": "socket:socket:type2:output=22 kw", + "then": { + "en": "
Type 2 (mennekes)
outputs at most 22 kw", + "nl": "
Type 2 (mennekes)
levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:type2~*", + "socket:type2!=0" + ] + } + }, + { + "id": "plugs-8", + "question": { + "en": "How much plugs of type
Type 2 CCS (mennekes)
are available here?", + "nl": "Hoeveel stekkers van type
Type 2 CCS (mennekes)
heeft dit oplaadpunt?" + }, + "render": { + "en": "There are {socket:type2_combo} plugs of type
Type 2 CCS (mennekes)
available here", + "nl": "Hier zijn {socket:type2_combo} stekkers van het type
Type 2 CCS (mennekes)
" + }, + "freeform": { + "key": "socket:type2_combo", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "id": "voltage-8", + "question": { + "en": "What voltage do the plugs with
Type 2 CCS (mennekes)
offer?", + "nl": "Welke spanning levert de stekker van type
Type 2 CCS (mennekes)
" + }, + "render": { + "en": "
Type 2 CCS (mennekes)
outputs {socket:type2_combo:voltage} volt", + "nl": "
Type 2 CCS (mennekes)
heeft een spanning van {socket:type2_combo:voltage} volt" + }, + "freeform": { + "key": "socket:type2_combo:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_combo:voltage=500 V", + "then": { + "en": "
Type 2 CCS (mennekes)
outputs 500 volt", + "nl": "
Type 2 CCS (mennekes)
heeft een spanning van 500 volt" + } + }, + { + "if": "socket:socket:type2_combo:voltage=920 V", + "then": { + "en": "
Type 2 CCS (mennekes)
outputs 920 volt", + "nl": "
Type 2 CCS (mennekes)
heeft een spanning van 920 volt" + } + } + ], + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "id": "current-8", + "question": { + "en": "What current do the plugs with
Type 2 CCS (mennekes)
offer?", + "nl": "Welke stroom levert de stekker van type
Type 2 CCS (mennekes)
?" + }, + "render": { + "en": "
Type 2 CCS (mennekes)
outputs at most {socket:type2_combo:current}A", + "nl": "
Type 2 CCS (mennekes)
levert een stroom van maximaal {socket:type2_combo:current}A" + }, + "freeform": { + "key": "socket:type2_combo:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_combo:current=125 A", + "then": { + "en": "
Type 2 CCS (mennekes)
outputs at most 125 A", + "nl": "
Type 2 CCS (mennekes)
levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:type2_combo:current=350 A", + "then": { + "en": "
Type 2 CCS (mennekes)
outputs at most 350 A", + "nl": "
Type 2 CCS (mennekes)
levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "id": "power-output-8", + "question": { + "en": "What power output does a single plug of type
Type 2 CCS (mennekes)
offer?", + "nl": "Welk vermogen levert een enkele stekker van type
Type 2 CCS (mennekes)
?" + }, + "render": { + "en": "
Type 2 CCS (mennekes)
outputs at most {socket:type2_combo:output}", + "nl": "
Type 2 CCS (mennekes)
levert een vermogen van maximaal {socket:type2_combo:output}" + }, + "freeform": { + "key": "socket:type2_combo:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_combo:output=50 kw", + "then": { + "en": "
Type 2 CCS (mennekes)
outputs at most 50 kw", + "nl": "
Type 2 CCS (mennekes)
levert een vermogen van maximaal 50 kw" + } + } + ], + "condition": { + "and": [ + "socket:type2_combo~*", + "socket:type2_combo!=0" + ] + } + }, + { + "id": "plugs-9", + "question": { + "en": "How much plugs of type
Type 2 with cable (mennekes)
are available here?", + "nl": "Hoeveel stekkers van type
Type 2 met kabel (J1772)
heeft dit oplaadpunt?" + }, + "render": { + "en": "There are {socket:type2_cable} plugs of type
Type 2 with cable (mennekes)
available here", + "nl": "Hier zijn {socket:type2_cable} stekkers van het type
Type 2 met kabel (J1772)
" + }, + "freeform": { + "key": "socket:type2_cable", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "id": "voltage-9", + "question": { + "en": "What voltage do the plugs with
Type 2 with cable (mennekes)
offer?", + "nl": "Welke spanning levert de stekker van type
Type 2 met kabel (J1772)
" + }, + "render": { + "en": "
Type 2 with cable (mennekes)
outputs {socket:type2_cable:voltage} volt", + "nl": "
Type 2 met kabel (J1772)
heeft een spanning van {socket:type2_cable:voltage} volt" + }, + "freeform": { + "key": "socket:type2_cable:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_cable:voltage=230 V", + "then": { + "en": "
Type 2 with cable (mennekes)
outputs 230 volt", + "nl": "
Type 2 met kabel (J1772)
heeft een spanning van 230 volt" + } + }, + { + "if": "socket:socket:type2_cable:voltage=400 V", + "then": { + "en": "
Type 2 with cable (mennekes)
outputs 400 volt", + "nl": "
Type 2 met kabel (J1772)
heeft een spanning van 400 volt" + } + } + ], + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "id": "current-9", + "question": { + "en": "What current do the plugs with
Type 2 with cable (mennekes)
offer?", + "nl": "Welke stroom levert de stekker van type
Type 2 met kabel (J1772)
?" + }, + "render": { + "en": "
Type 2 with cable (mennekes)
outputs at most {socket:type2_cable:current}A", + "nl": "
Type 2 met kabel (J1772)
levert een stroom van maximaal {socket:type2_cable:current}A" + }, + "freeform": { + "key": "socket:type2_cable:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_cable:current=16 A", + "then": { + "en": "
Type 2 with cable (mennekes)
outputs at most 16 A", + "nl": "
Type 2 met kabel (J1772)
levert een stroom van maximaal 16 A" + } + }, + { + "if": "socket:socket:type2_cable:current=32 A", + "then": { + "en": "
Type 2 with cable (mennekes)
outputs at most 32 A", + "nl": "
Type 2 met kabel (J1772)
levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "id": "power-output-9", + "question": { + "en": "What power output does a single plug of type
Type 2 with cable (mennekes)
offer?", + "nl": "Welk vermogen levert een enkele stekker van type
Type 2 met kabel (J1772)
?" + }, + "render": { + "en": "
Type 2 with cable (mennekes)
outputs at most {socket:type2_cable:output}", + "nl": "
Type 2 met kabel (J1772)
levert een vermogen van maximaal {socket:type2_cable:output}" + }, + "freeform": { + "key": "socket:type2_cable:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:type2_cable:output=11 kw", + "then": { + "en": "
Type 2 with cable (mennekes)
outputs at most 11 kw", + "nl": "
Type 2 met kabel (J1772)
levert een vermogen van maximaal 11 kw" + } + }, + { + "if": "socket:socket:type2_cable:output=22 kw", + "then": { + "en": "
Type 2 with cable (mennekes)
outputs at most 22 kw", + "nl": "
Type 2 met kabel (J1772)
levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:type2_cable~*", + "socket:type2_cable!=0" + ] + } + }, + { + "id": "plugs-10", + "question": { + "en": "How much plugs of type
Tesla Supercharger CCS (a branded type2_css)
are available here?", + "nl": "Hoeveel stekkers van type
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
heeft dit oplaadpunt?" + }, + "render": { + "en": "There are {socket:tesla_supercharger_ccs} plugs of type
Tesla Supercharger CCS (a branded type2_css)
available here", + "nl": "Hier zijn {socket:tesla_supercharger_ccs} stekkers van het type
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
" + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "id": "voltage-10", + "question": { + "en": "What voltage do the plugs with
Tesla Supercharger CCS (a branded type2_css)
offer?", + "nl": "Welke spanning levert de stekker van type
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
" + }, + "render": { + "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs {socket:tesla_supercharger_ccs:voltage} volt", + "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
heeft een spanning van {socket:tesla_supercharger_ccs:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger_ccs:voltage=500 V", + "then": { + "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs 500 volt", + "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
heeft een spanning van 500 volt" + } + }, + { + "if": "socket:socket:tesla_supercharger_ccs:voltage=920 V", + "then": { + "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs 920 volt", + "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
heeft een spanning van 920 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "id": "current-10", + "question": { + "en": "What current do the plugs with
Tesla Supercharger CCS (a branded type2_css)
offer?", + "nl": "Welke stroom levert de stekker van type
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
?" + }, + "render": { + "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs at most {socket:tesla_supercharger_ccs:current}A", + "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
levert een stroom van maximaal {socket:tesla_supercharger_ccs:current}A" + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger_ccs:current=125 A", + "then": { + "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs at most 125 A", + "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:tesla_supercharger_ccs:current=350 A", + "then": { + "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs at most 350 A", + "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "id": "power-output-10", + "question": { + "en": "What power output does a single plug of type
Tesla Supercharger CCS (a branded type2_css)
offer?", + "nl": "Welk vermogen levert een enkele stekker van type
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
?" + }, + "render": { + "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs at most {socket:tesla_supercharger_ccs:output}", + "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
levert een vermogen van maximaal {socket:tesla_supercharger_ccs:output}" + }, + "freeform": { + "key": "socket:tesla_supercharger_ccs:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_supercharger_ccs:output=50 kw", + "then": { + "en": "
Tesla Supercharger CCS (a branded type2_css)
outputs at most 50 kw", + "nl": "
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
levert een vermogen van maximaal 50 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_supercharger_ccs~*", + "socket:tesla_supercharger_ccs!=0" + ] + } + }, + { + "id": "plugs-11", + "question": { + "en": "How much plugs of type
Tesla Supercharger (destination)
are available here?", + "nl": "Hoeveel stekkers van type
Tesla Supercharger (destination)
heeft dit oplaadpunt?" + }, + "render": { + "en": "There are {socket:tesla_destination} plugs of type
Tesla Supercharger (destination)
available here", + "nl": "Hier zijn {socket:tesla_destination} stekkers van het type
Tesla Supercharger (destination)
" + }, + "freeform": { + "key": "socket:tesla_destination", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "voltage-11", + "question": { + "en": "What voltage do the plugs with
Tesla Supercharger (destination)
offer?", + "nl": "Welke spanning levert de stekker van type
Tesla Supercharger (destination)
" + }, + "render": { + "en": "
Tesla Supercharger (destination)
outputs {socket:tesla_destination:voltage} volt", + "nl": "
Tesla Supercharger (destination)
heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_destination:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:voltage=480 V", + "then": { + "en": "
Tesla Supercharger (destination)
outputs 480 volt", + "nl": "
Tesla Supercharger (destination)
heeft een spanning van 480 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "current-11", + "question": { + "en": "What current do the plugs with
Tesla Supercharger (destination)
offer?", + "nl": "Welke stroom levert de stekker van type
Tesla Supercharger (destination)
?" + }, + "render": { + "en": "
Tesla Supercharger (destination)
outputs at most {socket:tesla_destination:current}A", + "nl": "
Tesla Supercharger (destination)
levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "freeform": { + "key": "socket:tesla_destination:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:current=125 A", + "then": { + "en": "
Tesla Supercharger (destination)
outputs at most 125 A", + "nl": "
Tesla Supercharger (destination)
levert een stroom van maximaal 125 A" + } + }, + { + "if": "socket:socket:tesla_destination:current=350 A", + "then": { + "en": "
Tesla Supercharger (destination)
outputs at most 350 A", + "nl": "
Tesla Supercharger (destination)
levert een stroom van maximaal 350 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "power-output-11", + "question": { + "en": "What power output does a single plug of type
Tesla Supercharger (destination)
offer?", + "nl": "Welk vermogen levert een enkele stekker van type
Tesla Supercharger (destination)
?" + }, + "render": { + "en": "
Tesla Supercharger (destination)
outputs at most {socket:tesla_destination:output}", + "nl": "
Tesla Supercharger (destination)
levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "freeform": { + "key": "socket:tesla_destination:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:output=120 kw", + "then": { + "en": "
Tesla Supercharger (destination)
outputs at most 120 kw", + "nl": "
Tesla Supercharger (destination)
levert een vermogen van maximaal 120 kw" + } + }, + { + "if": "socket:socket:tesla_destination:output=150 kw", + "then": { + "en": "
Tesla Supercharger (destination)
outputs at most 150 kw", + "nl": "
Tesla Supercharger (destination)
levert een vermogen van maximaal 150 kw" + } + }, + { + "if": "socket:socket:tesla_destination:output=250 kw", + "then": { + "en": "
Tesla Supercharger (destination)
outputs at most 250 kw", + "nl": "
Tesla Supercharger (destination)
levert een vermogen van maximaal 250 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "plugs-12", + "question": { + "en": "How much plugs of type
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
are available here?", + "nl": "Hoeveel stekkers van type
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
heeft dit oplaadpunt?" + }, + "render": { + "en": "There are {socket:tesla_destination} plugs of type
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
available here", + "nl": "Hier zijn {socket:tesla_destination} stekkers van het type
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
" + }, + "freeform": { + "key": "socket:tesla_destination", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "voltage-12", + "question": { + "en": "What voltage do the plugs with
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
offer?", + "nl": "Welke spanning levert de stekker van type
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
" + }, + "render": { + "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs {socket:tesla_destination:voltage} volt", + "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
heeft een spanning van {socket:tesla_destination:voltage} volt" + }, + "freeform": { + "key": "socket:tesla_destination:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:voltage=230 V", + "then": { + "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs 230 volt", + "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
heeft een spanning van 230 volt" + } + }, + { + "if": "socket:socket:tesla_destination:voltage=400 V", + "then": { + "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs 400 volt", + "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
heeft een spanning van 400 volt" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "current-12", + "question": { + "en": "What current do the plugs with
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
offer?", + "nl": "Welke stroom levert de stekker van type
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
?" + }, + "render": { + "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most {socket:tesla_destination:current}A", + "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
levert een stroom van maximaal {socket:tesla_destination:current}A" + }, + "freeform": { + "key": "socket:tesla_destination:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:current=16 A", + "then": { + "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most 16 A", + "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
levert een stroom van maximaal 16 A" + } + }, + { + "if": "socket:socket:tesla_destination:current=32 A", + "then": { + "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most 32 A", + "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
levert een stroom van maximaal 32 A" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "power-output-12", + "question": { + "en": "What power output does a single plug of type
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
offer?", + "nl": "Welk vermogen levert een enkele stekker van type
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
?" + }, + "render": { + "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most {socket:tesla_destination:output}", + "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
levert een vermogen van maximaal {socket:tesla_destination:output}" + }, + "freeform": { + "key": "socket:tesla_destination:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:tesla_destination:output=11 kw", + "then": { + "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most 11 kw", + "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
levert een vermogen van maximaal 11 kw" + } + }, + { + "if": "socket:socket:tesla_destination:output=22 kw", + "then": { + "en": "
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most 22 kw", + "nl": "
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
levert een vermogen van maximaal 22 kw" + } + } + ], + "condition": { + "and": [ + "socket:tesla_destination~*", + "socket:tesla_destination!=0" + ] + } + }, + { + "id": "plugs-13", + "question": { + "en": "How much plugs of type
USB to charge phones and small electronics
are available here?", + "nl": "Hoeveel stekkers van type
USB om GSMs en kleine electronica op te laden
heeft dit oplaadpunt?" + }, + "render": { + "en": "There are {socket:USB-A} plugs of type
USB to charge phones and small electronics
available here", + "nl": "Hier zijn {socket:USB-A} stekkers van het type
USB om GSMs en kleine electronica op te laden
" + }, + "freeform": { + "key": "socket:USB-A", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:USB-A~*", + "socket:USB-A!=0" + ] + } + }, + { + "id": "voltage-13", + "question": { + "en": "What voltage do the plugs with
USB to charge phones and small electronics
offer?", + "nl": "Welke spanning levert de stekker van type
USB om GSMs en kleine electronica op te laden
" + }, + "render": { + "en": "
USB to charge phones and small electronics
outputs {socket:USB-A:voltage} volt", + "nl": "
USB om GSMs en kleine electronica op te laden
heeft een spanning van {socket:USB-A:voltage} volt" + }, + "freeform": { + "key": "socket:USB-A:voltage", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:USB-A:voltage=5 V", + "then": { + "en": "
USB to charge phones and small electronics
outputs 5 volt", + "nl": "
USB om GSMs en kleine electronica op te laden
heeft een spanning van 5 volt" + } + } + ], + "condition": { + "and": [ + "socket:USB-A~*", + "socket:USB-A!=0" + ] + } + }, + { + "id": "current-13", + "question": { + "en": "What current do the plugs with
USB to charge phones and small electronics
offer?", + "nl": "Welke stroom levert de stekker van type
USB om GSMs en kleine electronica op te laden
?" + }, + "render": { + "en": "
USB to charge phones and small electronics
outputs at most {socket:USB-A:current}A", + "nl": "
USB om GSMs en kleine electronica op te laden
levert een stroom van maximaal {socket:USB-A:current}A" + }, + "freeform": { + "key": "socket:USB-A:current", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:USB-A:current=1 A", + "then": { + "en": "
USB to charge phones and small electronics
outputs at most 1 A", + "nl": "
USB om GSMs en kleine electronica op te laden
levert een stroom van maximaal 1 A" + } + }, + { + "if": "socket:socket:USB-A:current=2 A", + "then": { + "en": "
USB to charge phones and small electronics
outputs at most 2 A", + "nl": "
USB om GSMs en kleine electronica op te laden
levert een stroom van maximaal 2 A" + } + } + ], + "condition": { + "and": [ + "socket:USB-A~*", + "socket:USB-A!=0" + ] + } + }, + { + "id": "power-output-13", + "question": { + "en": "What power output does a single plug of type
USB to charge phones and small electronics
offer?", + "nl": "Welk vermogen levert een enkele stekker van type
USB om GSMs en kleine electronica op te laden
?" + }, + "render": { + "en": "
USB to charge phones and small electronics
outputs at most {socket:USB-A:output}", + "nl": "
USB om GSMs en kleine electronica op te laden
levert een vermogen van maximaal {socket:USB-A:output}" + }, + "freeform": { + "key": "socket:USB-A:output", + "type": "pfloat" + }, + "mappings": [ + { + "if": "socket:socket:USB-A:output=5w", + "then": { + "en": "
USB to charge phones and small electronics
outputs at most 5w", + "nl": "
USB om GSMs en kleine electronica op te laden
levert een vermogen van maximaal 5w" + } + }, + { + "if": "socket:socket:USB-A:output=10w", + "then": { + "en": "
USB to charge phones and small electronics
outputs at most 10w", + "nl": "
USB om GSMs en kleine electronica op te laden
levert een vermogen van maximaal 10w" + } + } + ], + "condition": { + "and": [ + "socket:USB-A~*", + "socket:USB-A!=0" + ] + } + }, + { + "id": "plugs-14", + "question": { + "en": "How much plugs of type
Bosch Active Connect with cable
are available here?", + "nl": "Hoeveel stekkers van type
Bosch Active Connect aan een kabel
heeft dit oplaadpunt?" + }, + "render": { + "en": "There are {socket:bosch_3pin} plugs of type
Bosch Active Connect with cable
available here", + "nl": "Hier zijn {socket:bosch_3pin} stekkers van het type
Bosch Active Connect aan een kabel
" + }, + "freeform": { + "key": "socket:bosch_3pin", + "type": "pnat" + }, + "condition": { + "and": [ + "socket:bosch_3pin~*", + "socket:bosch_3pin!=0" + ] + } + }, + { + "id": "voltage-14", + "question": { + "en": "What voltage do the plugs with
Bosch Active Connect with cable
offer?", + "nl": "Welke spanning levert de stekker van type
Bosch Active Connect aan een kabel
" + }, + "render": { + "en": "
Bosch Active Connect with cable
outputs {socket:bosch_3pin:voltage} volt", + "nl": "
Bosch Active Connect aan een kabel
heeft een spanning van {socket:bosch_3pin:voltage} volt" + }, + "freeform": { + "key": "socket:bosch_3pin:voltage", + "type": "pfloat" + }, + "mappings": [], + "condition": { + "and": [ + "socket:bosch_3pin~*", + "socket:bosch_3pin!=0" + ] + } + }, + { + "id": "current-14", + "question": { + "en": "What current do the plugs with
Bosch Active Connect with cable
offer?", + "nl": "Welke stroom levert de stekker van type
Bosch Active Connect aan een kabel
?" + }, + "render": { + "en": "
Bosch Active Connect with cable
outputs at most {socket:bosch_3pin:current}A", + "nl": "
Bosch Active Connect aan een kabel
levert een stroom van maximaal {socket:bosch_3pin:current}A" + }, + "freeform": { + "key": "socket:bosch_3pin:current", + "type": "pfloat" + }, + "mappings": [], + "condition": { + "and": [ + "socket:bosch_3pin~*", + "socket:bosch_3pin!=0" + ] + } + }, + { + "id": "power-output-14", + "question": { + "en": "What power output does a single plug of type
Bosch Active Connect with cable
offer?", + "nl": "Welk vermogen levert een enkele stekker van type
Bosch Active Connect aan een kabel
?" + }, + "render": { + "en": "
Bosch Active Connect with cable
outputs at most {socket:bosch_3pin:output}", + "nl": "
Bosch Active Connect aan een kabel
levert een vermogen van maximaal {socket:bosch_3pin:output}" + }, + "freeform": { + "key": "socket:bosch_3pin:output", + "type": "pfloat" + }, + "mappings": [], + "condition": { + "and": [ + "socket:bosch_3pin~*", + "socket:bosch_3pin!=0" + ] + } + }, + { + "id": "Authentication", + "question": { + "en": "What kind of authentication is available at the charging station?", + "it": "Quali sono gli orari di apertura di questa stazione di ricarica?", + "ja": "この充電ステーションはいつオープンしますか?", + "nb_NO": "Når åpnet denne ladestasjonen?", + "ru": "В какое время работает эта зарядная станция?", + "zh_Hant": "何時是充電站開放使用的時間?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "authentication:membership_card=yes", + "ifnot": "authentication:membership_card=no", + "then": { + "en": "Authentication by a membership card" + } + }, + { + "if": "authentication:app=yes", + "ifnot": "authentication:app=no", + "then": { + "en": "Authentication by an app" + } + }, + { + "if": "authentication:phone_call=yes", + "ifnot": "authentication:phone_call=no", + "then": { + "en": "Authentication via phone call is available" + } + }, + { + "if": "authentication:short_message=yes", + "ifnot": "authentication:short_message=no", + "then": { + "en": "Authentication via phone call is available" + } + }, + { + "if": "authentication:nfc=yes", + "ifnot": "authentication:nfc=no", + "then": { + "en": "Authentication via NFC is available" + } + }, + { + "if": "authentication:money_card=yes", + "ifnot": "authentication:money_card=no", + "then": { + "en": "Authentication via Money Card is available" + } + }, + { + "if": "authentication:debit_card=yes", + "ifnot": "authentication:debit_card=no", + "then": { + "en": "Authentication via debit card is available" + } + }, + { + "if": "authentication:none=yes", + "ifnot": "authentication:none=no", + "then": { + "en": "No authentication is needed" + } + } + ] + }, + { + "id": "Auth phone", + "render": { + "en": "Authenticate by calling or SMS'ing to {authentication:phone_call:number}", + "it": "{network}", + "ja": "{network}", + "nb_NO": "{network}", + "ru": "{network}", + "zh_Hant": "{network}" + }, + "question": { + "en": "What's the phone number for authentication call or SMS?", + "it": "A quale rete appartiene questa stazione di ricarica?", + "ja": "この充電ステーションの運営チェーンはどこですか?", + "ru": "К какой сети относится эта станция?", + "zh_Hant": "充電站所屬的網路是?" + }, + "freeform": { + "key": "authentication:phone_call:number", + "type": "phone" + }, + "condition": { + "or": [ + "authentication:phone_call=yes", + "authentication:short_message=yes" + ] + }, + "it": { + "0": { + "then": "Non appartiene a una rete" + } + }, + "ja": { + "0": { + "then": "大規模な運営チェーンの一部ではない" + } + }, + "ru": { + "0": { + "then": "Не является частью более крупной сети" + } + }, + "zh_Hant": { + "0": { + "then": "不屬於大型網路" + } + } + }, + { + "id": "OH", + "render": "{opening_hours_table(opening_hours)}", + "freeform": { + "key": "opening_hours", + "type": "opening_hours" + }, + "question": { + "en": "When is this charging station opened?" + }, + "mappings": [ + { + "if": "opening_hours=24/7", + "then": { + "en": "24/7 opened (including holidays)" + } + } + ] + }, + { + "id": "fee/charge", + "question": { + "en": "How much does one have to pay to use this charging station?", + "nl": "Hoeveel kost het gebruik van dit oplaadpunt?" + }, + "freeform": { + "key": "charge", + "addExtraTags": [ + "fee=yes" + ] + }, + "render": { + "en": "Using this charging station costs {charge}", + "nl": "Dit oplaadpunt gebruiken kost {charge}" + }, + "mappings": [ + { + "if": { + "and": [ + "fee=no", + "charge=" + ] + }, + "then": { + "nl": "Gratis te gebruiken", + "en": "Free to use" + } + } + ] + }, + { + "id": "payment-options", + "builtin": "payment-options", + "override": { + "condition": { + "or": [ + "fee=yes", + "charge~*" + ] + }, + "mappings+": [ + { + "if": "payment:app=yes", + "ifnot": "payment:app=no", + "then": { + "en": "Payment is done using a dedicated app", + "nl": "Betalen via een app van het netwerk" + } + }, + { + "if": "payment:membership_card=yes", + "ifnot": "payment:membership_card=no", + "then": { + "en": "Payment is done using a membership card", + "nl": "Betalen via een lidkaart van het netwerk" + } + } + ] + } + }, + { + "id": "maxstay", + "question": { + "en": "What is the maximum amount of time one is allowed to stay here?", + "nl": "Hoelang mag een voertuig hier blijven staan?" + }, + "freeform": { + "key": "maxstay" + }, + "render": { + "en": "One can stay at most {canonical(maxstay)}", + "nl": "De maximale parkeertijd hier is {canonical(maxstay)}" + }, + "mappings": [ + { + "if": "maxstay=unlimited", + "then": { + "en": "No timelimit on leaving your vehicle here", + "nl": "Geen maximum parkeertijd" + } + } + ] + }, + { + "id": "Network", + "render": { + "en": "Part of the network {network}" + }, + "question": { + "en": "Is this charging station part of a network?" + }, + "freeform": { + "key": "network" + }, + "mappings": [ + { + "if": "no:network=yes", + "then": { + "en": "Not part of a bigger network" + } + }, + { + "if": "network=none", + "then": { + "en": "Not part of a bigger network" + }, + "hideInAnswer": true + }, + { + "if": "network=AeroVironment", + "then": "AeroVironment" + }, + { + "if": "network=Blink", + "then": "Blink" + }, + { + "if": "network=eVgo", + "then": "eVgo" + } + ] + }, + { + "id": "Operator", + "question": { + "en": "Who is the operator of this charging station?" + }, + "render": { + "en": "This charging station is operated by {operator}" + }, + "freeform": { + "key": "operator" + }, + "mappings": [ + { + "if": { + "and": [ + "network:={operator}" + ] + }, + "then": { + "en": "Actually, {operator} is the network" + }, + "addExtraTags": [ + "operator=" + ], + "hideInAnswer": "operator=" + } + ] + }, + { + "id": "phone", + "question": { + "en": "What number can one call if there is a problem with this charging station?" + }, + "render": { + "en": "In case of problems, call {phone}" + }, + "freeform": { + "key": "phone", + "type": "phone" + } + }, + { + "id": "email", + "question": { + "en": "What is the email address of the operator?" + }, + "render": { + "en": "In case of problems, send an email to {email}" + }, + "freeform": { + "key": "email", + "type": "email" + } + }, + { + "id": "website", + "question": { + "en": "What is the website of the operator?" + }, + "render": { + "en": "More info on {website}" + }, + "freeform": { + "key": "website", + "type": "url" + } + }, + "level", + { + "id": "ref", + "question": { + "en": "What is the reference number of this charging station?" + }, + "render": { + "en": "Reference number is {ref}" + }, + "freeform": { + "key": "ref" + } + }, + { + "id": "Operational status", + "question": { + "en": "Is this charging point in use?", + "nl": "Is dit oplaadpunt operationeel?" + }, + "mappings": [ + { + "if": "operational_status=broken", + "then": { + "en": "This charging station is broken", + "nl": "Dit oplaadpunt is kapot" + } + }, + { + "if": { + "and": [ + "planned:amenity=charging_station", + "amenity=" + ] + }, + "then": { + "en": "A charging station is planned here", + "nl": "Hier zal binnenkort een oplaadpunt gebouwd worden" + } + }, + { + "if": { + "and": [ + "construction:amenity=charging_station", + "amenity=" + ] + }, + "then": { + "en": "A charging station is constructed here", + "nl": "Hier wordt op dit moment een oplaadpunt gebouwd" + } + }, + { + "if": { + "and": [ + "disused:amenity=charging_station", + "amenity=" + ] + }, + "then": { + "en": "This charging station has beed permanently disabled and is not in use anymore but is still visible", + "nl": "Dit oplaadpunt is niet meer in gebruik maar is wel nog aanwezig" + } + }, + { + "if": { + "and": [ + "amenity=charging_station", + "operational_status=" + ] + }, + "then": { + "en": "This charging station works", + "nl": "Dit oplaadpunt werkt" + } + } + ] + }, + { + "id": "Parking:fee", + "question": { + "en": "Does one have to pay a parking fee while charging?" + }, + "mappings": [ + { + "if": "parking:fee=no", + "then": { + "en": "No additional parking cost while charging" + } + }, + { + "if": "parking:fee=yes", + "then": { + "en": "An additional parking fee should be paid while charging" + } + } + ] + } + ], + "icon": { + "render": "pin:#fff;./assets/themes/charging_stations/plug.svg", + "mappings": [ + { + "if": "bicycle=yes", + "then": "pin:#fff;./assets/themes/charging_stations/bicycle.svg" + }, + { + "if": { + "or": [ + "car=yes", + "motorcar=yes" + ] + }, + "then": "pin:#fff;./assets/themes/charging_stations/car.svg" } - } ] - } }, - { - "id": "maxstay", - "question": { - "en": "What is the maximum amount of time one is allowed to stay here?", - "nl": "Hoelang mag een voertuig hier blijven staan?" - }, - "freeform": { - "key": "maxstay" - }, - "render": { - "en": "One can stay at most {canonical(maxstay)}", - "nl": "De maximale parkeertijd hier is {canonical(maxstay)}" - }, - "mappings": [ + "iconOverlays": [ { - "if": "maxstay=unlimited", - "then": { - "en": "No timelimit on leaving your vehicle here", - "nl": "Geen maximum parkeertijd" - } + "if": { + "or": [ + "disused:amenity=charging_station", + "operational_status=broken" + ] + }, + "then": "cross_bottom_right:#c22;" + }, + { + "if": { + "or": [ + "proposed:amenity=charging_station", + "planned:amenity=charging_station" + ] + }, + "then": "./assets/layers/charging_station/under_construction.svg", + "badge": true + }, + { + "if": { + "and": [ + "bicycle=yes", + { + "or": [ + "motorcar=yes", + "car=yes" + ] + } + ] + }, + "then": "circle:#fff;./assets/themes/charging_stations/car.svg", + "badge": true } - ] + ], + "width": { + "render": "8" }, - { - "id": "Network", - "render": { - "en": "Part of the network {network}" - }, - "question": { - "en": "Is this charging station part of a network?" - }, - "freeform": { - "key": "network" - }, - "mappings": [ + "iconSize": { + "render": "50,50,bottom" + }, + "color": { + "render": "#00f" + }, + "presets": [ { - "if": "no:network=yes", - "then": { - "en": "Not part of a bigger network" - } - }, - { - "if": "network=none", - "then": { - "en": "Not part of a bigger network" - }, - "hideInAnswer": true - }, - { - "if": "network=AeroVironment", - "then": "AeroVironment" - }, - { - "if": "network=Blink", - "then": "Blink" - }, - { - "if": "network=eVgo", - "then": "eVgo" + "tags": [ + "amenity=charging_station" + ], + "title": { + "en": "Charging station" + }, + "preciseInput": { + "preferredBackground": "map" + } } - ] - }, - { - "id": "Operator", - "question": { - "en": "Who is the operator of this charging station?" - }, - "render": { - "en": "This charging station is operated by {operator}" - }, - "freeform": { - "key": "operator" - }, - "mappings": [ + ], + "wayHandling": 1, + "filter": [ { - "if": { - "and": [ - "network:={operator}" + "id": "vehicle-type", + "options": [ + { + "question": { + "en": "All vehicle types", + "nl": "Alle voertuigen" + } + }, + { + "question": { + "en": "Charging station for bicycles", + "nl": "Oplaadpunten voor fietsen" + }, + "osmTags": "bicycle=yes" + }, + { + "question": { + "en": "Charging station for cars", + "nl": "Oplaadpunten voor auto's" + }, + "osmTags": { + "or": [ + "car=yes", + "motorcar=yes" + ] + } + } + ] + }, + { + "id": "working", + "options": [ + { + "question": { + "en": "Only working charging stations" + }, + "osmTags": { + "and": [ + "operational_status!=broken", + "amenity=charging_station" + ] + } + } + ] + }, + { + "id": "connection_type", + "options": [ + { + "question": { + "en": "All connectors", + "nl": "Alle types" + } + }, + { + "question": { + "en": "Has a
Schuko wall plug without ground pin (CEE7/4 type F)
connector", + "nl": "Heeft een
Schuko stekker zonder aardingspin (CEE7/4 type F)
" + }, + "osmTags": "socket:schuko~*" + }, + { + "question": { + "en": "Has a
European wall plug with ground pin (CEE7/4 type E)
connector", + "nl": "Heeft een
Europese stekker met aardingspin (CEE7/4 type E)
" + }, + "osmTags": "socket:typee~*" + }, + { + "question": { + "en": "Has a
Chademo
connector", + "nl": "Heeft een
Chademo
" + }, + "osmTags": "socket:chademo~*" + }, + { + "question": { + "en": "Has a
Type 1 with cable (J1772)
connector", + "nl": "Heeft een
Type 1 met kabel (J1772)
" + }, + "osmTags": "socket:type1_cable~*" + }, + { + "question": { + "en": "Has a
Type 1 without cable (J1772)
connector", + "nl": "Heeft een
Type 1 zonder kabel (J1772)
" + }, + "osmTags": "socket:type1~*" + }, + { + "question": { + "en": "Has a
Type 1 CCS (aka Type 1 Combo)
connector", + "nl": "Heeft een
Type 1 CCS (ook gekend als Type 1 Combo)
" + }, + "osmTags": "socket:type1_combo~*" + }, + { + "question": { + "en": "Has a
Tesla Supercharger
connector", + "nl": "Heeft een
Tesla Supercharger
" + }, + "osmTags": "socket:tesla_supercharger~*" + }, + { + "question": { + "en": "Has a
Type 2 (mennekes)
connector", + "nl": "Heeft een
Type 2 (mennekes)
" + }, + "osmTags": "socket:type2~*" + }, + { + "question": { + "en": "Has a
Type 2 CCS (mennekes)
connector", + "nl": "Heeft een
Type 2 CCS (mennekes)
" + }, + "osmTags": "socket:type2_combo~*" + }, + { + "question": { + "en": "Has a
Type 2 with cable (mennekes)
connector", + "nl": "Heeft een
Type 2 met kabel (J1772)
" + }, + "osmTags": "socket:type2_cable~*" + }, + { + "question": { + "en": "Has a
Tesla Supercharger CCS (a branded type2_css)
connector", + "nl": "Heeft een
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
" + }, + "osmTags": "socket:tesla_supercharger_ccs~*" + }, + { + "question": { + "en": "Has a
Tesla Supercharger (destination)
connector", + "nl": "Heeft een
Tesla Supercharger (destination)
" + }, + "osmTags": "socket:tesla_destination~*" + }, + { + "question": { + "en": "Has a
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
connector", + "nl": "Heeft een
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
" + }, + "osmTags": "socket:tesla_destination~*" + }, + { + "question": { + "en": "Has a
USB to charge phones and small electronics
connector", + "nl": "Heeft een
USB om GSMs en kleine electronica op te laden
" + }, + "osmTags": "socket:USB-A~*" + }, + { + "question": { + "en": "Has a
Bosch Active Connect with cable
connector", + "nl": "Heeft een
Bosch Active Connect aan een kabel
" + }, + "osmTags": "socket:bosch_3pin~*" + } ] - }, - "then": { - "en": "Actually, {operator} is the network" - }, - "addExtraTags": [ - "operator=" - ], - "hideInAnswer": "operator=" } - ] - }, - { - "id": "phone", - "question": { - "en": "What number can one call if there is a problem with this charging station?" - }, - "render": { - "en": "In case of problems, call {phone}" - }, - "freeform": { - "key": "phone", - "type": "phone" - } - }, - { - "id": "email", - "question": { - "en": "What is the email address of the operator?" - }, - "render": { - "en": "In case of problems, send an email to {email}" - }, - "freeform": { - "key": "email", - "type": "email" - } - }, - { - "id": "website", - "question": { - "en": "What is the website of the operator?" - }, - "render": { - "en": "More info on {website}" - }, - "freeform": { - "key": "website", - "type": "url" - } - }, - "level", - { - "id": "ref", - "question": { - "en": "What is the reference number of this charging station?" - }, - "render": { - "en": "Reference number is {ref}" - }, - "freeform": { - "key": "ref" - } - }, - { - "id": "Operational status", - "question": { - "en": "Is this charging point in use?", - "nl": "Is dit oplaadpunt operationeel?" - }, - "mappings": [ + ], + "units": [ { - "if": "operational_status=broken", - "then": { - "en": "This charging station is broken", - "nl": "Dit oplaadpunt is kapot" - } + "appliesToKey": [ + "maxstay" + ], + "applicableUnits": [ + { + "canonicalDenomination": "minutes", + "canonicalDenominationSingular": "minute", + "alternativeDenomination": [ + "m", + "min", + "mins", + "minuten", + "mns" + ], + "human": { + "en": " minutes", + "nl": " minuten" + }, + "humanSingular": { + "en": " minute", + "nl": " minuut" + } + }, + { + "canonicalDenomination": "hours", + "canonicalDenominationSingular": "hour", + "alternativeDenomination": [ + "h", + "hrs", + "hours", + "u", + "uur", + "uren" + ], + "human": { + "en": " hours", + "nl": " uren" + }, + "humanSingular": { + "en": " hour", + "nl": " uur" + } + }, + { + "canonicalDenomination": "days", + "canonicalDenominationSingular": "day", + "alternativeDenomination": [ + "dys", + "dagen", + "dag" + ], + "human": { + "en": " days", + "nl": " day" + }, + "humanSingular": { + "en": " day", + "nl": " dag" + } + } + ] }, { - "if": { - "and": [ - "planned:amenity=charging_station", - "amenity=" - ] - }, - "then": { - "en": "A charging station is planned here", - "nl": "Hier zal binnenkort een oplaadpunt gebouwd worden" - } + "appliesToKey": [ + "socket:schuko:voltage", + "socket:typee:voltage", + "socket:chademo:voltage", + "socket:type1_cable:voltage", + "socket:type1:voltage", + "socket:type1_combo:voltage", + "socket:tesla_supercharger:voltage", + "socket:type2:voltage", + "socket:type2_combo:voltage", + "socket:type2_cable:voltage", + "socket:tesla_supercharger_ccs:voltage", + "socket:tesla_destination:voltage", + "socket:tesla_destination:voltage", + "socket:USB-A:voltage", + "socket:bosch_3pin:voltage" + ], + "applicableUnits": [ + { + "canonicalDenomination": "V", + "alternativeDenomination": [ + "v", + "volt", + "voltage", + "V", + "Volt" + ], + "human": { + "en": "Volts", + "nl": "volt" + } + } + ], + "eraseInvalidValues": true }, { - "if": { - "and": [ - "construction:amenity=charging_station", - "amenity=" - ] - }, - "then": { - "en": "A charging station is constructed here", - "nl": "Hier wordt op dit moment een oplaadpunt gebouwd" - } + "appliesToKey": [ + "socket:schuko:current", + "socket:typee:current", + "socket:chademo:current", + "socket:type1_cable:current", + "socket:type1:current", + "socket:type1_combo:current", + "socket:tesla_supercharger:current", + "socket:type2:current", + "socket:type2_combo:current", + "socket:type2_cable:current", + "socket:tesla_supercharger_ccs:current", + "socket:tesla_destination:current", + "socket:tesla_destination:current", + "socket:USB-A:current", + "socket:bosch_3pin:current" + ], + "applicableUnits": [ + { + "canonicalDenomination": "A", + "alternativeDenomination": [ + "a", + "amp", + "amperage", + "A" + ], + "human": { + "en": "A", + "nl": "A" + } + } + ], + "eraseInvalidValues": true }, { - "if": { - "and": [ - "disused:amenity=charging_station", - "amenity=" - ] - }, - "then": { - "en": "This charging station has beed permanently disabled and is not in use anymore but is still visible", - "nl": "Dit oplaadpunt is niet meer in gebruik maar is wel nog aanwezig" - } - }, - { - "if": { - "and": [ - "amenity=charging_station", - "operational_status=" - ] - }, - "then": { - "en": "This charging station works", - "nl": "Dit oplaadpunt werkt" - } + "appliesToKey": [ + "socket:schuko:output", + "socket:typee:output", + "socket:chademo:output", + "socket:type1_cable:output", + "socket:type1:output", + "socket:type1_combo:output", + "socket:tesla_supercharger:output", + "socket:type2:output", + "socket:type2_combo:output", + "socket:type2_cable:output", + "socket:tesla_supercharger_ccs:output", + "socket:tesla_destination:output", + "socket:tesla_destination:output", + "socket:USB-A:output", + "socket:bosch_3pin:output" + ], + "applicableUnits": [ + { + "canonicalDenomination": "kW", + "alternativeDenomination": [ + "kilowatt" + ], + "human": { + "en": "kilowatt", + "nl": "kilowatt" + } + }, + { + "canonicalDenomination": "mW", + "alternativeDenomination": [ + "megawatt" + ], + "human": { + "en": "megawatt", + "nl": "megawatt" + } + } + ], + "eraseInvalidValues": true } - ] - }, - { - "id": "Parking:fee", - "question": { - "en": "Does one have to pay a parking fee while charging?" - }, - "mappings": [ - { - "if": "parking:fee=no", - "then": { - "en": "No additional parking cost while charging" - } - }, - { - "if": "parking:fee=yes", - "then": { - "en": "An additional parking fee should be paid while charging" - } - } - ] - } - ], - "icon": { - "render": "pin:#fff;./assets/themes/charging_stations/plug.svg", - "mappings": [ - { - "if": "bicycle=yes", - "then": "pin:#fff;./assets/themes/charging_stations/bicycle.svg" - }, - { - "if": { - "or": [ - "car=yes", - "motorcar=yes" - ] - }, - "then": "pin:#fff;./assets/themes/charging_stations/car.svg" - } ] - }, - "iconOverlays": [ - { - "if": { - "or": [ - "disused:amenity=charging_station", - "operational_status=broken" - ] - }, - "then": "cross_bottom_right:#c22;" - }, - { - "if": { - "or": [ - "proposed:amenity=charging_station", - "planned:amenity=charging_station" - ] - }, - "then": "./assets/layers/charging_station/under_construction.svg", - "badge": true - }, - { - "if": { - "and": [ - "bicycle=yes", - { - "or": [ - "motorcar=yes", - "car=yes" - ] - } - ] - }, - "then": "circle:#fff;./assets/themes/charging_stations/car.svg", - "badge": true - } - ], - "width": { - "render": "8" - }, - "iconSize": { - "render": "50,50,bottom" - }, - "color": { - "render": "#00f" - }, - "presets": [ - { - "tags": [ - "amenity=charging_station" - ], - "title": { - "en": "Charging station" - }, - "preciseInput": { - "preferredBackground": "map" - } - } - ], - "wayHandling": 1, - "filter": [ - { - "id": "vehicle-type", - "options": [ - { - "question": { - "en": "All vehicle types", - "nl": "Alle voertuigen" - } - }, - { - "question": { - "en": "Charging station for bicycles", - "nl": "Oplaadpunten voor fietsen" - }, - "osmTags": "bicycle=yes" - }, - { - "question": { - "en": "Charging station for cars", - "nl": "Oplaadpunten voor auto's" - }, - "osmTags": { - "or": [ - "car=yes", - "motorcar=yes" - ] - } - } - ] - }, - { - "id": "working", - "options": [ - { - "question": { - "en": "Only working charging stations" - }, - "osmTags": { - "and": [ - "operational_status!=broken", - "amenity=charging_station" - ] - } - } - ] - }, - { - "id": "connection_type", - "options": [ - { - "question": { - "en": "All connectors", - "nl": "Alle types" - } - }, - { - "question": { - "en": "Has a
Schuko wall plug without ground pin (CEE7/4 type F)
connector", - "nl": "Heeft een
Schuko stekker zonder aardingspin (CEE7/4 type F)
" - }, - "osmTags": "socket:schuko~*" - }, - { - "question": { - "en": "Has a
European wall plug with ground pin (CEE7/4 type E)
connector", - "nl": "Heeft een
Europese stekker met aardingspin (CEE7/4 type E)
" - }, - "osmTags": "socket:typee~*" - }, - { - "question": { - "en": "Has a
Chademo
connector", - "nl": "Heeft een
Chademo
" - }, - "osmTags": "socket:chademo~*" - }, - { - "question": { - "en": "Has a
Type 1 with cable (J1772)
connector", - "nl": "Heeft een
Type 1 met kabel (J1772)
" - }, - "osmTags": "socket:type1_cable~*" - }, - { - "question": { - "en": "Has a
Type 1 without cable (J1772)
connector", - "nl": "Heeft een
Type 1 zonder kabel (J1772)
" - }, - "osmTags": "socket:type1~*" - }, - { - "question": { - "en": "Has a
Type 1 CCS (aka Type 1 Combo)
connector", - "nl": "Heeft een
Type 1 CCS (ook gekend als Type 1 Combo)
" - }, - "osmTags": "socket:type1_combo~*" - }, - { - "question": { - "en": "Has a
Tesla Supercharger
connector", - "nl": "Heeft een
Tesla Supercharger
" - }, - "osmTags": "socket:tesla_supercharger~*" - }, - { - "question": { - "en": "Has a
Type 2 (mennekes)
connector", - "nl": "Heeft een
Type 2 (mennekes)
" - }, - "osmTags": "socket:type2~*" - }, - { - "question": { - "en": "Has a
Type 2 CCS (mennekes)
connector", - "nl": "Heeft een
Type 2 CCS (mennekes)
" - }, - "osmTags": "socket:type2_combo~*" - }, - { - "question": { - "en": "Has a
Type 2 with cable (mennekes)
connector", - "nl": "Heeft een
Type 2 met kabel (J1772)
" - }, - "osmTags": "socket:type2_cable~*" - }, - { - "question": { - "en": "Has a
Tesla Supercharger CCS (a branded type2_css)
connector", - "nl": "Heeft een
Tesla Supercharger CCS (een type2 CCS met Tesla-logo)
" - }, - "osmTags": "socket:tesla_supercharger_ccs~*" - }, - { - "question": { - "en": "Has a
Tesla Supercharger (destination)
connector", - "nl": "Heeft een
Tesla Supercharger (destination)
" - }, - "osmTags": "socket:tesla_destination~*" - }, - { - "question": { - "en": "Has a
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
connector", - "nl": "Heeft een
Tesla supercharger (destination (Een Type 2 met kabel en Tesla-logo)
" - }, - "osmTags": "socket:tesla_destination~*" - }, - { - "question": { - "en": "Has a
USB to charge phones and small electronics
connector", - "nl": "Heeft een
USB om GSMs en kleine electronica op te laden
" - }, - "osmTags": "socket:USB-A~*" - }, - { - "question": { - "en": "Has a
Bosch Active Connect with cable
connector", - "nl": "Heeft een
Bosch Active Connect aan een kabel
" - }, - "osmTags": "socket:bosch_3pin~*" - } - ] - } - ], - "units": [ - { - "appliesToKey": [ - "maxstay" - ], - "applicableUnits": [ - { - "canonicalDenomination": "minutes", - "canonicalDenominationSingular": "minute", - "alternativeDenomination": [ - "m", - "min", - "mins", - "minuten", - "mns" - ], - "human": { - "en": " minutes", - "nl": " minuten" - }, - "humanSingular": { - "en": " minute", - "nl": " minuut" - } - }, - { - "canonicalDenomination": "hours", - "canonicalDenominationSingular": "hour", - "alternativeDenomination": [ - "h", - "hrs", - "hours", - "u", - "uur", - "uren" - ], - "human": { - "en": " hours", - "nl": " uren" - }, - "humanSingular": { - "en": " hour", - "nl": " uur" - } - }, - { - "canonicalDenomination": "days", - "canonicalDenominationSingular": "day", - "alternativeDenomination": [ - "dys", - "dagen", - "dag" - ], - "human": { - "en": " days", - "nl": " day" - }, - "humanSingular": { - "en": " day", - "nl": " dag" - } - } - ] - }, - { - "appliesToKey": [ - "socket:schuko:voltage", - "socket:typee:voltage", - "socket:chademo:voltage", - "socket:type1_cable:voltage", - "socket:type1:voltage", - "socket:type1_combo:voltage", - "socket:tesla_supercharger:voltage", - "socket:type2:voltage", - "socket:type2_combo:voltage", - "socket:type2_cable:voltage", - "socket:tesla_supercharger_ccs:voltage", - "socket:tesla_destination:voltage", - "socket:tesla_destination:voltage", - "socket:USB-A:voltage", - "socket:bosch_3pin:voltage" - ], - "applicableUnits": [ - { - "canonicalDenomination": "V", - "alternativeDenomination": [ - "v", - "volt", - "voltage", - "V", - "Volt" - ], - "human": { - "en": "Volts", - "nl": "volt" - } - } - ], - "eraseInvalidValues": true - }, - { - "appliesToKey": [ - "socket:schuko:current", - "socket:typee:current", - "socket:chademo:current", - "socket:type1_cable:current", - "socket:type1:current", - "socket:type1_combo:current", - "socket:tesla_supercharger:current", - "socket:type2:current", - "socket:type2_combo:current", - "socket:type2_cable:current", - "socket:tesla_supercharger_ccs:current", - "socket:tesla_destination:current", - "socket:tesla_destination:current", - "socket:USB-A:current", - "socket:bosch_3pin:current" - ], - "applicableUnits": [ - { - "canonicalDenomination": "A", - "alternativeDenomination": [ - "a", - "amp", - "amperage", - "A" - ], - "human": { - "en": "A", - "nl": "A" - } - } - ], - "eraseInvalidValues": true - }, - { - "appliesToKey": [ - "socket:schuko:output", - "socket:typee:output", - "socket:chademo:output", - "socket:type1_cable:output", - "socket:type1:output", - "socket:type1_combo:output", - "socket:tesla_supercharger:output", - "socket:type2:output", - "socket:type2_combo:output", - "socket:type2_cable:output", - "socket:tesla_supercharger_ccs:output", - "socket:tesla_destination:output", - "socket:tesla_destination:output", - "socket:USB-A:output", - "socket:bosch_3pin:output" - ], - "applicableUnits": [ - { - "canonicalDenomination": "kW", - "alternativeDenomination": [ - "kilowatt" - ], - "human": { - "en": "kilowatt", - "nl": "kilowatt" - } - }, - { - "canonicalDenomination": "mW", - "alternativeDenomination": [ - "megawatt" - ], - "human": { - "en": "megawatt", - "nl": "megawatt" - } - } - ], - "eraseInvalidValues": true - } - ] } \ No newline at end of file diff --git a/assets/tagRenderings/questions.json b/assets/tagRenderings/questions.json index 509749aa0..fc7756492 100644 --- a/assets/tagRenderings/questions.json +++ b/assets/tagRenderings/questions.json @@ -3,7 +3,8 @@ "render": "{image_carousel()}{image_upload()}" }, "wikipedia": { - "render": "{wikipedia():max-height:25rem}" + "render": "{wikipedia():max-height:25rem}", + "condition": "wikidata~*" }, "reviews": { "render": "{reviews()}" diff --git a/assets/themes/etymology.json b/assets/themes/etymology.json index ec170496a..499ec1c06 100644 --- a/assets/themes/etymology.json +++ b/assets/themes/etymology.json @@ -26,7 +26,7 @@ "socialImage": "", "layers": [ { - "id": "has_a_name", + "id": "has_etymology", "name": { "en": "Has etymolgy", "nl": "Heeft etymology info" @@ -71,6 +71,21 @@ "render": { "*": "{wikipedia(name:etymology:wikidata):max-height:30rem}" } + }, + { + "id": "wikidata-embed", + "render": { + "*": "" + }, + "condition": "name:etymology:wikidata~*" + }, + "wikipedia", + { + "id": "street-name-sign-image", + "render": { + "en": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Add image of a street name sign)}", + "nl": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" + } } ], "icon": { @@ -86,7 +101,114 @@ "render": "#00f" }, "presets": [] + }, + { + "id": "etymology_missing", + "name": { + "en": "No etymology data yet", + "nl": "Zonder etymology" + }, + "source": { + "osmTags": { + "and": [ + "name~*", + { + "or": [ + "highway~*", + "building~*", + "amenity=place_of_worship", + "man_made=bridge", + "heritage~*", + "leisure=park", + "leisure=nature_reserve", + "landuse=forest", + "natural=water" + ] + }, + { + "#": "We remove various features which often are too big and clutter the map", + "and": [ + "healtcare=", + "shop=", + "school=", + "place=", + "landuse!=residential" + ] + } + ] + } + }, + "minZoom": 16, + "title": { + "render": { + "*": "{name}" + } + }, + "tagRenderings": [ + { + "id": "name-origin-wikidata", + "question": { + "en": "What is the wikidata entry for the thing this feature is named after?", + "nl": "Wat is de wikidata-entry voor het object waarnaar dit vernoemd is?
Plak hier de wikidata entry of sla over" + }, + "render": { + "*": "{name:etymology:wikidata}" + }, + "freeform": { + "key": "name:etymology:wikidata", + "type": "wikidata", + "helperArgs": [ + "name", + { + "removePostfixes": [ + "steenweg", + "heirbaan", + "baan", + "straat", + "street", + "weg", + "dreef", + "laan", + "boulevard", + "pad", + "path", + "plein", + "square", + "plaza", + "wegel", + "kerk", + "church", + "kaai" + ] + } + ] + } + }, + { + "id": "name-origin", + "question": { + "en": "What is the origin of this name?", + "nl": "Naar wat is dit vernoemd?" + }, + "render": { + "en": "
This feature is named after

{name:etymology{", + "nl": "
Dit is vernoemd naar

{name:etymology{" + }, + "freeform": { + "key": "name:etymology" + }, + "condition": "name:etymology:wikidata=" + }, + "wikipedia", + { + "id": "street-name-sign-image", + "render": { + "en": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Add image of a street name sign)}", + "nl": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" + } + } + ], + "color": "#fcb35388" } - ], - "roamingRenderings": [] + ] } \ No newline at end of file diff --git a/css/index-tailwind-output.css b/css/index-tailwind-output.css index b51496b0f..d2b2ec440 100644 --- a/css/index-tailwind-output.css +++ b/css/index-tailwind-output.css @@ -824,6 +824,10 @@ video { margin: 1rem; } +.m-px { + margin: 1px; +} + .my-2 { margin-top: 0.5rem; margin-bottom: 0.5rem; @@ -848,18 +852,14 @@ video { margin-left: 0.75rem; } -.mr-3 { - margin-right: 0.75rem; +.mb-2 { + margin-bottom: 0.5rem; } .mr-4 { margin-right: 1rem; } -.mb-2 { - margin-bottom: 0.5rem; -} - .mt-3 { margin-top: 0.75rem; } @@ -912,6 +912,10 @@ video { margin-bottom: 0.25rem; } +.mr-3 { + margin-right: 0.75rem; +} + .mb-4 { margin-bottom: 1rem; } @@ -1251,14 +1255,14 @@ video { border-radius: 0.25rem; } -.rounded-xl { - border-radius: 0.75rem; -} - .rounded-lg { border-radius: 0.5rem; } +.rounded-xl { + border-radius: 0.75rem; +} + .border { border-width: 1px; } @@ -1390,18 +1394,6 @@ video { padding-left: 0.5rem; } -.pr-2 { - padding-right: 0.5rem; -} - -.pl-6 { - padding-left: 1.5rem; -} - -.pt-2 { - padding-top: 0.5rem; -} - .pt-3 { padding-top: 0.75rem; } @@ -1462,6 +1454,18 @@ video { padding-top: 0px; } +.pr-2 { + padding-right: 0.5rem; +} + +.pl-6 { + padding-left: 1.5rem; +} + +.pt-2 { + padding-top: 0.5rem; +} + .text-center { text-align: center; } @@ -1582,14 +1586,14 @@ video { text-decoration: underline; } -.opacity-50 { - opacity: 0.5; -} - .opacity-0 { opacity: 0; } +.opacity-50 { + opacity: 0.5; +} + .opacity-40 { opacity: 0.4; } @@ -1632,6 +1636,12 @@ video { transition-duration: 150ms; } +.transition-colors { + transition-property: background-color, border-color, color, fill, stroke; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + .transition-opacity { transition-property: opacity; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); @@ -1902,6 +1912,10 @@ li::marker { border: 5px solid var(--catch-detail-color); } +.border-attention { + border-color: var(--catch-detail-color); +} + .direction-svg svg path { fill: var(--catch-detail-color) !important; } @@ -2223,6 +2237,10 @@ li::marker { } @media (min-width: 640px) { + .sm\:m-1 { + margin: 0.25rem; + } + .sm\:mx-auto { margin-left: auto; margin-right: auto; @@ -2268,6 +2286,10 @@ li::marker { justify-content: space-between; } + .sm\:border-4 { + border-width: 4px; + } + .sm\:p-0\.5 { padding: 0.125rem; } @@ -2284,6 +2306,10 @@ li::marker { padding: 0.25rem; } + .sm\:p-2 { + padding: 0.5rem; + } + .sm\:pl-2 { padding-left: 0.5rem; } @@ -2383,6 +2409,10 @@ li::marker { padding: 0.5rem; } + .md\:p-3 { + padding: 0.75rem; + } + .md\:pt-4 { padding-top: 1rem; } diff --git a/index.css b/index.css index 8660c1ba3..f4e51240a 100644 --- a/index.css +++ b/index.css @@ -195,6 +195,10 @@ li::marker { border: 5px solid var(--catch-detail-color); } +.border-attention { + border-color: var(--catch-detail-color); +} + .direction-svg svg path { fill: var(--catch-detail-color) !important; } diff --git a/langs/en.json b/langs/en.json index 650963864..d890eccb4 100644 --- a/langs/en.json +++ b/langs/en.json @@ -222,7 +222,11 @@ "wikipediaboxTitle": "Wikipedia", "failed":"Loading the wikipedia entry failed", "loading": "Loading Wikipedia...", - "noWikipediaPage": "This wikidata item has no corresponding wikipedia page yet." + "noWikipediaPage": "This wikidata item has no corresponding wikipedia page yet.", + "searchWikidata": "Search on wikidata", + "doSearch": "Search above to see results", + "noResults": "Nothing found for {search}", + "createNewWikidata": "Create a new wikidata item" } }, "favourite": { diff --git a/langs/themes/en.json b/langs/themes/en.json index 9dcb4b54a..20550191a 100644 --- a/langs/themes/en.json +++ b/langs/themes/en.json @@ -752,6 +752,24 @@ "tagRenderings": { "simple etymology": { "render": "Named after {name:etymology}" + }, + "street-name-sign-image": { + "render": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Add image of a street name sign)}" + } + } + }, + "1": { + "name": "No etymology data yet", + "tagRenderings": { + "name-origin": { + "question": "What is the origin of this name?", + "render": "
This feature is named after

{name:etymology{" + }, + "name-origin-wikidata": { + "question": "What is the wikidata entry for the thing this feature is named after?" + }, + "street-name-sign-image": { + "render": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Add image of a street name sign)}" } } } diff --git a/langs/themes/nl.json b/langs/themes/nl.json index 409d96fea..faac84c2e 100644 --- a/langs/themes/nl.json +++ b/langs/themes/nl.json @@ -633,6 +633,24 @@ "tagRenderings": { "simple etymology": { "render": "Vernoemd naar {name:etymology}" + }, + "street-name-sign-image": { + "render": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" + } + } + }, + "1": { + "name": "Zonder etymology", + "tagRenderings": { + "name-origin": { + "question": "Naar wat is dit vernoemd?", + "render": "
Dit is vernoemd naar

{name:etymology{" + }, + "name-origin-wikidata": { + "question": "Wat is de wikidata-entry voor het object waarnaar dit vernoemd is?
Plak hier de wikidata entry of sla over" + }, + "street-name-sign-image": { + "render": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" } } } diff --git a/test.ts b/test.ts index e6f2a9966..631d1e061 100644 --- a/test.ts +++ b/test.ts @@ -1,26 +1,6 @@ -import FeatureInfoBox from "./UI/Popup/FeatureInfoBox"; +import WikidataPreviewBox from "./UI/Wikipedia/WikidataPreviewBox"; import {UIEventSource} from "./Logic/UIEventSource"; -import AllKnownLayers from "./Customizations/AllKnownLayers"; -import State from "./State"; -import {AllKnownLayouts} from "./Customizations/AllKnownLayouts"; +import Wikidata from "./Logic/Web/Wikidata"; +import WikidataSearchBox from "./UI/Wikipedia/WikidataSearchBox"; -State.state = new State(AllKnownLayouts.allKnownLayouts.get("charging_stations")) -State.state.changes.pendingChanges.setData([]) -const geojson = { - type: "Feature", - geometry: { - type: "Point", - coordinates: [51.0, 4] - }, - properties: - { - id: "node/42", - amenity: "charging_station", - } -} -State.state.allElements.addOrGetElement(geojson) -const tags = State.state.allElements.getEventSourceById("node/42") -new FeatureInfoBox( - tags, - AllKnownLayers.sharedLayers.get("charging_station") -).AttachTo("maindiv") \ No newline at end of file +new WikidataSearchBox({searchText: new UIEventSource("Brugge")}).AttachTo("maindiv") \ No newline at end of file From 5f5ad6222fe146c73ea7645a835c9e302e509dce Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sat, 9 Oct 2021 13:33:40 +0200 Subject: [PATCH 11/26] Version bump --- Models/Constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Models/Constants.ts b/Models/Constants.ts index 08a4f4358..97dc31237 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import {Utils} from "../Utils"; export default class Constants { - public static vNumber = "0.11.0-alpha"; + public static vNumber = "0.11.0-alpha-0"; public static ImgurApiKey = '7070e7167f0a25a' public static readonly mapillary_client_token_v3 = 'TXhLaWthQ1d4RUg0czVxaTVoRjFJZzowNDczNjUzNmIyNTQyYzI2' From 9726d85ad7033f006be6681757aee2b14a116b94 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sat, 9 Oct 2021 13:38:22 +0200 Subject: [PATCH 12/26] Translation reset --- langs/themes/en.json | 14 ++++---------- langs/themes/nl.json | 14 ++++---------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/langs/themes/en.json b/langs/themes/en.json index 20550191a..99694b1f4 100644 --- a/langs/themes/en.json +++ b/langs/themes/en.json @@ -759,17 +759,11 @@ } }, "1": { - "name": "No etymology data yet", + "description": "All objects which have an etymology known", + "name": "Has etymolgy", "tagRenderings": { - "name-origin": { - "question": "What is the origin of this name?", - "render": "
This feature is named after

{name:etymology{" - }, - "name-origin-wikidata": { - "question": "What is the wikidata entry for the thing this feature is named after?" - }, - "street-name-sign-image": { - "render": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Add image of a street name sign)}" + "simple etymology": { + "render": "Named after {name:etymology}" } } } diff --git a/langs/themes/nl.json b/langs/themes/nl.json index faac84c2e..c8ad880ca 100644 --- a/langs/themes/nl.json +++ b/langs/themes/nl.json @@ -640,17 +640,11 @@ } }, "1": { - "name": "Zonder etymology", + "description": "Alle lagen met een gelinkt etymology", + "name": "Heeft etymology info", "tagRenderings": { - "name-origin": { - "question": "Naar wat is dit vernoemd?", - "render": "
Dit is vernoemd naar

{name:etymology{" - }, - "name-origin-wikidata": { - "question": "Wat is de wikidata-entry voor het object waarnaar dit vernoemd is?
Plak hier de wikidata entry of sla over" - }, - "street-name-sign-image": { - "render": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" + "simple etymology": { + "render": "Vernoemd naar {name:etymology}" } } } From 9faac532b505aa885bafc1b810f01d1a1c4dd2f6 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sat, 9 Oct 2021 22:40:52 +0200 Subject: [PATCH 13/26] Support for lexemes, decent etymology layer and theme with rudimentary icon --- .gitignore | 3 +- Logic/Web/Wikidata.ts | 315 ++++++++++++++-------- UI/Input/ValidatedTextField.ts | 17 +- UI/Popup/TagRenderingQuestion.ts | 2 +- UI/Wikipedia/WikidataPreviewBox.ts | 3 +- UI/Wikipedia/WikidataSearchBox.ts | 4 +- UI/Wikipedia/WikipediaBox.ts | 7 +- assets/layers/etymology/etymology.json | 138 ++++++++++ assets/layers/etymology/license_info.json | 10 + assets/layers/etymology/logo.svg | 107 ++++++++ assets/tagRenderings/questions.json | 18 +- assets/themes/etymology.json | 146 ++-------- css/index-tailwind-output.css | 25 +- css/tagrendering.css | 6 - css/wikipedia.css | 6 + index.css | 21 ++ test.ts | 7 +- test/Wikidata.spec.test.ts | 46 ++++ 18 files changed, 611 insertions(+), 270 deletions(-) create mode 100644 assets/layers/etymology/etymology.json create mode 100644 assets/layers/etymology/license_info.json create mode 100644 assets/layers/etymology/logo.svg diff --git a/.gitignore b/.gitignore index 5d39c4885..f2ff425f8 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,5 @@ Docs/Tools/stats.csv missing_translations.txt *.swp .DS_Store -Svg.ts \ No newline at end of file +Svg.ts +data/ diff --git a/Logic/Web/Wikidata.ts b/Logic/Web/Wikidata.ts index e77dcc2ee..c23a5347c 100644 --- a/Logic/Web/Wikidata.ts +++ b/Logic/Web/Wikidata.ts @@ -2,27 +2,33 @@ import {Utils} from "../../Utils"; import {UIEventSource} from "../UIEventSource"; -export interface WikidataResponse { +export class WikidataResponse { + public readonly id: string + public readonly labels: Map + public readonly descriptions: Map + public readonly claims: Map> + public readonly wikisites: Map + public readonly commons: string - id: string, - labels: Map, - descriptions: Map, - claims: Map>, - wikisites: Map - commons: string -} + constructor( + id: string, + labels: Map, + descriptions: Map, + claims: Map>, + wikisites: Map, + commons: string + ) { -export interface WikidataSearchoptions { - lang?: "en" | string, - maxCount?: 20 | number -} + this.id = id + this.labels = labels + this.descriptions = descriptions + this.claims = claims + this.wikisites = wikisites + this.commons = commons -/** - * Utility functions around wikidata - */ -export default class Wikidata { + } - private static ParseResponse(entity: any): WikidataResponse { + public static fromJson(entity: any): WikidataResponse { const labels = new Map() for (const labelName in entity.labels) { // The labelname is the language code @@ -42,163 +48,252 @@ export default class Wikidata { const title = entity.sitelinks[labelName].title sitelinks.set(language, title) } - + const commons = sitelinks.get("commons") sitelinks.delete("commons") + const claims = WikidataResponse.extractClaims(entity.claims); + return new WikidataResponse( + entity.id, + labels, + descr, + claims, + sitelinks, + commons + ) + + } + + static extractClaims(claimsJson: any): Map> { const claims = new Map>(); - for (const claimId in entity.claims) { + for (const claimId in claimsJson) { - const claimsList: any[] = entity.claims[claimId] + const claimsList: any[] = claimsJson[claimId] const values = new Set() for (const claim of claimsList) { let value = claim.mainsnak?.datavalue?.value; if (value === undefined) { continue; } - if(value.id !== undefined){ + if (value.id !== undefined) { value = value.id } values.add(value) } claims.set(claimId, values); } + return claims + } +} - return { - claims: claims, - descriptions: descr, - id: entity.id, - labels: labels, - wikisites: sitelinks, - commons: commons +export class WikidataLexeme { + id: string + lemma: Map + senses: Map + claims: Map> + + + constructor(json) { + this.id = json.id + this.claims = WikidataResponse.extractClaims(json.claims) + this.lemma = new Map() + for (const language in json.lemmas) { + this.lemma.set(language, json.lemmas[language].value) + } + + this.senses = new Map() + + for (const sense of json.senses) { + const glosses = sense.glosses + for (const language in glosses) { + let previousSenses = this.senses.get(language) + if(previousSenses === undefined){ + previousSenses = "" + }else{ + previousSenses = previousSenses+"; " + } + this.senses.set(language, previousSenses + glosses[language].value ?? "") + } } } - private static readonly _cache = new Map>() - public static LoadWikidataEntry(value: string | number): UIEventSource<{success: WikidataResponse} | {error: any}> { + asWikidataResponse() { + return new WikidataResponse( + this.id, + this.lemma, + this.senses, + this.claims, + new Map(), + undefined + ); + } +} + +export interface WikidataSearchoptions { + lang?: "en" | string, + maxCount?: 20 | number +} + +/** + * Utility functions around wikidata + */ +export default class Wikidata { + + private static readonly _identifierPrefixes = ["Q", "L"].map(str => str.toLowerCase()) + private static readonly _prefixesToRemove = ["https://www.wikidata.org/wiki/Lexeme:", "https://www.wikidata.org/wiki/", "Lexeme:"].map(str => str.toLowerCase()) + + + private static readonly _cache = new Map>() + + public static LoadWikidataEntry(value: string | number): UIEventSource<{ success: WikidataResponse } | { error: any }> { const key = this.ExtractKey(value) const cached = Wikidata._cache.get(key) - if(cached !== undefined){ + if (cached !== undefined) { return cached } const src = UIEventSource.FromPromiseWithErr(Wikidata.LoadWikidataEntryAsync(key)) Wikidata._cache.set(key, src) return src; } - + public static async search( - search: string, - options?:WikidataSearchoptions, - page = 1 - ): Promise<{ + search: string, + options?: WikidataSearchoptions, + page = 1 + ): Promise<{ id: string, label: string, description: string }[]> { - const maxCount = options?.maxCount ?? 20 - let pageCount = Math.min(maxCount,50) - const start = page * pageCount - pageCount; - const lang = (options?.lang ?? "en") - const url = - "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + - search + - "&language=" + - lang + - "&limit="+pageCount+"&continue=" + - start + - "&format=json&uselang=" + - lang + - "&type=item&origin=*"+ - "&props=" ;// props= removes some unused values in the result - const response = await Utils.downloadJson(url) - - const result : any[] = response.search - - if(result.length < pageCount){ - // No next page - return result; - } - if(result.length < maxCount){ - const newOptions = {...options} - newOptions.maxCount = maxCount - result.length - result.push(...await Wikidata.search(search, - newOptions, - page + 1 - )) - } - + const maxCount = options?.maxCount ?? 20 + let pageCount = Math.min(maxCount, 50) + const start = page * pageCount - pageCount; + const lang = (options?.lang ?? "en") + const url = + "https://www.wikidata.org/w/api.php?action=wbsearchentities&search=" + + search + + "&language=" + + lang + + "&limit=" + pageCount + "&continue=" + + start + + "&format=json&uselang=" + + lang + + "&type=item&origin=*" + + "&props=";// props= removes some unused values in the result + const response = await Utils.downloadJson(url) + + const result: any[] = response.search + + if (result.length < pageCount) { + // No next page return result; + } + if (result.length < maxCount) { + const newOptions = {...options} + newOptions.maxCount = maxCount - result.length + result.push(...await Wikidata.search(search, + newOptions, + page + 1 + )) + } + + return result; } - + public static async searchAndFetch( - search: string, - options?:WikidataSearchoptions -) : Promise - { + search: string, + options?: WikidataSearchoptions + ): Promise { const maxCount = options.maxCount // We provide some padding to filter away invalid values options.maxCount = Math.ceil((options.maxCount ?? 20) * 1.5) const searchResults = await Wikidata.search(search, options) - const maybeResponses = await Promise.all(searchResults.map(async r => { - try{ - return await Wikidata.LoadWikidataEntry(r.id).AsPromise() - }catch(e){ - console.error(e) - return undefined; - } + const maybeResponses = await Promise.all(searchResults.map(async r => { + try { + return await Wikidata.LoadWikidataEntry(r.id).AsPromise() + } catch (e) { + console.error(e) + return undefined; + } })) const responses = maybeResponses - .map(r => r["success"]) + .map(r => r["success"]) .filter(wd => { - if(wd === undefined){ - return false; - } - if(wd.claims.get("P31" /*Instance of*/)?.has("Q4167410"/* Wikimedia Disambiguation page*/)){ - return false; - } - return true; - }) + if (wd === undefined) { + return false; + } + if (wd.claims.get("P31" /*Instance of*/)?.has("Q4167410"/* Wikimedia Disambiguation page*/)) { + return false; + } + return true; + }) responses.splice(maxCount, responses.length - maxCount) - return responses + return responses } - - private static ExtractKey(value: string | number) : number{ + + public static ExtractKey(value: string | number): string { if (typeof value === "number") { - return value + return "Q" + value } - const wikidataUrl = "https://www.wikidata.org/wiki/" - if (value.startsWith(wikidataUrl)) { - value = value.substring(wikidataUrl.length) + if (value === undefined) { + console.error("ExtractKey: value is undefined") + return undefined; } - if (value.startsWith("http")) { + value = value.trim().toLowerCase() + + for (const prefix of Wikidata._prefixesToRemove) { + if (value.startsWith(prefix)) { + value = value.substring(prefix.length) + } + } + + if (value.startsWith("http") && value === "") { // Probably some random link in the image field - we skip it return undefined } - if (value.startsWith("Q")) { - value = value.substring(1) + + for (const identifierPrefix of Wikidata._identifierPrefixes) { + if (value.startsWith(identifierPrefix)) { + const trimmed = value.substring(identifierPrefix.length); + if(trimmed === ""){ + return undefined + } + const n = Number(trimmed) + if (isNaN(n)) { + return undefined + } + return value.toUpperCase(); + } } - const n = Number(value) - if(isNaN(n)){ - return undefined + + if (value !== "" && !isNaN(Number(value))) { + return "Q" + value } - return n; + + return undefined; } - + /** * Loads a wikidata page * @returns the entity of the given value */ public static async LoadWikidataEntryAsync(value: string | number): Promise { const id = Wikidata.ExtractKey(value) - if(id === undefined){ + if (id === undefined) { console.warn("Could not extract a wikidata entry from", value) - return undefined; + throw "Could not extract a wikidata entry from " + value } - - const url = "https://www.wikidata.org/wiki/Special:EntityData/Q" + id + ".json"; - const response = await Utils.downloadJson(url) - return Wikidata.ParseResponse(response.entities["Q" + id]) + + const url = "https://www.wikidata.org/wiki/Special:EntityData/" + id + ".json"; + const response = (await Utils.downloadJson(url)).entities[id] + + if (id.startsWith("L")) { + // This is a lexeme: + return new WikidataLexeme(response).asWikidataResponse() + } + + return WikidataResponse.fromJson(response) } } \ No newline at end of file diff --git a/UI/Input/ValidatedTextField.ts b/UI/Input/ValidatedTextField.ts index 7218d590e..9840071aa 100644 --- a/UI/Input/ValidatedTextField.ts +++ b/UI/Input/ValidatedTextField.ts @@ -17,6 +17,7 @@ import {GeoOperations} from "../../Logic/GeoOperations"; import {Unit} from "../../Models/Unit"; import {FixedInputElement} from "./FixedInputElement"; import WikidataSearchBox from "../Wikipedia/WikidataSearchBox"; +import Wikidata from "../../Logic/Web/Wikidata"; interface TextFieldDef { name: string, @@ -153,20 +154,23 @@ export default class ValidatedTextField { if (str === undefined) { return false; } - return (str.length > 1 && (str.startsWith("q") || str.startsWith("Q")) || str.startsWith("https://www.wikidata.org/wiki/Q")) + if(str.length <= 2){ + return false; + } + return !str.split(";").some(str => Wikidata.ExtractKey(str) === undefined) }, (str) => { if (str === undefined) { return undefined; } - const wd = "https://www.wikidata.org/wiki/"; - if (str.startsWith(wd)) { - str = str.substr(wd.length) + let out = str.split(";").map(str => Wikidata.ExtractKey(str)).join("; ") + if(str.endsWith(";")){ + out = out + ";" } - return str.toUpperCase(); + return out; }, (currentValue, inputHelperOptions) => { - const args = inputHelperOptions.args + const args = inputHelperOptions.args ?? [] const searchKey = args[0] ?? "name" let searchFor = inputHelperOptions.feature?.properties[searchKey]?.toLowerCase() @@ -175,7 +179,6 @@ export default class ValidatedTextField { if (searchFor !== undefined && options !== undefined) { const prefixes = options["removePrefixes"] const postfixes = options["removePostfixes"] - for (const postfix of postfixes ?? []) { if (searchFor.endsWith(postfix)) { searchFor = searchFor.substring(0, searchFor.length - postfix.length) diff --git a/UI/Popup/TagRenderingQuestion.ts b/UI/Popup/TagRenderingQuestion.ts index 16811a3b1..556635c57 100644 --- a/UI/Popup/TagRenderingQuestion.ts +++ b/UI/Popup/TagRenderingQuestion.ts @@ -136,7 +136,7 @@ export default class TagRenderingQuestion extends Combine { options.cancelButton, saveButton, bottomTags]) - this.SetClass("question") + this.SetClass("question disable-links") } diff --git a/UI/Wikipedia/WikidataPreviewBox.ts b/UI/Wikipedia/WikidataPreviewBox.ts index 650b76327..3fe01aab8 100644 --- a/UI/Wikipedia/WikidataPreviewBox.ts +++ b/UI/Wikipedia/WikidataPreviewBox.ts @@ -51,8 +51,9 @@ export default class WikidataPreviewBox extends VariableUiElement { wikidata.id, Svg.wikidata_ui().SetStyle("width: 2.5rem").SetClass("block") ]).SetClass("flex"), - "https://wikidata.org/wiki/"+wikidata.id ,true) + "https://wikidata.org/wiki/"+wikidata.id ,true).SetClass("must-link") + console.log(wikidata) let info = new Combine( [ new Combine([Translation.fromMap(wikidata.labels).SetClass("font-bold"), link]).SetClass("flex justify-between"), diff --git a/UI/Wikipedia/WikidataSearchBox.ts b/UI/Wikipedia/WikidataSearchBox.ts index dce60c02e..da0c90ebc 100644 --- a/UI/Wikipedia/WikidataSearchBox.ts +++ b/UI/Wikipedia/WikidataSearchBox.ts @@ -6,12 +6,10 @@ import {UIEventSource} from "../../Logic/UIEventSource"; import Wikidata, {WikidataResponse} from "../../Logic/Web/Wikidata"; import Locale from "../i18n/Locale"; import {VariableUiElement} from "../Base/VariableUIElement"; -import {FixedUiElement} from "../Base/FixedUiElement"; import WikidataPreviewBox from "./WikidataPreviewBox"; import Title from "../Base/Title"; import WikipediaBox from "./WikipediaBox"; import Svg from "../../Svg"; -import Link from "../Base/Link"; export default class WikidataSearchBox extends InputElement { @@ -104,7 +102,7 @@ export default class WikidataSearchBox extends InputElement { if (wid === undefined) { return undefined } - return new WikipediaBox([wid]); + return new WikipediaBox(wid.split(";")); })).SetStyle("max-height:12.5rem"), full ]).ConstructElement(); diff --git a/UI/Wikipedia/WikipediaBox.ts b/UI/Wikipedia/WikipediaBox.ts index 0dc059ac0..4c7ba9235 100644 --- a/UI/Wikipedia/WikipediaBox.ts +++ b/UI/Wikipedia/WikipediaBox.ts @@ -22,7 +22,7 @@ export default class WikipediaBox extends Combine { const mainContents = [] - const pages = wikidataIds.map(wdId => WikipediaBox.createLinkedContent(wdId)) + const pages = wikidataIds.map(wdId => WikipediaBox.createLinkedContent(wdId.trim())) if (wikidataIds.length == 1) { const page = pages[0] mainContents.push( @@ -88,6 +88,9 @@ export default class WikipediaBox extends Combine { } const wikidata = maybewikidata["success"] + if(wikidata === undefined){ + return "failed" + } if (wikidata.wikisites.size === 0) { return ["no page", wikidata] } @@ -157,7 +160,7 @@ export default class WikipediaBox extends Combine { } return undefined })) - .SetClass("flex items-center") + .SetClass("flex items-center enable-links") return { contents: contents, diff --git a/assets/layers/etymology/etymology.json b/assets/layers/etymology/etymology.json new file mode 100644 index 000000000..5182f5380 --- /dev/null +++ b/assets/layers/etymology/etymology.json @@ -0,0 +1,138 @@ +{ + "id": "etymology", + "#": "A layer showing all objects having etymology info (either via `name:etymology:wikidata` or `name:etymology`. The intention is that this layer is reused for a certain category to also _ask_ for information", + "name": { + "en": "Has etymolgy", + "nl": "Heeft etymology info" + }, + "minzoom": 12, + "source": { + "osmTags": { + "or": [ + "name:etymology:wikidata~*", + "name:etymology~*" + ] + } + }, + "title": { + "render": { + "*": "{name}" + } + }, + "description": { + "en": "All objects which have an etymology known", + "nl": "Alle lagen met een gelinkt etymology" + }, + "tagRenderings": [ + { + "id": "wikipedia-etymology", + "question": { + "en": "What is the Wikidata-item that this object is named after?", + "nl": "Wat is het Wikidata-item van hetgeen dit object is naar vernoemd?" + }, + "freeform": { + "key": "name:etymology:wikidata", + "type": "wikidata", + "helperArgs": [ + "name", + { + "removePostfixes": [ + "steenweg", + "heirbaan", + "baan", + "straat", + "street", + "weg", + "dreef", + "laan", + "boulevard", + "pad", + "path", + "plein", + "square", + "plaza", + "wegel", + "kerk", + "church", + "kaai" + ] + } + ] + }, + "render": { + "en": "

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}", + "nl": "

Wikipedia artikel van de naamgever

{wikipedia(name:etymology:wikidata):max-height:20rem}" + } + }, + { + "id": "zoeken op inventaris onroerend erfgoed", + "render": { + "nl": "Zoeken op inventaris onroerend erfgoed", + "en": "Search on inventaris onroerend erfgoed" + }, + "conditions": "_country=be" + }, + { + "id": "simple etymology", + "question": { + "en": "What is this object named after?
This might be written on the street name sign", + "nl": "Naar wat is dit object vernoemd?
Dit staat mogelijks vermeld op het straatnaambordje" + }, + "render": { + "en": "Named after {name:etymology}", + "nl": "Vernoemd naar {name:etymology}" + }, + "freeform": { + "key": "name:etymology" + }, + "condition": { + "or": [ + "name:etymology~*", + "name:etymology:wikidata=" + ] + } + }, + { + "id": "street-name-sign-image", + "render": { + "en": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Add image of a street name sign)}", + "nl": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" + } + }, + "wikipedia" + ], + "icon": { + "render": "pin:#05d7fcaa;./assets/layers/etymology/logo.svg", + "mappings": [ + { + "if": { + "and": [ + "name:etymology=", + "name:etymology:wikidata=" + ] + }, + "then": "pin:#fcca05aa;./assets/layers/etymology/logo.svg" + } + ] + }, + "width": { + "render": "8" + }, + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "#05d7fcaa", + "mappings": [ + { + "if": { + "and": [ + "name:etymology=", + "name:etymology:wikidata=" + ] + }, + "then": "#fcca05aa" + } + ] + } +} \ No newline at end of file diff --git a/assets/layers/etymology/license_info.json b/assets/layers/etymology/license_info.json new file mode 100644 index 000000000..d186e73a2 --- /dev/null +++ b/assets/layers/etymology/license_info.json @@ -0,0 +1,10 @@ +[ + { + "path": "logo.svg", + "license": "CC0", + "authors": [ + "Pieter Vander Vennet" + ], + "sources": [] + } +] \ No newline at end of file diff --git a/assets/layers/etymology/logo.svg b/assets/layers/etymology/logo.svg new file mode 100644 index 000000000..6d6c9a0f6 --- /dev/null +++ b/assets/layers/etymology/logo.svg @@ -0,0 +1,107 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/tagRenderings/questions.json b/assets/tagRenderings/questions.json index fc7756492..22edf9199 100644 --- a/assets/tagRenderings/questions.json +++ b/assets/tagRenderings/questions.json @@ -45,7 +45,23 @@ }, "wikipedialink": { "render": "WP", - "condition": "wikipedia~*" + "freeform": { + "key": "wikidata", + "type": "wikidata" + }, + "question": { + "en": "What is the corresponding item on Wikipedia?", + "nl": "Welk Wikipedia-artikel beschrijft dit object?" + }, + "mappings": [ + { + "if": "wikidata=", + "then": { + "en": "Not linked with Wikipedia", + "nl": "Nog geen Wikipedia-artikel bekend" + } + } + ] }, "email": { "render": "{email}", diff --git a/assets/themes/etymology.json b/assets/themes/etymology.json index e71445814..3aa346dc3 100644 --- a/assets/themes/etymology.json +++ b/assets/themes/etymology.json @@ -17,7 +17,7 @@ "nl" ], "maintainer": "", - "icon": "./assets/svg/bug.svg", + "icon": "./assets/layers/etymology/logo.svg", "version": "0", "startLat": 0, "startLon": 0, @@ -25,138 +25,26 @@ "widenFactor": 2, "socialImage": "", "layers": [ + "etymology", { - "id": "has_etymology", - "name": { - "en": "Has etymolgy", - "nl": "Heeft etymology info" - }, - "minzoom": 12, - "source": { - "osmTags": { - "or": [ - "name:etymology:wikidata~*", - "name:etymology~*" - ] - } - }, - "title": { - "render": { - "*": "{name}" - } - }, - "description": { - "en": "All objects which have an etymology known", - "nl": "Alle lagen met een gelinkt etymology" - }, - "tagRenderings": [ - { - "id": "etymology_wikidata_image", - "render": { - "*": "{image_carousel(name:etymology:wikidata)}" - } + "builtin": "etymology", + "override": { + "id": "streets_without_etymology", + "name": { + "en": "Streets without etymology information", + "nl": "Straten zonder etymologische informatie" }, - { - "id": "simple etymology", - "render": { - "en": "Named after {name:etymology}", - "nl": "Vernoemd naar {name:etymology}" - }, - "freeform": { - "key": "name:etymology" - } - }, - { - "id": "wikipedia-etymology", - "render": { - "*": "{wikipedia(name:etymology:wikidata):max-height:30rem}" - } - }, - { - "id": "wikidata-embed", - "render": { - "*": "" - }, - "condition": "name:etymology:wikidata~*" - }, - "wikipedia", - { - "id": "street-name-sign-image", - "render": { - "en": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Add image of a street name sign)}", - "nl": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" + "minzoom": 18, + "source": { + "osmTags": { + "and": [ + "name~*", + "highway~*", + "highway!=bus_stop" + ] } } - ], - "icon": { - "render": "./assets/svg/bug.svg" - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#00f" - }, - "presets": [] - }, - { - "id": "has_a_name", - "name": { - "en": "Has etymolgy", - "nl": "Heeft etymology info" - }, - "minzoom": 12, - "source": { - "osmTags": { - "or": [ - "name:etymology:wikidata~*", - "name:etymology~*" - ] - } - }, - "title": { - "render": { - "*": "{name}" - } - }, - "description": { - "en": "All objects which have an etymology known", - "nl": "Alle lagen met een gelinkt etymology" - }, - "tagRenderings": [ - { - "id": "simple etymology", - "render": { - "en": "Named after {name:etymology}", - "nl": "Vernoemd naar {name:etymology}" - }, - "freeform": { - "key": "name:etymology" - } - }, - { - "id": "wikipedia-etymology", - "render": { - "*": "{wikipedia(name:etymology:wikidata):max-height:20rem}" - } - } - ], - "icon": { - "render": "./assets/svg/bug.svg" - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#00f" - }, - "presets": [] + } } ], "hideFromOverview": true diff --git a/css/index-tailwind-output.css b/css/index-tailwind-output.css index d2b2ec440..69508ef54 100644 --- a/css/index-tailwind-output.css +++ b/css/index-tailwind-output.css @@ -1958,6 +1958,27 @@ li::marker { max-width: 2em !important; } +.block-ruby { + display: block ruby; +} + +.disable-links a { + pointer-events: none; + text-decoration: none !important; + color: var(--subtle-detail-color-contrast) !important; +} + +.enable-links a { + pointer-events: unset; + text-decoration: underline !important; + color: unset !important; +} + +.disable-links a.must-link, .disable-links .must-link a { + /* Hide links if they are disabled */ + display: none; +} + /**************** GENERIC ****************/ .alert { @@ -2237,10 +2258,6 @@ li::marker { } @media (min-width: 640px) { - .sm\:m-1 { - margin: 0.25rem; - } - .sm\:mx-auto { margin-left: auto; margin-right: auto; diff --git a/css/tagrendering.css b/css/tagrendering.css index a87f67a47..6e154e6c1 100644 --- a/css/tagrendering.css +++ b/css/tagrendering.css @@ -20,12 +20,6 @@ height: 100%; } -.question a { - pointer-events: none; - text-decoration: none; - color: var(--subtle-detail-color-contrast) -} - .question-text { font-size: larger; font-weight: bold; diff --git a/css/wikipedia.css b/css/wikipedia.css index e636fb8dc..e261ffbde 100644 --- a/css/wikipedia.css +++ b/css/wikipedia.css @@ -33,6 +33,12 @@ text-decoration: none; } +.disable-links .wikipedia-article a { + color: black !important; + background: none !important; + text-decoration: none; +} + .wikipedia-article p { margin-bottom: 0.5rem; diff --git a/index.css b/index.css index f4e51240a..9111b847d 100644 --- a/index.css +++ b/index.css @@ -243,6 +243,27 @@ li::marker { } +.block-ruby { + display: block ruby; +} + +.disable-links a { + pointer-events: none; + text-decoration: none !important; + color: var(--subtle-detail-color-contrast) !important; +} + +.enable-links a { + pointer-events: unset; + text-decoration: underline !important; + color: unset !important; +} + +.disable-links a.must-link, .disable-links .must-link a { + /* Hide links if they are disabled */ + display: none; +} + /**************** GENERIC ****************/ diff --git a/test.ts b/test.ts index 631d1e061..e2bb93acd 100644 --- a/test.ts +++ b/test.ts @@ -1,6 +1,3 @@ -import WikidataPreviewBox from "./UI/Wikipedia/WikidataPreviewBox"; -import {UIEventSource} from "./Logic/UIEventSource"; -import Wikidata from "./Logic/Web/Wikidata"; -import WikidataSearchBox from "./UI/Wikipedia/WikidataSearchBox"; +import WikipediaBox from "./UI/Wikipedia/WikipediaBox"; -new WikidataSearchBox({searchText: new UIEventSource("Brugge")}).AttachTo("maindiv") \ No newline at end of file +new WikipediaBox(["L614072"]).AttachTo("maindiv") \ No newline at end of file diff --git a/test/Wikidata.spec.test.ts b/test/Wikidata.spec.test.ts index 1bc6a8558..f2a7bb25a 100644 --- a/test/Wikidata.spec.test.ts +++ b/test/Wikidata.spec.test.ts @@ -1881,6 +1881,52 @@ export default class WikidataSpecTest extends T { ) const wikidata = await Wikidata.LoadWikidataEntryAsync("2747456") + }], + ["Extract key from a lexeme", () => { + Utils.injectJsonDownloadForTests( + "https://www.wikidata.org/wiki/Special:EntityData/L614072.json" , + { + "entities": { + "L614072": { + "pageid": 104085278, + "ns": 146, + "title": "Lexeme:L614072", + "lastrevid": 1509989280, + "modified": "2021-10-09T18:43:52Z", + "type": "lexeme", + "id": "L614072", + "lemmas": {"nl": {"language": "nl", "value": "Groen"}}, + "lexicalCategory": "Q34698", + "language": "Q7411", + "claims": {}, + "forms": [], + "senses": [{ + "id": "L614072-S1", + "glosses": {"nl": {"language": "nl", "value": "Nieuw"}}, + "claims": {} + }, { + "id": "L614072-S2", + "glosses": {"nl": {"language": "nl", "value": "Jong"}}, + "claims": {} + }, { + "id": "L614072-S3", + "glosses": {"nl": {"language": "nl", "value": "Pril"}}, + "claims": {} + }] + } + } + } + ) + + const key = Wikidata.ExtractKey("https://www.wikidata.org/wiki/Lexeme:L614072") + T.equals("L614072", key) + + }], + ["Download a lexeme", async () => { + + const response = await Wikidata.LoadWikidataEntryAsync("https://www.wikidata.org/wiki/Lexeme:L614072") + T.isTrue(response !== undefined, "Response is undefined") + }] ]); From 661c606b71399e844151cf9c1b770182cdc84ae7 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sat, 9 Oct 2021 23:24:20 +0200 Subject: [PATCH 14/26] Translation reset --- langs/layers/en.json | 20 ++++++++++++++++++++ langs/layers/nl.json | 20 ++++++++++++++++++++ langs/shared-questions/en.json | 8 ++++++++ langs/shared-questions/nl.json | 8 ++++++++ langs/themes/en.json | 20 ++------------------ langs/themes/nl.json | 20 ++------------------ 6 files changed, 60 insertions(+), 36 deletions(-) diff --git a/langs/layers/en.json b/langs/layers/en.json index ac297439b..2b397fa17 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -2475,6 +2475,26 @@ "render": "Drinking water" } }, + "etymology": { + "description": "All objects which have an etymology known", + "name": "Has etymolgy", + "tagRenderings": { + "simple etymology": { + "question": "What is this object named after?
This might be written on the street name sign", + "render": "Named after {name:etymology}" + }, + "street-name-sign-image": { + "render": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Add image of a street name sign)}" + }, + "wikipedia-etymology": { + "question": "What is the Wikidata-item that this object is named after?", + "render": "

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}" + }, + "zoeken op inventaris onroerend erfgoed": { + "render": "Search on inventaris onroerend erfgoed" + } + } + }, "food": { "filter": { "0": { diff --git a/langs/layers/nl.json b/langs/layers/nl.json index 0ff5387f3..ba9e93be1 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -2421,6 +2421,26 @@ "render": "Drinkbaar water" } }, + "etymology": { + "description": "Alle lagen met een gelinkt etymology", + "name": "Heeft etymology info", + "tagRenderings": { + "simple etymology": { + "question": "Naar wat is dit object vernoemd?
Dit staat mogelijks vermeld op het straatnaambordje", + "render": "Vernoemd naar {name:etymology}" + }, + "street-name-sign-image": { + "render": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" + }, + "wikipedia-etymology": { + "question": "Wat is het Wikidata-item van hetgeen dit object is naar vernoemd?", + "render": "

Wikipedia artikel van de naamgever

{wikipedia(name:etymology:wikidata):max-height:20rem}" + }, + "zoeken op inventaris onroerend erfgoed": { + "render": "Zoeken op inventaris onroerend erfgoed" + } + } + }, "food": { "filter": { "0": { diff --git a/langs/shared-questions/en.json b/langs/shared-questions/en.json index 709534fcc..384d57e97 100644 --- a/langs/shared-questions/en.json +++ b/langs/shared-questions/en.json @@ -78,6 +78,14 @@ } }, "question": "Is this place accessible with a wheelchair?" + }, + "wikipedialink": { + "mappings": { + "0": { + "then": "Not linked with Wikipedia" + } + }, + "question": "What is the corresponding item on Wikipedia?" } } } \ No newline at end of file diff --git a/langs/shared-questions/nl.json b/langs/shared-questions/nl.json index 8c7d6b514..433512603 100644 --- a/langs/shared-questions/nl.json +++ b/langs/shared-questions/nl.json @@ -78,6 +78,14 @@ } }, "question": "Is deze plaats rolstoeltoegankelijk?" + }, + "wikipedialink": { + "mappings": { + "0": { + "then": "Nog geen Wikipedia-artikel bekend" + } + }, + "question": "Welk Wikipedia-artikel beschrijft dit object?" } } } \ No newline at end of file diff --git a/langs/themes/en.json b/langs/themes/en.json index 99694b1f4..cd96da916 100644 --- a/langs/themes/en.json +++ b/langs/themes/en.json @@ -746,25 +746,9 @@ "etymology": { "description": "On this map, you can see what an object is named after. The streets, buildings, ... come from OpenStreetMap which got linked with Wikidata. The information comes from Wpikipedia.", "layers": { - "0": { - "description": "All objects which have an etymology known", - "name": "Has etymolgy", - "tagRenderings": { - "simple etymology": { - "render": "Named after {name:etymology}" - }, - "street-name-sign-image": { - "render": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Add image of a street name sign)}" - } - } - }, "1": { - "description": "All objects which have an etymology known", - "name": "Has etymolgy", - "tagRenderings": { - "simple etymology": { - "render": "Named after {name:etymology}" - } + "override": { + "name": "Streets without etymology information" } } }, diff --git a/langs/themes/nl.json b/langs/themes/nl.json index c8ad880ca..7f5ae4fea 100644 --- a/langs/themes/nl.json +++ b/langs/themes/nl.json @@ -627,25 +627,9 @@ "etymology": { "description": "Op deze kaart zie je waar een plaats naar is vernoemd. De straten, gebouwen, ... komen uit OpenStreetMap, waar een link naar Wikidata werd gelegd. De informatie komt uit wikipedia.", "layers": { - "0": { - "description": "Alle lagen met een gelinkt etymology", - "name": "Heeft etymology info", - "tagRenderings": { - "simple etymology": { - "render": "Vernoemd naar {name:etymology}" - }, - "street-name-sign-image": { - "render": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" - } - } - }, "1": { - "description": "Alle lagen met een gelinkt etymology", - "name": "Heeft etymology info", - "tagRenderings": { - "simple etymology": { - "render": "Vernoemd naar {name:etymology}" - } + "override": { + "name": "Straten zonder etymologische informatie" } } }, From 4d919ec3fbe3ca6e8e28ffeea942a3f017293ba9 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 10 Oct 2021 00:04:49 +0200 Subject: [PATCH 15/26] Add unkown option to etymology --- assets/layers/etymology/etymology.json | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/assets/layers/etymology/etymology.json b/assets/layers/etymology/etymology.json index 5182f5380..70ecdc93d 100644 --- a/assets/layers/etymology/etymology.json +++ b/assets/layers/etymology/etymology.json @@ -62,7 +62,8 @@ "render": { "en": "

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}", "nl": "

Wikipedia artikel van de naamgever

{wikipedia(name:etymology:wikidata):max-height:20rem}" - } + }, + "condition":"name:etymology!=unknown" }, { "id": "zoeken op inventaris onroerend erfgoed", @@ -85,6 +86,13 @@ "freeform": { "key": "name:etymology" }, + "mappings": [ + {"if":"name:etymology=unknown", + "then": { + "en": "The origin of this name is unknown in all literature", + "nl": "De oorsprong van deze naam is onbekend in de literatuur" + }} + ], "condition": { "or": [ "name:etymology~*", @@ -135,4 +143,4 @@ } ] } -} \ No newline at end of file +} From f7dbed7c971923c7ca2c4c224d0fee050cd8996e Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 10 Oct 2021 00:20:38 +0200 Subject: [PATCH 16/26] Add wikidata images to etymology --- assets/layers/etymology/etymology.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/assets/layers/etymology/etymology.json b/assets/layers/etymology/etymology.json index 70ecdc93d..216e9a87d 100644 --- a/assets/layers/etymology/etymology.json +++ b/assets/layers/etymology/etymology.json @@ -24,6 +24,12 @@ "nl": "Alle lagen met een gelinkt etymology" }, "tagRenderings": [ + { + "id":"etymology-images-from-wikipedia", + "render": { + "*": "{image_carousel(name:etymology:wikidata)}" + } + }, { "id": "wikipedia-etymology", "question": { From ed161afc7e5f6600169f0204b08f84ebb9da16d3 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 10 Oct 2021 00:56:08 +0200 Subject: [PATCH 17/26] Formatting, add possibility to link wikipedia in the 'wikipedia'-question --- assets/layers/etymology/etymology.json | 300 +++++++++++++------------ assets/tagRenderings/questions.json | 21 +- 2 files changed, 170 insertions(+), 151 deletions(-) diff --git a/assets/layers/etymology/etymology.json b/assets/layers/etymology/etymology.json index 216e9a87d..5e819a3ee 100644 --- a/assets/layers/etymology/etymology.json +++ b/assets/layers/etymology/etymology.json @@ -1,152 +1,154 @@ { - "id": "etymology", - "#": "A layer showing all objects having etymology info (either via `name:etymology:wikidata` or `name:etymology`. The intention is that this layer is reused for a certain category to also _ask_ for information", - "name": { - "en": "Has etymolgy", - "nl": "Heeft etymology info" - }, - "minzoom": 12, - "source": { - "osmTags": { - "or": [ - "name:etymology:wikidata~*", - "name:etymology~*" - ] - } - }, - "title": { - "render": { - "*": "{name}" - } - }, - "description": { - "en": "All objects which have an etymology known", - "nl": "Alle lagen met een gelinkt etymology" - }, - "tagRenderings": [ - { - "id":"etymology-images-from-wikipedia", - "render": { - "*": "{image_carousel(name:etymology:wikidata)}" - } - }, - { - "id": "wikipedia-etymology", - "question": { - "en": "What is the Wikidata-item that this object is named after?", - "nl": "Wat is het Wikidata-item van hetgeen dit object is naar vernoemd?" - }, - "freeform": { - "key": "name:etymology:wikidata", - "type": "wikidata", - "helperArgs": [ - "name", - { - "removePostfixes": [ - "steenweg", - "heirbaan", - "baan", - "straat", - "street", - "weg", - "dreef", - "laan", - "boulevard", - "pad", - "path", - "plein", - "square", - "plaza", - "wegel", - "kerk", - "church", - "kaai" - ] - } - ] - }, - "render": { - "en": "

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}", - "nl": "

Wikipedia artikel van de naamgever

{wikipedia(name:etymology:wikidata):max-height:20rem}" - }, - "condition":"name:etymology!=unknown" - }, - { - "id": "zoeken op inventaris onroerend erfgoed", - "render": { - "nl": "Zoeken op inventaris onroerend erfgoed", - "en": "Search on inventaris onroerend erfgoed" - }, - "conditions": "_country=be" - }, - { - "id": "simple etymology", - "question": { - "en": "What is this object named after?
This might be written on the street name sign", - "nl": "Naar wat is dit object vernoemd?
Dit staat mogelijks vermeld op het straatnaambordje" - }, - "render": { - "en": "Named after {name:etymology}", - "nl": "Vernoemd naar {name:etymology}" - }, - "freeform": { - "key": "name:etymology" - }, - "mappings": [ - {"if":"name:etymology=unknown", - "then": { - "en": "The origin of this name is unknown in all literature", - "nl": "De oorsprong van deze naam is onbekend in de literatuur" - }} - ], - "condition": { - "or": [ - "name:etymology~*", - "name:etymology:wikidata=" - ] - } - }, - { - "id": "street-name-sign-image", - "render": { - "en": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Add image of a street name sign)}", - "nl": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" - } - }, - "wikipedia" - ], - "icon": { - "render": "pin:#05d7fcaa;./assets/layers/etymology/logo.svg", - "mappings": [ - { - "if": { - "and": [ - "name:etymology=", - "name:etymology:wikidata=" - ] - }, - "then": "pin:#fcca05aa;./assets/layers/etymology/logo.svg" - } - ] - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#05d7fcaa", - "mappings": [ - { - "if": { - "and": [ - "name:etymology=", - "name:etymology:wikidata=" - ] - }, - "then": "#fcca05aa" - } - ] + "id": "etymology", + "#": "A layer showing all objects having etymology info (either via `name:etymology:wikidata` or `name:etymology`. The intention is that this layer is reused for a certain category to also _ask_ for information", + "name": { + "en": "Has etymolgy", + "nl": "Heeft etymology info" + }, + "minzoom": 12, + "source": { + "osmTags": { + "or": [ + "name:etymology:wikidata~*", + "name:etymology~*" + ] } + }, + "title": { + "render": { + "*": "{name}" + } + }, + "description": { + "en": "All objects which have an etymology known", + "nl": "Alle lagen met een gelinkt etymology" + }, + "tagRenderings": [ + { + "id": "etymology-images-from-wikipedia", + "render": { + "*": "{image_carousel(name:etymology:wikidata)}" + } + }, + { + "id": "wikipedia-etymology", + "question": { + "en": "What is the Wikidata-item that this object is named after?", + "nl": "Wat is het Wikidata-item van hetgeen dit object is naar vernoemd?" + }, + "freeform": { + "key": "name:etymology:wikidata", + "type": "wikidata", + "helperArgs": [ + "name", + { + "removePostfixes": [ + "steenweg", + "heirbaan", + "baan", + "straat", + "street", + "weg", + "dreef", + "laan", + "boulevard", + "pad", + "path", + "plein", + "square", + "plaza", + "wegel", + "kerk", + "church", + "kaai" + ] + } + ] + }, + "render": { + "en": "

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}", + "nl": "

Wikipedia artikel van de naamgever

{wikipedia(name:etymology:wikidata):max-height:20rem}" + }, + "condition": "name:etymology!=unknown" + }, + { + "id": "zoeken op inventaris onroerend erfgoed", + "render": { + "nl": "Zoeken op inventaris onroerend erfgoed", + "en": "Search on inventaris onroerend erfgoed" + }, + "conditions": "_country=be" + }, + { + "id": "simple etymology", + "question": { + "en": "What is this object named after?
This might be written on the street name sign", + "nl": "Naar wat is dit object vernoemd?
Dit staat mogelijks vermeld op het straatnaambordje" + }, + "render": { + "en": "Named after {name:etymology}", + "nl": "Vernoemd naar {name:etymology}" + }, + "freeform": { + "key": "name:etymology" + }, + "mappings": [ + { + "if": "name:etymology=unknown", + "then": { + "en": "The origin of this name is unknown in all literature", + "nl": "De oorsprong van deze naam is onbekend in de literatuur" + } + } + ], + "condition": { + "or": [ + "name:etymology~*", + "name:etymology:wikidata=" + ] + } + }, + { + "id": "street-name-sign-image", + "render": { + "en": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Add image of a street name sign)}", + "nl": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" + } + }, + "wikipedia" + ], + "icon": { + "render": "pin:#05d7fcaa;./assets/layers/etymology/logo.svg", + "mappings": [ + { + "if": { + "and": [ + "name:etymology=", + "name:etymology:wikidata=" + ] + }, + "then": "pin:#fcca05aa;./assets/layers/etymology/logo.svg" + } + ] + }, + "width": { + "render": "8" + }, + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "#05d7fcaa", + "mappings": [ + { + "if": { + "and": [ + "name:etymology=", + "name:etymology:wikidata=" + ] + }, + "then": "#fcca05aa" + } + ] + } } diff --git a/assets/tagRenderings/questions.json b/assets/tagRenderings/questions.json index 22edf9199..a317a9645 100644 --- a/assets/tagRenderings/questions.json +++ b/assets/tagRenderings/questions.json @@ -4,7 +4,24 @@ }, "wikipedia": { "render": "{wikipedia():max-height:25rem}", - "condition": "wikidata~*" + "question": { + "en": "What is the corresponding Wikidata entity?", + "nl": "Welk Wikidata-item komt overeen met dit object?" + }, + "freeform": { + "key": "wikidata", + "type": "wikidata" + }, + "mappings": [ + { + "if": "wikidata=", + "then": { + "en": "No Wikipedia page has been linked yet", + "nl": "Er werd nog geen Wikipedia-pagina gekoppeld" + }, + "hideInAnswer": true + } + ] }, "reviews": { "render": "{reviews()}" @@ -50,7 +67,7 @@ "type": "wikidata" }, "question": { - "en": "What is the corresponding item on Wikipedia?", + "en": "What is the corresponding item on Wikipedia?", "nl": "Welk Wikipedia-artikel beschrijft dit object?" }, "mappings": [ From 5f5079ddfe8691614fd779c4536248ba08f97827 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 10 Oct 2021 23:50:50 +0200 Subject: [PATCH 18/26] Fix link to lexemes, fix #507 --- Logic/Web/Wikidata.ts | 9 +++++++++ UI/Wikipedia/WikidataPreviewBox.ts | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Logic/Web/Wikidata.ts b/Logic/Web/Wikidata.ts index c23a5347c..4c9fd5081 100644 --- a/Logic/Web/Wikidata.ts +++ b/Logic/Web/Wikidata.ts @@ -273,6 +273,15 @@ export default class Wikidata { return undefined; } + public static IdToArticle(id: string){ + if(id.startsWith("Q")){ + return "https://wikidata.org/wiki/"+id + } + if(id.startsWith("L")){ + return "https://wikidata.org/wiki/Lexeme:"+id + } + throw "Unknown id type: "+id + } /** * Loads a wikidata page diff --git a/UI/Wikipedia/WikidataPreviewBox.ts b/UI/Wikipedia/WikidataPreviewBox.ts index 3fe01aab8..d6682326b 100644 --- a/UI/Wikipedia/WikidataPreviewBox.ts +++ b/UI/Wikipedia/WikidataPreviewBox.ts @@ -51,7 +51,7 @@ export default class WikidataPreviewBox extends VariableUiElement { wikidata.id, Svg.wikidata_ui().SetStyle("width: 2.5rem").SetClass("block") ]).SetClass("flex"), - "https://wikidata.org/wiki/"+wikidata.id ,true).SetClass("must-link") + Wikidata.IdToArticle(wikidata.id) ,true).SetClass("must-link") console.log(wikidata) let info = new Combine( [ From a2006021faab35c18385ca86356a6b4fae7db74c Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sun, 10 Oct 2021 23:52:53 +0200 Subject: [PATCH 19/26] Formatting, translation sync --- assets/layers/etymology/etymology.json | 294 ++++++++++++------------- langs/layers/en.json | 77 ++++--- langs/layers/nl.json | 77 ++++--- langs/shared-questions/en.json | 8 + langs/shared-questions/nl.json | 8 + 5 files changed, 245 insertions(+), 219 deletions(-) diff --git a/assets/layers/etymology/etymology.json b/assets/layers/etymology/etymology.json index 5e819a3ee..d49b45670 100644 --- a/assets/layers/etymology/etymology.json +++ b/assets/layers/etymology/etymology.json @@ -1,154 +1,154 @@ { - "id": "etymology", - "#": "A layer showing all objects having etymology info (either via `name:etymology:wikidata` or `name:etymology`. The intention is that this layer is reused for a certain category to also _ask_ for information", - "name": { - "en": "Has etymolgy", - "nl": "Heeft etymology info" - }, - "minzoom": 12, - "source": { - "osmTags": { - "or": [ - "name:etymology:wikidata~*", - "name:etymology~*" - ] - } - }, - "title": { - "render": { - "*": "{name}" - } - }, - "description": { - "en": "All objects which have an etymology known", - "nl": "Alle lagen met een gelinkt etymology" - }, - "tagRenderings": [ - { - "id": "etymology-images-from-wikipedia", - "render": { - "*": "{image_carousel(name:etymology:wikidata)}" - } + "id": "etymology", + "#": "A layer showing all objects having etymology info (either via `name:etymology:wikidata` or `name:etymology`. The intention is that this layer is reused for a certain category to also _ask_ for information", + "name": { + "en": "Has etymolgy", + "nl": "Heeft etymology info" }, - { - "id": "wikipedia-etymology", - "question": { - "en": "What is the Wikidata-item that this object is named after?", - "nl": "Wat is het Wikidata-item van hetgeen dit object is naar vernoemd?" - }, - "freeform": { - "key": "name:etymology:wikidata", - "type": "wikidata", - "helperArgs": [ - "name", - { - "removePostfixes": [ - "steenweg", - "heirbaan", - "baan", - "straat", - "street", - "weg", - "dreef", - "laan", - "boulevard", - "pad", - "path", - "plein", - "square", - "plaza", - "wegel", - "kerk", - "church", - "kaai" + "minzoom": 12, + "source": { + "osmTags": { + "or": [ + "name:etymology:wikidata~*", + "name:etymology~*" ] - } - ] - }, - "render": { - "en": "

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}", - "nl": "

Wikipedia artikel van de naamgever

{wikipedia(name:etymology:wikidata):max-height:20rem}" - }, - "condition": "name:etymology!=unknown" - }, - { - "id": "zoeken op inventaris onroerend erfgoed", - "render": { - "nl": "Zoeken op inventaris onroerend erfgoed", - "en": "Search on inventaris onroerend erfgoed" - }, - "conditions": "_country=be" - }, - { - "id": "simple etymology", - "question": { - "en": "What is this object named after?
This might be written on the street name sign", - "nl": "Naar wat is dit object vernoemd?
Dit staat mogelijks vermeld op het straatnaambordje" - }, - "render": { - "en": "Named after {name:etymology}", - "nl": "Vernoemd naar {name:etymology}" - }, - "freeform": { - "key": "name:etymology" - }, - "mappings": [ - { - "if": "name:etymology=unknown", - "then": { - "en": "The origin of this name is unknown in all literature", - "nl": "De oorsprong van deze naam is onbekend in de literatuur" - } } - ], - "condition": { - "or": [ - "name:etymology~*", - "name:etymology:wikidata=" + }, + "title": { + "render": { + "*": "{name}" + } + }, + "description": { + "en": "All objects which have an etymology known", + "nl": "Alle lagen met een gelinkt etymology" + }, + "tagRenderings": [ + { + "id": "etymology-images-from-wikipedia", + "render": { + "*": "{image_carousel(name:etymology:wikidata)}" + } + }, + { + "id": "wikipedia-etymology", + "question": { + "en": "What is the Wikidata-item that this object is named after?", + "nl": "Wat is het Wikidata-item van hetgeen dit object is naar vernoemd?" + }, + "freeform": { + "key": "name:etymology:wikidata", + "type": "wikidata", + "helperArgs": [ + "name", + { + "removePostfixes": [ + "steenweg", + "heirbaan", + "baan", + "straat", + "street", + "weg", + "dreef", + "laan", + "boulevard", + "pad", + "path", + "plein", + "square", + "plaza", + "wegel", + "kerk", + "church", + "kaai" + ] + } + ] + }, + "render": { + "en": "

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}", + "nl": "

Wikipedia artikel van de naamgever

{wikipedia(name:etymology:wikidata):max-height:20rem}" + }, + "condition": "name:etymology!=unknown" + }, + { + "id": "zoeken op inventaris onroerend erfgoed", + "render": { + "nl": "Zoeken op inventaris onroerend erfgoed", + "en": "Search on inventaris onroerend erfgoed" + }, + "conditions": "_country=be" + }, + { + "id": "simple etymology", + "question": { + "en": "What is this object named after?
This might be written on the street name sign", + "nl": "Naar wat is dit object vernoemd?
Dit staat mogelijks vermeld op het straatnaambordje" + }, + "render": { + "en": "Named after {name:etymology}", + "nl": "Vernoemd naar {name:etymology}" + }, + "freeform": { + "key": "name:etymology" + }, + "mappings": [ + { + "if": "name:etymology=unknown", + "then": { + "en": "The origin of this name is unknown in all literature", + "nl": "De oorsprong van deze naam is onbekend in de literatuur" + } + } + ], + "condition": { + "or": [ + "name:etymology~*", + "name:etymology:wikidata=" + ] + } + }, + { + "id": "street-name-sign-image", + "render": { + "en": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Add image of a street name sign)}", + "nl": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" + } + }, + "wikipedia" + ], + "icon": { + "render": "pin:#05d7fcaa;./assets/layers/etymology/logo.svg", + "mappings": [ + { + "if": { + "and": [ + "name:etymology=", + "name:etymology:wikidata=" + ] + }, + "then": "pin:#fcca05aa;./assets/layers/etymology/logo.svg" + } ] - } }, - { - "id": "street-name-sign-image", - "render": { - "en": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Add image of a street name sign)}", - "nl": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" - } + "width": { + "render": "8" }, - "wikipedia" - ], - "icon": { - "render": "pin:#05d7fcaa;./assets/layers/etymology/logo.svg", - "mappings": [ - { - "if": { - "and": [ - "name:etymology=", - "name:etymology:wikidata=" - ] - }, - "then": "pin:#fcca05aa;./assets/layers/etymology/logo.svg" - } - ] - }, - "width": { - "render": "8" - }, - "iconSize": { - "render": "40,40,center" - }, - "color": { - "render": "#05d7fcaa", - "mappings": [ - { - "if": { - "and": [ - "name:etymology=", - "name:etymology:wikidata=" - ] - }, - "then": "#fcca05aa" - } - ] - } -} + "iconSize": { + "render": "40,40,center" + }, + "color": { + "render": "#05d7fcaa", + "mappings": [ + { + "if": { + "and": [ + "name:etymology=", + "name:etymology:wikidata=" + ] + }, + "then": "#fcca05aa" + } + ] + } +} \ No newline at end of file diff --git a/langs/layers/en.json b/langs/layers/en.json index f9b43a8fb..86eac29b2 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -1231,6 +1231,10 @@ "question": "What current do the plugs with
Bosch Active Connect with 3 pins and cable
offer?", "render": "
Bosch Active Connect with 3 pins and cable
outputs at most {socket:bosch_3pin:current}A" }, + "current-15": { + "question": "What current do the plugs with
Bosch Active Connect with 5 pins and cable
offer?", + "render": "
Bosch Active Connect with 5 pins and cable
outputs at most {socket:bosch_5pin:current}A" + }, "current-2": { "mappings": { "0": { @@ -1384,6 +1388,10 @@ "question": "How much plugs of type
Bosch Active Connect with 3 pins and cable
are available here?", "render": "There are {socket:bosch_3pin} plugs of type
Bosch Active Connect with 3 pins and cable
available here" }, + "plugs-15": { + "question": "How much plugs of type
Bosch Active Connect with 5 pins and cable
are available here?", + "render": "There are {socket:bosch_5pin} plugs of type
Bosch Active Connect with 5 pins and cable
available here" + }, "plugs-2": { "question": "How much plugs of type
Chademo
are available here?", "render": "There are {socket:chademo} plugs of type
Chademo
available here" @@ -1489,6 +1497,10 @@ "question": "What power output does a single plug of type
Bosch Active Connect with 3 pins and cable
offer?", "render": "
Bosch Active Connect with 3 pins and cable
outputs at most {socket:bosch_3pin:output}" }, + "power-output-15": { + "question": "What power output does a single plug of type
Bosch Active Connect with 5 pins and cable
offer?", + "render": "
Bosch Active Connect with 5 pins and cable
outputs at most {socket:bosch_5pin:output}" + }, "power-output-2": { "mappings": { "0": { @@ -1662,6 +1674,10 @@ "question": "What voltage do the plugs with
Bosch Active Connect with 3 pins and cable
offer?", "render": "
Bosch Active Connect with 3 pins and cable
outputs {socket:bosch_3pin:voltage} volt" }, + "voltage-15": { + "question": "What voltage do the plugs with
Bosch Active Connect with 5 pins and cable
offer?", + "render": "
Bosch Active Connect with 5 pins and cable
outputs {socket:bosch_5pin:voltage} volt" + }, "voltage-2": { "mappings": { "0": { @@ -1755,22 +1771,6 @@ "website": { "question": "What is the website of the operator?", "render": "More info on {website}" - }, - "voltage-15": { - "question": "What voltage do the plugs with
Bosch Active Connect with 5 pins and cable
offer?", - "render": "
Bosch Active Connect with 5 pins and cable
outputs {socket:bosch_5pin:voltage} volt" - }, - "power-output-15": { - "question": "What power output does a single plug of type
Bosch Active Connect with 5 pins and cable
offer?", - "render": "
Bosch Active Connect with 5 pins and cable
outputs at most {socket:bosch_5pin:output}" - }, - "plugs-15": { - "question": "How much plugs of type
Bosch Active Connect with 5 pins and cable
are available here?", - "render": "There are {socket:bosch_5pin} plugs of type
Bosch Active Connect with 5 pins and cable
available here" - }, - "current-15": { - "question": "What current do the plugs with
Bosch Active Connect with 5 pins and cable
offer?", - "render": "
Bosch Active Connect with 5 pins and cable
outputs at most {socket:bosch_5pin:current}A" } }, "title": { @@ -2500,6 +2500,31 @@ "render": "Drinking water" } }, + "etymology": { + "description": "All objects which have an etymology known", + "name": "Has etymolgy", + "tagRenderings": { + "simple etymology": { + "mappings": { + "0": { + "then": "The origin of this name is unknown in all literature" + } + }, + "question": "What is this object named after?
This might be written on the street name sign", + "render": "Named after {name:etymology}" + }, + "street-name-sign-image": { + "render": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Add image of a street name sign)}" + }, + "wikipedia-etymology": { + "question": "What is the Wikidata-item that this object is named after?", + "render": "

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}" + }, + "zoeken op inventaris onroerend erfgoed": { + "render": "Search on inventaris onroerend erfgoed" + } + } + }, "food": { "filter": { "0": { @@ -3715,25 +3740,5 @@ }, "watermill": { "name": "Watermill" - }, - "etymology": { - "description": "All objects which have an etymology known", - "name": "Has etymolgy", - "tagRenderings": { - "simple etymology": { - "question": "What is this object named after?
This might be written on the street name sign", - "render": "Named after {name:etymology}" - }, - "street-name-sign-image": { - "render": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Add image of a street name sign)}" - }, - "wikipedia-etymology": { - "question": "What is the Wikidata-item that this object is named after?", - "render": "

Wikipedia article of the name giver

{wikipedia(name:etymology:wikidata):max-height:20rem}" - }, - "zoeken op inventaris onroerend erfgoed": { - "render": "Search on inventaris onroerend erfgoed" - } - } } } \ No newline at end of file diff --git a/langs/layers/nl.json b/langs/layers/nl.json index 6533d745a..6bd476a7e 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -1229,6 +1229,10 @@ "question": "Welke stroom levert de stekker van type
Bosch Active Connect met 3 pinnen aan een kabel
?", "render": "
Bosch Active Connect met 3 pinnen aan een kabel
levert een stroom van maximaal {socket:bosch_3pin:current}A" }, + "current-15": { + "question": "Welke stroom levert de stekker van type
Bosch Active Connect met 5 pinnen aan een kabel
?", + "render": "
Bosch Active Connect met 5 pinnen aan een kabel
levert een stroom van maximaal {socket:bosch_5pin:current}A" + }, "current-2": { "mappings": { "0": { @@ -1374,6 +1378,10 @@ "question": "Hoeveel stekkers van type
Bosch Active Connect met 3 pinnen aan een kabel
heeft dit oplaadpunt?", "render": "Hier zijn {socket:bosch_3pin} stekkers van het type
Bosch Active Connect met 3 pinnen aan een kabel
" }, + "plugs-15": { + "question": "Hoeveel stekkers van type
Bosch Active Connect met 5 pinnen aan een kabel
heeft dit oplaadpunt?", + "render": "Hier zijn {socket:bosch_5pin} stekkers van het type
Bosch Active Connect met 5 pinnen aan een kabel
" + }, "plugs-2": { "question": "Hoeveel stekkers van type
Chademo
heeft dit oplaadpunt?", "render": "Hier zijn {socket:chademo} stekkers van het type
Chademo
" @@ -1479,6 +1487,10 @@ "question": "Welk vermogen levert een enkele stekker van type
Bosch Active Connect met 3 pinnen aan een kabel
?", "render": "
Bosch Active Connect met 3 pinnen aan een kabel
levert een vermogen van maximaal {socket:bosch_3pin:output}" }, + "power-output-15": { + "question": "Welk vermogen levert een enkele stekker van type
Bosch Active Connect met 5 pinnen aan een kabel
?", + "render": "
Bosch Active Connect met 5 pinnen aan een kabel
levert een vermogen van maximaal {socket:bosch_5pin:output}" + }, "power-output-2": { "mappings": { "0": { @@ -1648,6 +1660,10 @@ "question": "Welke spanning levert de stekker van type
Bosch Active Connect met 3 pinnen aan een kabel
", "render": "
Bosch Active Connect met 3 pinnen aan een kabel
heeft een spanning van {socket:bosch_3pin:voltage} volt" }, + "voltage-15": { + "question": "Welke spanning levert de stekker van type
Bosch Active Connect met 5 pinnen aan een kabel
", + "render": "
Bosch Active Connect met 5 pinnen aan een kabel
heeft een spanning van {socket:bosch_5pin:voltage} volt" + }, "voltage-2": { "mappings": { "0": { @@ -1737,22 +1753,6 @@ }, "question": "Welke spanning levert de stekker van type
Type 2 met kabel (J1772)
", "render": "
Type 2 met kabel (J1772)
heeft een spanning van {socket:type2_cable:voltage} volt" - }, - "voltage-15": { - "question": "Welke spanning levert de stekker van type
Bosch Active Connect met 5 pinnen aan een kabel
", - "render": "
Bosch Active Connect met 5 pinnen aan een kabel
heeft een spanning van {socket:bosch_5pin:voltage} volt" - }, - "power-output-15": { - "question": "Welk vermogen levert een enkele stekker van type
Bosch Active Connect met 5 pinnen aan een kabel
?", - "render": "
Bosch Active Connect met 5 pinnen aan een kabel
levert een vermogen van maximaal {socket:bosch_5pin:output}" - }, - "plugs-15": { - "question": "Hoeveel stekkers van type
Bosch Active Connect met 5 pinnen aan een kabel
heeft dit oplaadpunt?", - "render": "Hier zijn {socket:bosch_5pin} stekkers van het type
Bosch Active Connect met 5 pinnen aan een kabel
" - }, - "current-15": { - "question": "Welke stroom levert de stekker van type
Bosch Active Connect met 5 pinnen aan een kabel
?", - "render": "
Bosch Active Connect met 5 pinnen aan een kabel
levert een stroom van maximaal {socket:bosch_5pin:current}A" } }, "units": { @@ -2446,6 +2446,31 @@ "render": "Drinkbaar water" } }, + "etymology": { + "description": "Alle lagen met een gelinkt etymology", + "name": "Heeft etymology info", + "tagRenderings": { + "simple etymology": { + "mappings": { + "0": { + "then": "De oorsprong van deze naam is onbekend in de literatuur" + } + }, + "question": "Naar wat is dit object vernoemd?
Dit staat mogelijks vermeld op het straatnaambordje", + "render": "Vernoemd naar {name:etymology}" + }, + "street-name-sign-image": { + "render": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" + }, + "wikipedia-etymology": { + "question": "Wat is het Wikidata-item van hetgeen dit object is naar vernoemd?", + "render": "

Wikipedia artikel van de naamgever

{wikipedia(name:etymology:wikidata):max-height:20rem}" + }, + "zoeken op inventaris onroerend erfgoed": { + "render": "Zoeken op inventaris onroerend erfgoed" + } + } + }, "food": { "filter": { "0": { @@ -4077,25 +4102,5 @@ }, "render": "Watermolens" } - }, - "etymology": { - "description": "Alle lagen met een gelinkt etymology", - "name": "Heeft etymology info", - "tagRenderings": { - "simple etymology": { - "question": "Naar wat is dit object vernoemd?
Dit staat mogelijks vermeld op het straatnaambordje", - "render": "Vernoemd naar {name:etymology}" - }, - "street-name-sign-image": { - "render": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" - }, - "wikipedia-etymology": { - "question": "Wat is het Wikidata-item van hetgeen dit object is naar vernoemd?", - "render": "

Wikipedia artikel van de naamgever

{wikipedia(name:etymology:wikidata):max-height:20rem}" - }, - "zoeken op inventaris onroerend erfgoed": { - "render": "Zoeken op inventaris onroerend erfgoed" - } - } } } \ No newline at end of file diff --git a/langs/shared-questions/en.json b/langs/shared-questions/en.json index 384d57e97..0de90284a 100644 --- a/langs/shared-questions/en.json +++ b/langs/shared-questions/en.json @@ -79,6 +79,14 @@ }, "question": "Is this place accessible with a wheelchair?" }, + "wikipedia": { + "mappings": { + "0": { + "then": "No Wikipedia page has been linked yet" + } + }, + "question": "What is the corresponding Wikidata entity?" + }, "wikipedialink": { "mappings": { "0": { diff --git a/langs/shared-questions/nl.json b/langs/shared-questions/nl.json index 433512603..f3345bcb7 100644 --- a/langs/shared-questions/nl.json +++ b/langs/shared-questions/nl.json @@ -79,6 +79,14 @@ }, "question": "Is deze plaats rolstoeltoegankelijk?" }, + "wikipedia": { + "mappings": { + "0": { + "then": "Er werd nog geen Wikipedia-pagina gekoppeld" + } + }, + "question": "Welk Wikidata-item komt overeen met dit object?" + }, "wikipedialink": { "mappings": { "0": { From f3aea74df5b3da4b953a14c2a6e2ad55c5523897 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 11 Oct 2021 23:41:55 +0200 Subject: [PATCH 20/26] Fix import --- UI/SpecialVisualizations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index 7c0092fe2..af9a2aa88 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -26,7 +26,7 @@ import StaticFeatureSource from "../Logic/FeatureSource/Sources/StaticFeatureSou import ShowDataMultiLayer from "./ShowDataLayer/ShowDataMultiLayer"; import Minimap from "./Base/Minimap"; import AllImageProviders from "../Logic/ImageProviders/AllImageProviders"; -import WikipediaBox from "./WikipediaBox"; +import WikipediaBox from "./Wikipedia/WikipediaBox"; import SimpleMetaTagger from "../Logic/SimpleMetaTagger"; export interface SpecialVisualization { From 253069b534b5195c2e5cc947c8ab398461c1ccfe Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Mon, 11 Oct 2021 23:52:17 +0200 Subject: [PATCH 21/26] Add new taginfo project files --- Customizations/AllKnownLayers.ts | 1 + Customizations/AllKnownLayouts.ts | 1 + Docs/TagInfo/mapcomplete_benches.json | 19 - Docs/TagInfo/mapcomplete_binoculars.json | 19 - Docs/TagInfo/mapcomplete_cafes_and_pubs.json | 20 + .../mapcomplete_charging_stations.json | 474 +++++++++++++++--- Docs/TagInfo/mapcomplete_cyclofix.json | 4 - Docs/TagInfo/mapcomplete_food.json | 20 + Docs/TagInfo/mapcomplete_fritures.json | 40 ++ Docs/TagInfo/mapcomplete_hackerspaces.json | 2 +- Docs/TagInfo/mapcomplete_nature.json | 6 +- .../mapcomplete_observation_towers.json | 24 +- Docs/TagInfo/mapcomplete_parkings.json | 91 +--- Docs/TagInfo/mapcomplete_postboxes.json | 65 +++ Docs/TagInfo/mapcomplete_toilets.json | 33 +- 15 files changed, 575 insertions(+), 244 deletions(-) create mode 100644 Docs/TagInfo/mapcomplete_postboxes.json diff --git a/Customizations/AllKnownLayers.ts b/Customizations/AllKnownLayers.ts index d6e7cb636..2335fe710 100644 --- a/Customizations/AllKnownLayers.ts +++ b/Customizations/AllKnownLayers.ts @@ -13,6 +13,7 @@ export default class AllKnownLayers { const sharedLayers = new Map(); for (const layer of known_layers.layers) { try { + // @ts-ignore const parsed = new LayerConfig(layer, "shared_layers") sharedLayers.set(layer.id, parsed); sharedLayers[layer.id] = parsed; diff --git a/Customizations/AllKnownLayouts.ts b/Customizations/AllKnownLayouts.ts index 57dbbf0ba..f5695d70b 100644 --- a/Customizations/AllKnownLayouts.ts +++ b/Customizations/AllKnownLayouts.ts @@ -63,6 +63,7 @@ export class AllKnownLayouts { private static AllLayouts(): Map { const dict: Map = new Map(); for (const layoutConfigJson of known_themes.themes) { + // @ts-ignore const layout = new LayoutConfig(layoutConfigJson, true) if (layout.id === "cyclofix") { diff --git a/Docs/TagInfo/mapcomplete_benches.json b/Docs/TagInfo/mapcomplete_benches.json index 8a3aff6a9..31b671d8e 100644 --- a/Docs/TagInfo/mapcomplete_benches.json +++ b/Docs/TagInfo/mapcomplete_benches.json @@ -140,25 +140,6 @@ "description": "Layer 'Benches' shows survey:date= with a fixed text, namely 'Surveyed today!' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Benches') Picking this answer will delete the key survey:date.", "value": "" }, - { - "key": "service:bicycle:cleaning:charge", - "description": "Layer 'Benches' shows and asks freeform values for key 'service:bicycle:cleaning:charge' (in the MapComplete.osm.be theme 'Benches')" - }, - { - "key": "service:bicycle:cleaning:fee", - "description": "Layer 'Benches' shows service:bicycle:cleaning:fee=no&service:bicycle:cleaning:charge= with a fixed text, namely 'The cleaning service is free to use' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Benches')", - "value": "no&service:bicycle:cleaning:charge=" - }, - { - "key": "service:bicycle:cleaning:fee", - "description": "Layer 'Benches' shows service:bicycle:cleaning:fee=no& with a fixed text, namely 'Free to use' (in the MapComplete.osm.be theme 'Benches')", - "value": "no&" - }, - { - "key": "service:bicycle:cleaning:fee", - "description": "Layer 'Benches' shows service:bicycle:cleaning:fee=yes with a fixed text, namely 'The cleaning service has a fee' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Benches')", - "value": "yes" - }, { "key": "bench", "description": "The MapComplete theme Benches has a layer Benches at public transport stops showing features with this tag", diff --git a/Docs/TagInfo/mapcomplete_binoculars.json b/Docs/TagInfo/mapcomplete_binoculars.json index 0539d1e6b..8b9686cc6 100644 --- a/Docs/TagInfo/mapcomplete_binoculars.json +++ b/Docs/TagInfo/mapcomplete_binoculars.json @@ -48,25 +48,6 @@ { "key": "direction", "description": "Layer 'Binoculars' shows and asks freeform values for key 'direction' (in the MapComplete.osm.be theme 'Binoculars')" - }, - { - "key": "service:bicycle:cleaning:charge", - "description": "Layer 'Binoculars' shows and asks freeform values for key 'service:bicycle:cleaning:charge' (in the MapComplete.osm.be theme 'Binoculars')" - }, - { - "key": "service:bicycle:cleaning:fee", - "description": "Layer 'Binoculars' shows service:bicycle:cleaning:fee=no&service:bicycle:cleaning:charge= with a fixed text, namely 'The cleaning service is free to use' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Binoculars')", - "value": "no&service:bicycle:cleaning:charge=" - }, - { - "key": "service:bicycle:cleaning:fee", - "description": "Layer 'Binoculars' shows service:bicycle:cleaning:fee=no& with a fixed text, namely 'Free to use' (in the MapComplete.osm.be theme 'Binoculars')", - "value": "no&" - }, - { - "key": "service:bicycle:cleaning:fee", - "description": "Layer 'Binoculars' shows service:bicycle:cleaning:fee=yes with a fixed text, namely 'The cleaning service has a fee' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Binoculars')", - "value": "yes" } ] } \ No newline at end of file diff --git a/Docs/TagInfo/mapcomplete_cafes_and_pubs.json b/Docs/TagInfo/mapcomplete_cafes_and_pubs.json index 2f05a486f..630d8e52b 100644 --- a/Docs/TagInfo/mapcomplete_cafes_and_pubs.json +++ b/Docs/TagInfo/mapcomplete_cafes_and_pubs.json @@ -120,6 +120,26 @@ "key": "wheelchair", "description": "Layer 'Cafés and pubs' shows wheelchair=no with a fixed text, namely 'This place is not reachable with a wheelchair' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Cafés and pubs')", "value": "no" + }, + { + "key": "dog", + "description": "Layer 'Cafés and pubs' shows dog=yes with a fixed text, namely 'Dogs are allowed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Cafés and pubs')", + "value": "yes" + }, + { + "key": "dog", + "description": "Layer 'Cafés and pubs' shows dog=no with a fixed text, namely 'Dogs are not allowed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Cafés and pubs')", + "value": "no" + }, + { + "key": "dog", + "description": "Layer 'Cafés and pubs' shows dog=leashed with a fixed text, namely 'Dogs are allowed, but they have to be leashed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Cafés and pubs')", + "value": "leashed" + }, + { + "key": "dog", + "description": "Layer 'Cafés and pubs' shows dog=unleashed with a fixed text, namely 'Dogs are allowed and can run around freely' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Cafés and pubs')", + "value": "unleashed" } ] } \ No newline at end of file diff --git a/Docs/TagInfo/mapcomplete_charging_stations.json b/Docs/TagInfo/mapcomplete_charging_stations.json index 22ca1d0a4..6cd7b7772 100644 --- a/Docs/TagInfo/mapcomplete_charging_stations.json +++ b/Docs/TagInfo/mapcomplete_charging_stations.json @@ -106,84 +106,147 @@ }, { "key": "socket:schuko", - "description": "Layer 'Charging stations' shows socket:schuko=1 with a fixed text, namely ' Schuko wall plug without ground pin (CEE7/4 type F)' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:schuko=1 with a fixed text, namely '
Schuko wall plug without ground pin (CEE7/4 type F)
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "1" }, { "key": "socket:schuko", - "description": "Layer 'Charging stations' shows socket:schuko~^..*$&socket:schuko!~^1$ with a fixed text, namely ' Schuko wall plug without ground pin (CEE7/4 type F)' (in the MapComplete.osm.be theme 'Charging stations')" + "description": "Layer 'Charging stations' shows socket:schuko~^..*$&socket:schuko!~^1$ with a fixed text, namely '
Schuko wall plug without ground pin (CEE7/4 type F)
' (in the MapComplete.osm.be theme 'Charging stations')" }, { "key": "socket:typee", - "description": "Layer 'Charging stations' shows socket:typee=1 with a fixed text, namely ' European wall plug with ground pin (CEE7/4 type E)' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:typee=1 with a fixed text, namely '
European wall plug with ground pin (CEE7/4 type E)
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "1" }, { "key": "socket:typee", - "description": "Layer 'Charging stations' shows socket:typee~^..*$&socket:typee!~^1$ with a fixed text, namely ' European wall plug with ground pin (CEE7/4 type E)' (in the MapComplete.osm.be theme 'Charging stations')" + "description": "Layer 'Charging stations' shows socket:typee~^..*$&socket:typee!~^1$ with a fixed text, namely '
European wall plug with ground pin (CEE7/4 type E)
' (in the MapComplete.osm.be theme 'Charging stations')" }, { "key": "socket:chademo", - "description": "Layer 'Charging stations' shows socket:chademo=1 with a fixed text, namely ' Chademo' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:chademo=1 with a fixed text, namely '
Chademo
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "1" }, { "key": "socket:chademo", - "description": "Layer 'Charging stations' shows socket:chademo~^..*$&socket:chademo!~^1$ with a fixed text, namely ' Chademo' (in the MapComplete.osm.be theme 'Charging stations')" + "description": "Layer 'Charging stations' shows socket:chademo~^..*$&socket:chademo!~^1$ with a fixed text, namely '
Chademo
' (in the MapComplete.osm.be theme 'Charging stations')" }, { "key": "socket:type1_cable", - "description": "Layer 'Charging stations' shows socket:type1_cable=1 with a fixed text, namely ' Type 1 with cable (J1772)' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:type1_cable=1 with a fixed text, namely '
Type 1 with cable (J1772)
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "1" }, { "key": "socket:type1_cable", - "description": "Layer 'Charging stations' shows socket:type1_cable~^..*$&socket:type1_cable!~^1$ with a fixed text, namely ' Type 1 with cable (J1772)' (in the MapComplete.osm.be theme 'Charging stations')" + "description": "Layer 'Charging stations' shows socket:type1_cable~^..*$&socket:type1_cable!~^1$ with a fixed text, namely '
Type 1 with cable (J1772)
' (in the MapComplete.osm.be theme 'Charging stations')" }, { "key": "socket:type1", - "description": "Layer 'Charging stations' shows socket:type1=1 with a fixed text, namely ' Type 1 without cable (J1772)' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:type1=1 with a fixed text, namely '
Type 1 without cable (J1772)
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "1" }, { "key": "socket:type1", - "description": "Layer 'Charging stations' shows socket:type1~^..*$&socket:type1!~^1$ with a fixed text, namely ' Type 1 without cable (J1772)' (in the MapComplete.osm.be theme 'Charging stations')" + "description": "Layer 'Charging stations' shows socket:type1~^..*$&socket:type1!~^1$ with a fixed text, namely '
Type 1 without cable (J1772)
' (in the MapComplete.osm.be theme 'Charging stations')" }, { "key": "socket:type1_combo", - "description": "Layer 'Charging stations' shows socket:type1_combo=1 with a fixed text, namely ' Type 1 CCS (aka Type 1 Combo)' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:type1_combo=1 with a fixed text, namely '
Type 1 CCS (aka Type 1 Combo)
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "1" }, { "key": "socket:type1_combo", - "description": "Layer 'Charging stations' shows socket:type1_combo~^..*$&socket:type1_combo!~^1$ with a fixed text, namely ' Type 1 CCS (aka Type 1 Combo)' (in the MapComplete.osm.be theme 'Charging stations')" + "description": "Layer 'Charging stations' shows socket:type1_combo~^..*$&socket:type1_combo!~^1$ with a fixed text, namely '
Type 1 CCS (aka Type 1 Combo)
' (in the MapComplete.osm.be theme 'Charging stations')" }, { "key": "socket:tesla_supercharger", - "description": "Layer 'Charging stations' shows socket:tesla_supercharger=1 with a fixed text, namely ' Tesla Supercharger' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:tesla_supercharger=1 with a fixed text, namely '
Tesla Supercharger
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "1" }, { "key": "socket:tesla_supercharger", - "description": "Layer 'Charging stations' shows socket:tesla_supercharger~^..*$&socket:tesla_supercharger!~^1$ with a fixed text, namely ' Tesla Supercharger' (in the MapComplete.osm.be theme 'Charging stations')" + "description": "Layer 'Charging stations' shows socket:tesla_supercharger~^..*$&socket:tesla_supercharger!~^1$ with a fixed text, namely '
Tesla Supercharger
' (in the MapComplete.osm.be theme 'Charging stations')" }, { "key": "socket:type2", - "description": "Layer 'Charging stations' shows socket:type2=1 with a fixed text, namely ' Type 2 (mennekes)' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:type2=1 with a fixed text, namely '
Type 2 (mennekes)
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "1" }, { "key": "socket:type2", - "description": "Layer 'Charging stations' shows socket:type2~^..*$&socket:type2!~^1$ with a fixed text, namely ' Type 2 (mennekes)' (in the MapComplete.osm.be theme 'Charging stations')" + "description": "Layer 'Charging stations' shows socket:type2~^..*$&socket:type2!~^1$ with a fixed text, namely '
Type 2 (mennekes)
' (in the MapComplete.osm.be theme 'Charging stations')" }, { "key": "socket:type2_combo", - "description": "Layer 'Charging stations' shows socket:type2_combo=1 with a fixed text, namely ' Type 2 CCS (mennekes)' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:type2_combo=1 with a fixed text, namely '
Type 2 CCS (mennekes)
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "1" }, { "key": "socket:type2_combo", - "description": "Layer 'Charging stations' shows socket:type2_combo~^..*$&socket:type2_combo!~^1$ with a fixed text, namely ' Type 2 CCS (mennekes)' (in the MapComplete.osm.be theme 'Charging stations')" + "description": "Layer 'Charging stations' shows socket:type2_combo~^..*$&socket:type2_combo!~^1$ with a fixed text, namely '
Type 2 CCS (mennekes)
' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:type2_cable", + "description": "Layer 'Charging stations' shows socket:type2_cable=1 with a fixed text, namely '
Type 2 with cable (mennekes)
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "1" + }, + { + "key": "socket:type2_cable", + "description": "Layer 'Charging stations' shows socket:type2_cable~^..*$&socket:type2_cable!~^1$ with a fixed text, namely '
Type 2 with cable (mennekes)
' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:tesla_supercharger_ccs", + "description": "Layer 'Charging stations' shows socket:tesla_supercharger_ccs=1 with a fixed text, namely '
Tesla Supercharger CCS (a branded type2_css)
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "1" + }, + { + "key": "socket:tesla_supercharger_ccs", + "description": "Layer 'Charging stations' shows socket:tesla_supercharger_ccs~^..*$&socket:tesla_supercharger_ccs!~^1$ with a fixed text, namely '
Tesla Supercharger CCS (a branded type2_css)
' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:tesla_destination", + "description": "Layer 'Charging stations' shows socket:tesla_destination=1 with a fixed text, namely '
Tesla Supercharger (destination)
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "1" + }, + { + "key": "socket:tesla_destination", + "description": "Layer 'Charging stations' shows socket:tesla_destination~^..*$&socket:tesla_destination!~^1$ with a fixed text, namely '
Tesla Supercharger (destination)
' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:tesla_destination", + "description": "Layer 'Charging stations' shows socket:tesla_destination=1 with a fixed text, namely '
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "1" + }, + { + "key": "socket:tesla_destination", + "description": "Layer 'Charging stations' shows socket:tesla_destination~^..*$&socket:tesla_destination!~^1$ with a fixed text, namely '
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:USB-A", + "description": "Layer 'Charging stations' shows socket:USB-A=1 with a fixed text, namely '
USB to charge phones and small electronics
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "1" + }, + { + "key": "socket:USB-A", + "description": "Layer 'Charging stations' shows socket:USB-A~^..*$&socket:USB-A!~^1$ with a fixed text, namely '
USB to charge phones and small electronics
' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:bosch_3pin", + "description": "Layer 'Charging stations' shows socket:bosch_3pin=1 with a fixed text, namely '
Bosch Active Connect with 3 pins and cable
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "1" + }, + { + "key": "socket:bosch_3pin", + "description": "Layer 'Charging stations' shows socket:bosch_3pin~^..*$&socket:bosch_3pin!~^1$ with a fixed text, namely '
Bosch Active Connect with 3 pins and cable
' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:bosch_5pin", + "description": "Layer 'Charging stations' shows socket:bosch_5pin=1 with a fixed text, namely '
Bosch Active Connect with 5 pins and cable
' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "1" + }, + { + "key": "socket:bosch_5pin", + "description": "Layer 'Charging stations' shows socket:bosch_5pin~^..*$&socket:bosch_5pin!~^1$ with a fixed text, namely '
Bosch Active Connect with 5 pins and cable
' (in the MapComplete.osm.be theme 'Charging stations')" }, { "key": "socket:schuko", @@ -195,7 +258,7 @@ }, { "key": "socket:socket:schuko:voltage", - "description": "Layer 'Charging stations' shows socket:socket:schuko:voltage=230 V with a fixed text, namely 'Schuko wall plug without ground pin (CEE7/4 type F) outputs 230 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:schuko:voltage=230 V with a fixed text, namely '
Schuko wall plug without ground pin (CEE7/4 type F)
outputs 230 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "230 V" }, { @@ -204,7 +267,7 @@ }, { "key": "socket:socket:schuko:current", - "description": "Layer 'Charging stations' shows socket:socket:schuko:current=16 A with a fixed text, namely 'Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 16 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:schuko:current=16 A with a fixed text, namely '
Schuko wall plug without ground pin (CEE7/4 type F)
outputs at most 16 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "16 A" }, { @@ -213,7 +276,7 @@ }, { "key": "socket:socket:schuko:output", - "description": "Layer 'Charging stations' shows socket:socket:schuko:output=3.6 kw with a fixed text, namely 'Schuko wall plug without ground pin (CEE7/4 type F) outputs at most 3.6 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:schuko:output=3.6 kw with a fixed text, namely '
Schuko wall plug without ground pin (CEE7/4 type F)
outputs at most 3.6 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "3.6 kw" }, { @@ -226,7 +289,7 @@ }, { "key": "socket:socket:typee:voltage", - "description": "Layer 'Charging stations' shows socket:socket:typee:voltage=230 V with a fixed text, namely 'European wall plug with ground pin (CEE7/4 type E) outputs 230 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:typee:voltage=230 V with a fixed text, namely '
European wall plug with ground pin (CEE7/4 type E)
outputs 230 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "230 V" }, { @@ -235,7 +298,7 @@ }, { "key": "socket:socket:typee:current", - "description": "Layer 'Charging stations' shows socket:socket:typee:current=16 A with a fixed text, namely 'European wall plug with ground pin (CEE7/4 type E) outputs at most 16 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:typee:current=16 A with a fixed text, namely '
European wall plug with ground pin (CEE7/4 type E)
outputs at most 16 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "16 A" }, { @@ -244,12 +307,12 @@ }, { "key": "socket:socket:typee:output", - "description": "Layer 'Charging stations' shows socket:socket:typee:output=3 kw with a fixed text, namely 'European wall plug with ground pin (CEE7/4 type E) outputs at most 3 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:typee:output=3 kw with a fixed text, namely '
European wall plug with ground pin (CEE7/4 type E)
outputs at most 3 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "3 kw" }, { "key": "socket:socket:typee:output", - "description": "Layer 'Charging stations' shows socket:socket:typee:output=22 kw with a fixed text, namely 'European wall plug with ground pin (CEE7/4 type E) outputs at most 22 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:typee:output=22 kw with a fixed text, namely '
European wall plug with ground pin (CEE7/4 type E)
outputs at most 22 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "22 kw" }, { @@ -262,7 +325,7 @@ }, { "key": "socket:socket:chademo:voltage", - "description": "Layer 'Charging stations' shows socket:socket:chademo:voltage=500 V with a fixed text, namely 'Chademo outputs 500 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:chademo:voltage=500 V with a fixed text, namely '
Chademo
outputs 500 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "500 V" }, { @@ -271,7 +334,7 @@ }, { "key": "socket:socket:chademo:current", - "description": "Layer 'Charging stations' shows socket:socket:chademo:current=120 A with a fixed text, namely 'Chademo outputs at most 120 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:chademo:current=120 A with a fixed text, namely '
Chademo
outputs at most 120 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "120 A" }, { @@ -280,7 +343,7 @@ }, { "key": "socket:socket:chademo:output", - "description": "Layer 'Charging stations' shows socket:socket:chademo:output=50 kw with a fixed text, namely 'Chademo outputs at most 50 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:chademo:output=50 kw with a fixed text, namely '
Chademo
outputs at most 50 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "50 kw" }, { @@ -293,12 +356,12 @@ }, { "key": "socket:socket:type1_cable:voltage", - "description": "Layer 'Charging stations' shows socket:socket:type1_cable:voltage=200 V with a fixed text, namely 'Type 1 with cable (J1772) outputs 200 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1_cable:voltage=200 V with a fixed text, namely '
Type 1 with cable (J1772)
outputs 200 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "200 V" }, { "key": "socket:socket:type1_cable:voltage", - "description": "Layer 'Charging stations' shows socket:socket:type1_cable:voltage=240 V with a fixed text, namely 'Type 1 with cable (J1772) outputs 240 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1_cable:voltage=240 V with a fixed text, namely '
Type 1 with cable (J1772)
outputs 240 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "240 V" }, { @@ -307,7 +370,7 @@ }, { "key": "socket:socket:type1_cable:current", - "description": "Layer 'Charging stations' shows socket:socket:type1_cable:current=32 A with a fixed text, namely 'Type 1 with cable (J1772) outputs at most 32 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1_cable:current=32 A with a fixed text, namely '
Type 1 with cable (J1772)
outputs at most 32 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "32 A" }, { @@ -316,12 +379,12 @@ }, { "key": "socket:socket:type1_cable:output", - "description": "Layer 'Charging stations' shows socket:socket:type1_cable:output=3.7 kw with a fixed text, namely 'Type 1 with cable (J1772) outputs at most 3.7 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1_cable:output=3.7 kw with a fixed text, namely '
Type 1 with cable (J1772)
outputs at most 3.7 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "3.7 kw" }, { "key": "socket:socket:type1_cable:output", - "description": "Layer 'Charging stations' shows socket:socket:type1_cable:output=7 kw with a fixed text, namely 'Type 1 with cable (J1772) outputs at most 7 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1_cable:output=7 kw with a fixed text, namely '
Type 1 with cable (J1772)
outputs at most 7 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "7 kw" }, { @@ -334,12 +397,12 @@ }, { "key": "socket:socket:type1:voltage", - "description": "Layer 'Charging stations' shows socket:socket:type1:voltage=200 V with a fixed text, namely 'Type 1 without cable (J1772) outputs 200 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1:voltage=200 V with a fixed text, namely '
Type 1 without cable (J1772)
outputs 200 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "200 V" }, { "key": "socket:socket:type1:voltage", - "description": "Layer 'Charging stations' shows socket:socket:type1:voltage=240 V with a fixed text, namely 'Type 1 without cable (J1772) outputs 240 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1:voltage=240 V with a fixed text, namely '
Type 1 without cable (J1772)
outputs 240 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "240 V" }, { @@ -348,7 +411,7 @@ }, { "key": "socket:socket:type1:current", - "description": "Layer 'Charging stations' shows socket:socket:type1:current=32 A with a fixed text, namely 'Type 1 without cable (J1772) outputs at most 32 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1:current=32 A with a fixed text, namely '
Type 1 without cable (J1772)
outputs at most 32 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "32 A" }, { @@ -357,22 +420,22 @@ }, { "key": "socket:socket:type1:output", - "description": "Layer 'Charging stations' shows socket:socket:type1:output=3.7 kw with a fixed text, namely 'Type 1 without cable (J1772) outputs at most 3.7 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1:output=3.7 kw with a fixed text, namely '
Type 1 without cable (J1772)
outputs at most 3.7 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "3.7 kw" }, { "key": "socket:socket:type1:output", - "description": "Layer 'Charging stations' shows socket:socket:type1:output=6.6 kw with a fixed text, namely 'Type 1 without cable (J1772) outputs at most 6.6 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1:output=6.6 kw with a fixed text, namely '
Type 1 without cable (J1772)
outputs at most 6.6 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "6.6 kw" }, { "key": "socket:socket:type1:output", - "description": "Layer 'Charging stations' shows socket:socket:type1:output=7 kw with a fixed text, namely 'Type 1 without cable (J1772) outputs at most 7 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1:output=7 kw with a fixed text, namely '
Type 1 without cable (J1772)
outputs at most 7 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "7 kw" }, { "key": "socket:socket:type1:output", - "description": "Layer 'Charging stations' shows socket:socket:type1:output=7.2 kw with a fixed text, namely 'Type 1 without cable (J1772) outputs at most 7.2 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1:output=7.2 kw with a fixed text, namely '
Type 1 without cable (J1772)
outputs at most 7.2 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "7.2 kw" }, { @@ -385,12 +448,12 @@ }, { "key": "socket:socket:type1_combo:voltage", - "description": "Layer 'Charging stations' shows socket:socket:type1_combo:voltage=400 V with a fixed text, namely 'Type 1 CCS (aka Type 1 Combo) outputs 400 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1_combo:voltage=400 V with a fixed text, namely '
Type 1 CCS (aka Type 1 Combo)
outputs 400 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "400 V" }, { "key": "socket:socket:type1_combo:voltage", - "description": "Layer 'Charging stations' shows socket:socket:type1_combo:voltage=1000 V with a fixed text, namely 'Type 1 CCS (aka Type 1 Combo) outputs 1000 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1_combo:voltage=1000 V with a fixed text, namely '
Type 1 CCS (aka Type 1 Combo)
outputs 1000 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "1000 V" }, { @@ -399,12 +462,12 @@ }, { "key": "socket:socket:type1_combo:current", - "description": "Layer 'Charging stations' shows socket:socket:type1_combo:current=50 A with a fixed text, namely 'Type 1 CCS (aka Type 1 Combo) outputs at most 50 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1_combo:current=50 A with a fixed text, namely '
Type 1 CCS (aka Type 1 Combo)
outputs at most 50 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "50 A" }, { "key": "socket:socket:type1_combo:current", - "description": "Layer 'Charging stations' shows socket:socket:type1_combo:current=125 A with a fixed text, namely 'Type 1 CCS (aka Type 1 Combo) outputs at most 125 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1_combo:current=125 A with a fixed text, namely '
Type 1 CCS (aka Type 1 Combo)
outputs at most 125 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "125 A" }, { @@ -413,22 +476,22 @@ }, { "key": "socket:socket:type1_combo:output", - "description": "Layer 'Charging stations' shows socket:socket:type1_combo:output=50 kw with a fixed text, namely 'Type 1 CCS (aka Type 1 Combo) outputs at most 50 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1_combo:output=50 kw with a fixed text, namely '
Type 1 CCS (aka Type 1 Combo)
outputs at most 50 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "50 kw" }, { "key": "socket:socket:type1_combo:output", - "description": "Layer 'Charging stations' shows socket:socket:type1_combo:output=62.5 kw with a fixed text, namely 'Type 1 CCS (aka Type 1 Combo) outputs at most 62.5 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1_combo:output=62.5 kw with a fixed text, namely '
Type 1 CCS (aka Type 1 Combo)
outputs at most 62.5 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "62.5 kw" }, { "key": "socket:socket:type1_combo:output", - "description": "Layer 'Charging stations' shows socket:socket:type1_combo:output=150 kw with a fixed text, namely 'Type 1 CCS (aka Type 1 Combo) outputs at most 150 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1_combo:output=150 kw with a fixed text, namely '
Type 1 CCS (aka Type 1 Combo)
outputs at most 150 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "150 kw" }, { "key": "socket:socket:type1_combo:output", - "description": "Layer 'Charging stations' shows socket:socket:type1_combo:output=350 kw with a fixed text, namely 'Type 1 CCS (aka Type 1 Combo) outputs at most 350 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type1_combo:output=350 kw with a fixed text, namely '
Type 1 CCS (aka Type 1 Combo)
outputs at most 350 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "350 kw" }, { @@ -441,7 +504,7 @@ }, { "key": "socket:socket:tesla_supercharger:voltage", - "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger:voltage=480 V with a fixed text, namely 'Tesla Supercharger outputs 480 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger:voltage=480 V with a fixed text, namely '
Tesla Supercharger
outputs 480 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "480 V" }, { @@ -450,12 +513,12 @@ }, { "key": "socket:socket:tesla_supercharger:current", - "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger:current=125 A with a fixed text, namely 'Tesla Supercharger outputs at most 125 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger:current=125 A with a fixed text, namely '
Tesla Supercharger
outputs at most 125 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "125 A" }, { "key": "socket:socket:tesla_supercharger:current", - "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger:current=350 A with a fixed text, namely 'Tesla Supercharger outputs at most 350 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger:current=350 A with a fixed text, namely '
Tesla Supercharger
outputs at most 350 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "350 A" }, { @@ -464,17 +527,17 @@ }, { "key": "socket:socket:tesla_supercharger:output", - "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger:output=120 kw with a fixed text, namely 'Tesla Supercharger outputs at most 120 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger:output=120 kw with a fixed text, namely '
Tesla Supercharger
outputs at most 120 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "120 kw" }, { "key": "socket:socket:tesla_supercharger:output", - "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger:output=150 kw with a fixed text, namely 'Tesla Supercharger outputs at most 150 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger:output=150 kw with a fixed text, namely '
Tesla Supercharger
outputs at most 150 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "150 kw" }, { "key": "socket:socket:tesla_supercharger:output", - "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger:output=250 kw with a fixed text, namely 'Tesla Supercharger outputs at most 250 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger:output=250 kw with a fixed text, namely '
Tesla Supercharger
outputs at most 250 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "250 kw" }, { @@ -487,12 +550,12 @@ }, { "key": "socket:socket:type2:voltage", - "description": "Layer 'Charging stations' shows socket:socket:type2:voltage=230 V with a fixed text, namely 'Type 2 (mennekes) outputs 230 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type2:voltage=230 V with a fixed text, namely '
Type 2 (mennekes)
outputs 230 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "230 V" }, { "key": "socket:socket:type2:voltage", - "description": "Layer 'Charging stations' shows socket:socket:type2:voltage=400 V with a fixed text, namely 'Type 2 (mennekes) outputs 400 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type2:voltage=400 V with a fixed text, namely '
Type 2 (mennekes)
outputs 400 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "400 V" }, { @@ -501,12 +564,12 @@ }, { "key": "socket:socket:type2:current", - "description": "Layer 'Charging stations' shows socket:socket:type2:current=16 A with a fixed text, namely 'Type 2 (mennekes) outputs at most 16 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type2:current=16 A with a fixed text, namely '
Type 2 (mennekes)
outputs at most 16 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "16 A" }, { "key": "socket:socket:type2:current", - "description": "Layer 'Charging stations' shows socket:socket:type2:current=32 A with a fixed text, namely 'Type 2 (mennekes) outputs at most 32 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type2:current=32 A with a fixed text, namely '
Type 2 (mennekes)
outputs at most 32 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "32 A" }, { @@ -515,12 +578,12 @@ }, { "key": "socket:socket:type2:output", - "description": "Layer 'Charging stations' shows socket:socket:type2:output=11 kw with a fixed text, namely 'Type 2 (mennekes) outputs at most 11 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type2:output=11 kw with a fixed text, namely '
Type 2 (mennekes)
outputs at most 11 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "11 kw" }, { "key": "socket:socket:type2:output", - "description": "Layer 'Charging stations' shows socket:socket:type2:output=22 kw with a fixed text, namely 'Type 2 (mennekes) outputs at most 22 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type2:output=22 kw with a fixed text, namely '
Type 2 (mennekes)
outputs at most 22 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "22 kw" }, { @@ -533,12 +596,12 @@ }, { "key": "socket:socket:type2_combo:voltage", - "description": "Layer 'Charging stations' shows socket:socket:type2_combo:voltage=500 V with a fixed text, namely 'Type 2 CCS (mennekes) outputs 500 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type2_combo:voltage=500 V with a fixed text, namely '
Type 2 CCS (mennekes)
outputs 500 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "500 V" }, { "key": "socket:socket:type2_combo:voltage", - "description": "Layer 'Charging stations' shows socket:socket:type2_combo:voltage=920 V with a fixed text, namely 'Type 2 CCS (mennekes) outputs 920 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type2_combo:voltage=920 V with a fixed text, namely '
Type 2 CCS (mennekes)
outputs 920 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "920 V" }, { @@ -547,12 +610,12 @@ }, { "key": "socket:socket:type2_combo:current", - "description": "Layer 'Charging stations' shows socket:socket:type2_combo:current=125 A with a fixed text, namely 'Type 2 CCS (mennekes) outputs at most 125 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type2_combo:current=125 A with a fixed text, namely '
Type 2 CCS (mennekes)
outputs at most 125 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "125 A" }, { "key": "socket:socket:type2_combo:current", - "description": "Layer 'Charging stations' shows socket:socket:type2_combo:current=350 A with a fixed text, namely 'Type 2 CCS (mennekes) outputs at most 350 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type2_combo:current=350 A with a fixed text, namely '
Type 2 CCS (mennekes)
outputs at most 350 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "350 A" }, { @@ -561,9 +624,261 @@ }, { "key": "socket:socket:type2_combo:output", - "description": "Layer 'Charging stations' shows socket:socket:type2_combo:output=50 kw with a fixed text, namely 'Type 2 CCS (mennekes) outputs at most 50 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows socket:socket:type2_combo:output=50 kw with a fixed text, namely '
Type 2 CCS (mennekes)
outputs at most 50 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "50 kw" }, + { + "key": "socket:type2_cable", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:type2_cable' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:type2_cable:voltage", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:type2_cable:voltage' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:socket:type2_cable:voltage", + "description": "Layer 'Charging stations' shows socket:socket:type2_cable:voltage=230 V with a fixed text, namely '
Type 2 with cable (mennekes)
outputs 230 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "230 V" + }, + { + "key": "socket:socket:type2_cable:voltage", + "description": "Layer 'Charging stations' shows socket:socket:type2_cable:voltage=400 V with a fixed text, namely '
Type 2 with cable (mennekes)
outputs 400 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "400 V" + }, + { + "key": "socket:type2_cable:current", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:type2_cable:current' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:socket:type2_cable:current", + "description": "Layer 'Charging stations' shows socket:socket:type2_cable:current=16 A with a fixed text, namely '
Type 2 with cable (mennekes)
outputs at most 16 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "16 A" + }, + { + "key": "socket:socket:type2_cable:current", + "description": "Layer 'Charging stations' shows socket:socket:type2_cable:current=32 A with a fixed text, namely '
Type 2 with cable (mennekes)
outputs at most 32 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "32 A" + }, + { + "key": "socket:type2_cable:output", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:type2_cable:output' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:socket:type2_cable:output", + "description": "Layer 'Charging stations' shows socket:socket:type2_cable:output=11 kw with a fixed text, namely '
Type 2 with cable (mennekes)
outputs at most 11 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "11 kw" + }, + { + "key": "socket:socket:type2_cable:output", + "description": "Layer 'Charging stations' shows socket:socket:type2_cable:output=22 kw with a fixed text, namely '
Type 2 with cable (mennekes)
outputs at most 22 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "22 kw" + }, + { + "key": "socket:tesla_supercharger_ccs", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:tesla_supercharger_ccs' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:tesla_supercharger_ccs:voltage", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:tesla_supercharger_ccs:voltage' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:socket:tesla_supercharger_ccs:voltage", + "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger_ccs:voltage=500 V with a fixed text, namely '
Tesla Supercharger CCS (a branded type2_css)
outputs 500 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "500 V" + }, + { + "key": "socket:socket:tesla_supercharger_ccs:voltage", + "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger_ccs:voltage=920 V with a fixed text, namely '
Tesla Supercharger CCS (a branded type2_css)
outputs 920 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "920 V" + }, + { + "key": "socket:tesla_supercharger_ccs:current", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:tesla_supercharger_ccs:current' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:socket:tesla_supercharger_ccs:current", + "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger_ccs:current=125 A with a fixed text, namely '
Tesla Supercharger CCS (a branded type2_css)
outputs at most 125 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "125 A" + }, + { + "key": "socket:socket:tesla_supercharger_ccs:current", + "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger_ccs:current=350 A with a fixed text, namely '
Tesla Supercharger CCS (a branded type2_css)
outputs at most 350 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "350 A" + }, + { + "key": "socket:tesla_supercharger_ccs:output", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:tesla_supercharger_ccs:output' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:socket:tesla_supercharger_ccs:output", + "description": "Layer 'Charging stations' shows socket:socket:tesla_supercharger_ccs:output=50 kw with a fixed text, namely '
Tesla Supercharger CCS (a branded type2_css)
outputs at most 50 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "50 kw" + }, + { + "key": "socket:tesla_destination", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:tesla_destination' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:tesla_destination:voltage", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:tesla_destination:voltage' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:socket:tesla_destination:voltage", + "description": "Layer 'Charging stations' shows socket:socket:tesla_destination:voltage=480 V with a fixed text, namely '
Tesla Supercharger (destination)
outputs 480 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "480 V" + }, + { + "key": "socket:tesla_destination:current", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:tesla_destination:current' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:socket:tesla_destination:current", + "description": "Layer 'Charging stations' shows socket:socket:tesla_destination:current=125 A with a fixed text, namely '
Tesla Supercharger (destination)
outputs at most 125 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "125 A" + }, + { + "key": "socket:socket:tesla_destination:current", + "description": "Layer 'Charging stations' shows socket:socket:tesla_destination:current=350 A with a fixed text, namely '
Tesla Supercharger (destination)
outputs at most 350 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "350 A" + }, + { + "key": "socket:tesla_destination:output", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:tesla_destination:output' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:socket:tesla_destination:output", + "description": "Layer 'Charging stations' shows socket:socket:tesla_destination:output=120 kw with a fixed text, namely '
Tesla Supercharger (destination)
outputs at most 120 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "120 kw" + }, + { + "key": "socket:socket:tesla_destination:output", + "description": "Layer 'Charging stations' shows socket:socket:tesla_destination:output=150 kw with a fixed text, namely '
Tesla Supercharger (destination)
outputs at most 150 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "150 kw" + }, + { + "key": "socket:socket:tesla_destination:output", + "description": "Layer 'Charging stations' shows socket:socket:tesla_destination:output=250 kw with a fixed text, namely '
Tesla Supercharger (destination)
outputs at most 250 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "250 kw" + }, + { + "key": "socket:tesla_destination", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:tesla_destination' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:tesla_destination:voltage", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:tesla_destination:voltage' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:socket:tesla_destination:voltage", + "description": "Layer 'Charging stations' shows socket:socket:tesla_destination:voltage=230 V with a fixed text, namely '
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs 230 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "230 V" + }, + { + "key": "socket:socket:tesla_destination:voltage", + "description": "Layer 'Charging stations' shows socket:socket:tesla_destination:voltage=400 V with a fixed text, namely '
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs 400 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "400 V" + }, + { + "key": "socket:tesla_destination:current", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:tesla_destination:current' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:socket:tesla_destination:current", + "description": "Layer 'Charging stations' shows socket:socket:tesla_destination:current=16 A with a fixed text, namely '
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most 16 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "16 A" + }, + { + "key": "socket:socket:tesla_destination:current", + "description": "Layer 'Charging stations' shows socket:socket:tesla_destination:current=32 A with a fixed text, namely '
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most 32 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "32 A" + }, + { + "key": "socket:tesla_destination:output", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:tesla_destination:output' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:socket:tesla_destination:output", + "description": "Layer 'Charging stations' shows socket:socket:tesla_destination:output=11 kw with a fixed text, namely '
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most 11 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "11 kw" + }, + { + "key": "socket:socket:tesla_destination:output", + "description": "Layer 'Charging stations' shows socket:socket:tesla_destination:output=22 kw with a fixed text, namely '
Tesla supercharger (destination (A Type 2 with cable branded as tesla)
outputs at most 22 kw' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "22 kw" + }, + { + "key": "socket:USB-A", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:USB-A' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:USB-A:voltage", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:USB-A:voltage' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:socket:USB-A:voltage", + "description": "Layer 'Charging stations' shows socket:socket:USB-A:voltage=5 V with a fixed text, namely '
USB to charge phones and small electronics
outputs 5 volt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "5 V" + }, + { + "key": "socket:USB-A:current", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:USB-A:current' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:socket:USB-A:current", + "description": "Layer 'Charging stations' shows socket:socket:USB-A:current=1 A with a fixed text, namely '
USB to charge phones and small electronics
outputs at most 1 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "1 A" + }, + { + "key": "socket:socket:USB-A:current", + "description": "Layer 'Charging stations' shows socket:socket:USB-A:current=2 A with a fixed text, namely '
USB to charge phones and small electronics
outputs at most 2 A' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "2 A" + }, + { + "key": "socket:USB-A:output", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:USB-A:output' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:socket:USB-A:output", + "description": "Layer 'Charging stations' shows socket:socket:USB-A:output=5w with a fixed text, namely '
USB to charge phones and small electronics
outputs at most 5w' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "5w" + }, + { + "key": "socket:socket:USB-A:output", + "description": "Layer 'Charging stations' shows socket:socket:USB-A:output=10w with a fixed text, namely '
USB to charge phones and small electronics
outputs at most 10w' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "10w" + }, + { + "key": "socket:bosch_3pin", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:bosch_3pin' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:bosch_3pin:voltage", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:bosch_3pin:voltage' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:bosch_3pin:current", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:bosch_3pin:current' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:bosch_3pin:output", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:bosch_3pin:output' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:bosch_5pin", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:bosch_5pin' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:bosch_5pin:voltage", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:bosch_5pin:voltage' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:bosch_5pin:current", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:bosch_5pin:current' (in the MapComplete.osm.be theme 'Charging stations')" + }, + { + "key": "socket:bosch_5pin:output", + "description": "Layer 'Charging stations' shows and asks freeform values for key 'socket:bosch_5pin:output' (in the MapComplete.osm.be theme 'Charging stations')" + }, { "key": "authentication:membership_card", "description": "Layer 'Charging stations' shows authentication:membership_card=yes with a fixed text, namely 'Authentication by a membership card' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", @@ -646,6 +961,11 @@ "description": "Layer 'Charging stations' shows payment:app=yes with a fixed text, namely 'Payment is done using a dedicated app' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "yes" }, + { + "key": "payment:membership_card", + "description": "Layer 'Charging stations' shows payment:membership_card=yes with a fixed text, namely 'Payment is done using a membership card' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "yes" + }, { "key": "maxstay", "description": "Layer 'Charging stations' shows and asks freeform values for key 'maxstay' (in the MapComplete.osm.be theme 'Charging stations')" @@ -770,27 +1090,23 @@ }, { "key": "amenity", - "description": "Layer 'Charging stations' shows amenity=charging_station with a fixed text, namely 'This charging station works' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "description": "Layer 'Charging stations' shows amenity=charging_station&operational_status= with a fixed text, namely 'This charging station works' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "charging_station" }, { - "key": "service:bicycle:cleaning:charge", - "description": "Layer 'Charging stations' shows and asks freeform values for key 'service:bicycle:cleaning:charge' (in the MapComplete.osm.be theme 'Charging stations')" + "key": "operational_status", + "description": "Layer 'Charging stations' shows amenity=charging_station&operational_status= with a fixed text, namely 'This charging station works' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations') Picking this answer will delete the key operational_status.", + "value": "" }, { - "key": "service:bicycle:cleaning:fee", - "description": "Layer 'Charging stations' shows service:bicycle:cleaning:fee=no&service:bicycle:cleaning:charge= with a fixed text, namely 'The cleaning service is free to use' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", - "value": "no&service:bicycle:cleaning:charge=" + "key": "parking:fee", + "description": "Layer 'Charging stations' shows parking:fee=no with a fixed text, namely 'No additional parking cost while charging' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "value": "no" }, { - "key": "service:bicycle:cleaning:fee", - "description": "Layer 'Charging stations' shows service:bicycle:cleaning:fee=no& with a fixed text, namely 'Free to use' (in the MapComplete.osm.be theme 'Charging stations')", - "value": "no&" - }, - { - "key": "service:bicycle:cleaning:fee", - "description": "Layer 'Charging stations' shows service:bicycle:cleaning:fee=yes with a fixed text, namely 'The cleaning service has a fee' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", + "key": "parking:fee", + "description": "Layer 'Charging stations' shows parking:fee=yes with a fixed text, namely 'An additional parking fee should be paid while charging' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Charging stations')", "value": "yes" } ] -} +} \ No newline at end of file diff --git a/Docs/TagInfo/mapcomplete_cyclofix.json b/Docs/TagInfo/mapcomplete_cyclofix.json index 477e19640..9138e75b4 100644 --- a/Docs/TagInfo/mapcomplete_cyclofix.json +++ b/Docs/TagInfo/mapcomplete_cyclofix.json @@ -170,10 +170,6 @@ "description": "The MapComplete theme Cyclofix - an open map for cyclists has a layer Bike repair/shop showing features with this tag", "value": "" }, - { - "key": "shop", - "description": "The MapComplete theme Cyclofix - an open map for cyclists has a layer Bike repair/shop showing features with this tag" - }, { "key": "image", "description": "The layer 'Bike repair/shop allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" diff --git a/Docs/TagInfo/mapcomplete_food.json b/Docs/TagInfo/mapcomplete_food.json index 6ce5dfc7c..2ae75a8ff 100644 --- a/Docs/TagInfo/mapcomplete_food.json +++ b/Docs/TagInfo/mapcomplete_food.json @@ -304,6 +304,26 @@ "key": "reusable_packaging:accept", "description": "Layer 'Restaurants and fast food' shows reusable_packaging:accept=only with a fixed text, namely 'You must bring your own container to order here.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Restaurants and fast food')", "value": "only" + }, + { + "key": "dog", + "description": "Layer 'Restaurants and fast food' shows dog=yes with a fixed text, namely 'Dogs are allowed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Restaurants and fast food')", + "value": "yes" + }, + { + "key": "dog", + "description": "Layer 'Restaurants and fast food' shows dog=no with a fixed text, namely 'Dogs are not allowed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Restaurants and fast food')", + "value": "no" + }, + { + "key": "dog", + "description": "Layer 'Restaurants and fast food' shows dog=leashed with a fixed text, namely 'Dogs are allowed, but they have to be leashed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Restaurants and fast food')", + "value": "leashed" + }, + { + "key": "dog", + "description": "Layer 'Restaurants and fast food' shows dog=unleashed with a fixed text, namely 'Dogs are allowed and can run around freely' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Restaurants and fast food')", + "value": "unleashed" } ] } \ No newline at end of file diff --git a/Docs/TagInfo/mapcomplete_fritures.json b/Docs/TagInfo/mapcomplete_fritures.json index 0af12c652..ae5de3180 100644 --- a/Docs/TagInfo/mapcomplete_fritures.json +++ b/Docs/TagInfo/mapcomplete_fritures.json @@ -310,6 +310,26 @@ "description": "Layer 'Fries shop' shows reusable_packaging:accept=only with a fixed text, namely 'You must bring your own container to order here.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Friturenkaart')", "value": "only" }, + { + "key": "dog", + "description": "Layer 'Fries shop' shows dog=yes with a fixed text, namely 'Dogs are allowed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Friturenkaart')", + "value": "yes" + }, + { + "key": "dog", + "description": "Layer 'Fries shop' shows dog=no with a fixed text, namely 'Dogs are not allowed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Friturenkaart')", + "value": "no" + }, + { + "key": "dog", + "description": "Layer 'Fries shop' shows dog=leashed with a fixed text, namely 'Dogs are allowed, but they have to be leashed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Friturenkaart')", + "value": "leashed" + }, + { + "key": "dog", + "description": "Layer 'Fries shop' shows dog=unleashed with a fixed text, namely 'Dogs are allowed and can run around freely' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Friturenkaart')", + "value": "unleashed" + }, { "key": "amenity", "description": "The MapComplete theme Friturenkaart has a layer Restaurants and fast food showing features with this tag", @@ -604,6 +624,26 @@ "key": "reusable_packaging:accept", "description": "Layer 'Restaurants and fast food' shows reusable_packaging:accept=only with a fixed text, namely 'You must bring your own container to order here.' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Friturenkaart')", "value": "only" + }, + { + "key": "dog", + "description": "Layer 'Restaurants and fast food' shows dog=yes with a fixed text, namely 'Dogs are allowed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Friturenkaart')", + "value": "yes" + }, + { + "key": "dog", + "description": "Layer 'Restaurants and fast food' shows dog=no with a fixed text, namely 'Dogs are not allowed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Friturenkaart')", + "value": "no" + }, + { + "key": "dog", + "description": "Layer 'Restaurants and fast food' shows dog=leashed with a fixed text, namely 'Dogs are allowed, but they have to be leashed' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Friturenkaart')", + "value": "leashed" + }, + { + "key": "dog", + "description": "Layer 'Restaurants and fast food' shows dog=unleashed with a fixed text, namely 'Dogs are allowed and can run around freely' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Friturenkaart')", + "value": "unleashed" } ] } \ No newline at end of file diff --git a/Docs/TagInfo/mapcomplete_hackerspaces.json b/Docs/TagInfo/mapcomplete_hackerspaces.json index b805e26d4..dad544320 100644 --- a/Docs/TagInfo/mapcomplete_hackerspaces.json +++ b/Docs/TagInfo/mapcomplete_hackerspaces.json @@ -77,7 +77,7 @@ }, { "key": "drink:club-mate", - "description": "Layer 'Hackerspace' shows drink:club-mate=no with a fixed text, namely 'This hackerspace is not worthy of the name hackerspace as it does not serve club mate' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hackerspaces')", + "description": "Layer 'Hackerspace' shows drink:club-mate=no with a fixed text, namely 'This hackerspace does not serve club mate' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Hackerspaces')", "value": "no" }, { diff --git a/Docs/TagInfo/mapcomplete_nature.json b/Docs/TagInfo/mapcomplete_nature.json index 2ccd10406..b1f7732be 100644 --- a/Docs/TagInfo/mapcomplete_nature.json +++ b/Docs/TagInfo/mapcomplete_nature.json @@ -428,16 +428,16 @@ }, { "key": "operator", - "description": "Layer 'Natuurgebied' shows operator=Natuurpunt with a fixed text, namely 'Dit gebied wordt beheerd door Natuurpunt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'De Natuur in')", + "description": "Layer 'Natuurgebied' shows operator=Natuurpunt with a fixed text, namely 'Dit gebied wordt beheerd door Natuurpunt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'De Natuur in')", "value": "Natuurpunt" }, { "key": "operator", - "description": "Layer 'Natuurgebied' shows operator~^(n|N)atuurpunt.*$ with a fixed text, namely 'Dit gebied wordt beheerd door {operator}' (in the MapComplete.osm.be theme 'De Natuur in')" + "description": "Layer 'Natuurgebied' shows operator~^(n|N)atuurpunt.*$ with a fixed text, namely 'Dit gebied wordt beheerd door {operator}' (in the MapComplete.osm.be theme 'De Natuur in')" }, { "key": "operator", - "description": "Layer 'Natuurgebied' shows operator=Agentschap Natuur en Bos with a fixed text, namely 'Dit gebied wordt beheerd door het Agentschap Natuur en Bos' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'De Natuur in')", + "description": "Layer 'Natuurgebied' shows operator=Agentschap Natuur en Bos with a fixed text, namely 'Dit gebied wordt beheerd door het Agentschap Natuur en Bos' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'De Natuur in')", "value": "Agentschap Natuur en Bos" }, { diff --git a/Docs/TagInfo/mapcomplete_observation_towers.json b/Docs/TagInfo/mapcomplete_observation_towers.json index ecf00cd66..375dc56a1 100644 --- a/Docs/TagInfo/mapcomplete_observation_towers.json +++ b/Docs/TagInfo/mapcomplete_observation_towers.json @@ -81,6 +81,11 @@ "description": "Layer 'Observation towers' shows payment:app=yes with a fixed text, namely 'Payment is done using a dedicated app' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Observation towers')", "value": "yes" }, + { + "key": "payment:membership_card", + "description": "Layer 'Observation towers' shows payment:membership_card=yes with a fixed text, namely 'Payment is done using a membership card' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Observation towers')", + "value": "yes" + }, { "key": "wheelchair", "description": "Layer 'Observation towers' shows wheelchair=designated with a fixed text, namely 'This place is specially adapated for wheelchair users' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Observation towers')", @@ -100,25 +105,6 @@ "key": "wheelchair", "description": "Layer 'Observation towers' shows wheelchair=no with a fixed text, namely 'This place is not reachable with a wheelchair' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Observation towers')", "value": "no" - }, - { - "key": "service:bicycle:cleaning:charge", - "description": "Layer 'Observation towers' shows and asks freeform values for key 'service:bicycle:cleaning:charge' (in the MapComplete.osm.be theme 'Observation towers')" - }, - { - "key": "service:bicycle:cleaning:fee", - "description": "Layer 'Observation towers' shows service:bicycle:cleaning:fee=no&service:bicycle:cleaning:charge= with a fixed text, namely 'The cleaning service is free to use' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Observation towers')", - "value": "no&service:bicycle:cleaning:charge=" - }, - { - "key": "service:bicycle:cleaning:fee", - "description": "Layer 'Observation towers' shows service:bicycle:cleaning:fee=no& with a fixed text, namely 'Free to use' (in the MapComplete.osm.be theme 'Observation towers')", - "value": "no&" - }, - { - "key": "service:bicycle:cleaning:fee", - "description": "Layer 'Observation towers' shows service:bicycle:cleaning:fee=yes with a fixed text, namely 'The cleaning service has a fee' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Observation towers')", - "value": "yes" } ] } \ No newline at end of file diff --git a/Docs/TagInfo/mapcomplete_parkings.json b/Docs/TagInfo/mapcomplete_parkings.json index 59ba9cdc3..86bcd0f4c 100644 --- a/Docs/TagInfo/mapcomplete_parkings.json +++ b/Docs/TagInfo/mapcomplete_parkings.json @@ -12,111 +12,34 @@ "tags": [ { "key": "amenity", - "description": "The MapComplete theme Parking has a layer parking showing features with this tag", + "description": "The MapComplete theme Parking has a layer Parking showing features with this tag", "value": "parking" }, { "key": "amenity", - "description": "The MapComplete theme Parking has a layer parking showing features with this tag", + "description": "The MapComplete theme Parking has a layer Parking showing features with this tag", "value": "motorcycle_parking" }, { "key": "amenity", - "description": "The MapComplete theme Parking has a layer parking showing features with this tag", + "description": "The MapComplete theme Parking has a layer Parking showing features with this tag", "value": "bicycle_parking" }, { "key": "image", - "description": "The layer 'parking allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" + "description": "The layer 'Parking allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" }, { "key": "mapillary", - "description": "The layer 'parking allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" + "description": "The layer 'Parking allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" }, { "key": "wikidata", - "description": "The layer 'parking allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" + "description": "The layer 'Parking allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" }, { "key": "wikipedia", - "description": "The layer 'parking allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" - }, - { - "key": "access:description", - "description": "Layer 'parking' shows and asks freeform values for key 'access:description' (in the MapComplete.osm.be theme 'Parking')" - }, - { - "key": "access", - "description": "Layer 'parking' shows access=yes&fee= with a fixed text, namely 'Vrij toegankelijk' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Parking')", - "value": "yes" - }, - { - "key": "fee", - "description": "Layer 'parking' shows access=yes&fee= with a fixed text, namely 'Vrij toegankelijk' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Parking') Picking this answer will delete the key fee.", - "value": "" - }, - { - "key": "access", - "description": "Layer 'parking' shows access=no&fee= with a fixed text, namely 'Niet toegankelijk' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Parking')", - "value": "no" - }, - { - "key": "fee", - "description": "Layer 'parking' shows access=no&fee= with a fixed text, namely 'Niet toegankelijk' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Parking') Picking this answer will delete the key fee.", - "value": "" - }, - { - "key": "access", - "description": "Layer 'parking' shows access=private&fee= with a fixed text, namely 'Niet toegankelijk, want privégebied' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Parking')", - "value": "private" - }, - { - "key": "fee", - "description": "Layer 'parking' shows access=private&fee= with a fixed text, namely 'Niet toegankelijk, want privégebied' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Parking') Picking this answer will delete the key fee.", - "value": "" - }, - { - "key": "access", - "description": "Layer 'parking' shows access=permissive&fee= with a fixed text, namely 'Toegankelijk, ondanks dat het privegebied is' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Parking')", - "value": "permissive" - }, - { - "key": "fee", - "description": "Layer 'parking' shows access=permissive&fee= with a fixed text, namely 'Toegankelijk, ondanks dat het privegebied is' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Parking') Picking this answer will delete the key fee.", - "value": "" - }, - { - "key": "access", - "description": "Layer 'parking' shows access=guided&fee= with a fixed text, namely 'Enkel toegankelijk met een gids of tijdens een activiteit' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Parking')", - "value": "guided" - }, - { - "key": "fee", - "description": "Layer 'parking' shows access=guided&fee= with a fixed text, namely 'Enkel toegankelijk met een gids of tijdens een activiteit' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Parking') Picking this answer will delete the key fee.", - "value": "" - }, - { - "key": "access", - "description": "Layer 'parking' shows access=yes&fee=yes with a fixed text, namely 'Toegankelijk mits betaling' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Parking')", - "value": "yes" - }, - { - "key": "fee", - "description": "Layer 'parking' shows access=yes&fee=yes with a fixed text, namely 'Toegankelijk mits betaling' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Parking')", - "value": "yes" - }, - { - "key": "operator", - "description": "Layer 'parking' shows and asks freeform values for key 'operator' (in the MapComplete.osm.be theme 'Parking')" - }, - { - "key": "operator", - "description": "Layer 'parking' shows operator=Natuurpunt with a fixed text, namely 'Dit gebied wordt beheerd door Natuurpunt' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Parking')", - "value": "Natuurpunt" - }, - { - "key": "operator", - "description": "Layer 'parking' shows operator~^(n|N)atuurpunt.*$ with a fixed text, namely 'Dit gebied wordt beheerd door {operator}' (in the MapComplete.osm.be theme 'Parking')" + "description": "The layer 'Parking allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" } ] } \ No newline at end of file diff --git a/Docs/TagInfo/mapcomplete_postboxes.json b/Docs/TagInfo/mapcomplete_postboxes.json new file mode 100644 index 000000000..ecc1874ce --- /dev/null +++ b/Docs/TagInfo/mapcomplete_postboxes.json @@ -0,0 +1,65 @@ +{ + "data_format": 1, + "project": { + "name": "MapComplete Postbox and Post Office Map", + "description": "A map showing postboxes and post offices", + "project_url": "https://mapcomplete.osm.be/postboxes", + "doc_url": "https://github.com/pietervdvn/MapComplete/tree/master/assets/themes/", + "icon_url": "https://mapcomplete.osm.be/assets/themes/postboxes/postbox.svg", + "contact_name": "Pieter Vander Vennet, ", + "contact_email": "pietervdvn@posteo.net" + }, + "tags": [ + { + "key": "amenity", + "description": "The MapComplete theme Postbox and Post Office Map has a layer Postboxes showing features with this tag", + "value": "post_box" + }, + { + "key": "image", + "description": "The layer 'Postboxes allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" + }, + { + "key": "mapillary", + "description": "The layer 'Postboxes allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" + }, + { + "key": "wikidata", + "description": "The layer 'Postboxes allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" + }, + { + "key": "wikipedia", + "description": "The layer 'Postboxes allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" + }, + { + "key": "amenity", + "description": "The MapComplete theme Postbox and Post Office Map has a layer Post offices showing features with this tag", + "value": "post_office" + }, + { + "key": "image", + "description": "The layer 'Post offices allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" + }, + { + "key": "mapillary", + "description": "The layer 'Post offices allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" + }, + { + "key": "wikidata", + "description": "The layer 'Post offices allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" + }, + { + "key": "wikipedia", + "description": "The layer 'Post offices allows to upload images and adds them under the 'image'-tag (and image:0, image:1, ... for multiple images). Furhtermore, this layer shows images based on the keys image, wikidata, wikipedia, wikimedia_commons and mapillary" + }, + { + "key": "opening_hours", + "description": "Layer 'Post offices' shows and asks freeform values for key 'opening_hours' (in the MapComplete.osm.be theme 'Postbox and Post Office Map')" + }, + { + "key": "opening_hours", + "description": "Layer 'Post offices' shows opening_hours=24/7 with a fixed text, namely '24/7 opened (including holidays)' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Postbox and Post Office Map')", + "value": "24/7" + } + ] +} \ No newline at end of file diff --git a/Docs/TagInfo/mapcomplete_toilets.json b/Docs/TagInfo/mapcomplete_toilets.json index 713b2b65b..776bae332 100644 --- a/Docs/TagInfo/mapcomplete_toilets.json +++ b/Docs/TagInfo/mapcomplete_toilets.json @@ -139,23 +139,24 @@ "value": "dedicated_room" }, { - "key": "service:bicycle:cleaning:charge", - "description": "Layer 'Toilets' shows and asks freeform values for key 'service:bicycle:cleaning:charge' (in the MapComplete.osm.be theme 'Open Toilet Map')" - }, - { - "key": "service:bicycle:cleaning:fee", - "description": "Layer 'Toilets' shows service:bicycle:cleaning:fee=no&service:bicycle:cleaning:charge= with a fixed text, namely 'The cleaning service is free to use' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Open Toilet Map')", - "value": "no&service:bicycle:cleaning:charge=" - }, - { - "key": "service:bicycle:cleaning:fee", - "description": "Layer 'Toilets' shows service:bicycle:cleaning:fee=no& with a fixed text, namely 'Free to use' (in the MapComplete.osm.be theme 'Open Toilet Map')", - "value": "no&" - }, - { - "key": "service:bicycle:cleaning:fee", - "description": "Layer 'Toilets' shows service:bicycle:cleaning:fee=yes with a fixed text, namely 'The cleaning service has a fee' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Open Toilet Map')", + "key": "toilets:handwashing", + "description": "Layer 'Toilets' shows toilets:handwashing=yes with a fixed text, namely 'This toilets have a sink to wash your hands' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Open Toilet Map')", "value": "yes" + }, + { + "key": "toilets:handwashing", + "description": "Layer 'Toilets' shows toilets:handwashing=no with a fixed text, namely 'This toilets don't have a sink to wash your hands' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Open Toilet Map')", + "value": "no" + }, + { + "key": "toilets:paper_supplied", + "description": "Layer 'Toilets' shows toilets:paper_supplied=yes with a fixed text, namely 'Toilet paper is equipped with toilet paper' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Open Toilet Map')", + "value": "yes" + }, + { + "key": "toilets:paper_supplied", + "description": "Layer 'Toilets' shows toilets:paper_supplied=no with a fixed text, namely 'You have to bring your own toilet paper to this toilet' and allows to pick this as a default answer (in the MapComplete.osm.be theme 'Open Toilet Map')", + "value": "no" } ] } \ No newline at end of file From d3550fefbe1f719e9c2682c63a77083a9e9c5ad3 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Tue, 12 Oct 2021 02:12:45 +0200 Subject: [PATCH 22/26] Add multi-apply box/feature, use it in etymology-theme to apply tags onto all segments of the same street --- Docs/CalculatedTags.md | 13 +- Docs/SpecialInputElements.md | 2 +- Docs/SpecialRenderings.md | 22 ++- Docs/TagInfo/mapcomplete_nature.json | 9 + .../mapcomplete_observation_towers.json | 9 + Logic/ExtraFunction.ts | 4 +- Logic/FeatureSource/FeaturePipeline.ts | 3 + Logic/ImageProviders/ImageProvider.ts | 1 - Logic/ImageProviders/WikidataImageProvider.ts | 1 - Logic/MetaTagging.ts | 4 +- Logic/SimpleMetaTagger.ts | 20 ++- UI/Popup/MultiApply.ts | 158 ++++++++++++++++++ UI/SpecialVisualizations.ts | 33 +++- UI/Wikipedia/WikidataPreviewBox.ts | 1 - UI/i18n/Translation.ts | 2 +- assets/layers/etymology/etymology.json | 16 ++ assets/tagRenderings/questions.json | 21 ++- .../toerisme_vlaanderen.json | 2 +- langs/en.json | 3 + langs/layers/en.json | 3 + langs/themes/en.json | 102 +++++------ langs/themes/nl.json | 4 +- 22 files changed, 355 insertions(+), 78 deletions(-) create mode 100644 UI/Popup/MultiApply.ts diff --git a/Docs/CalculatedTags.md b/Docs/CalculatedTags.md index 08083a10f..b9bfe2104 100644 --- a/Docs/CalculatedTags.md +++ b/Docs/CalculatedTags.md @@ -28,6 +28,15 @@ The latitude and longitude of the point (or centerpoint in the case of a way/are +### _layer + + + +The layer-id to which this feature belongs. Note that this might be return any applicable if `passAllFeatures` is defined. + + + + ### _surface, _surface:ha @@ -173,7 +182,7 @@ For example to get all objects which overlap or embed from a layer, use `_contai Given either a list of geojson features or a single layer name, gives the single object which is nearest to the feature. In the case of ways/polygons, only the centerpoint is considered. Returns a single geojson feature or undefined if nothing is found (or not yet laoded) - 0. list of features + 0. list of features or a layer name or '*' to get all features ### closestn @@ -181,7 +190,7 @@ For example to get all objects which overlap or embed from a layer, use `_contai If a 'unique tag key' is given, the tag with this key will only appear once (e.g. if 'name' is given, all features will have a different name) - 0. list of features or layer name + 0. list of features or layer name or '*' to get all features 1. amount of features 2. unique tag key (optional) 3. maxDistanceInMeters (optional) diff --git a/Docs/SpecialInputElements.md b/Docs/SpecialInputElements.md index 957a74db4..3c05b4c87 100644 --- a/Docs/SpecialInputElements.md +++ b/Docs/SpecialInputElements.md @@ -24,7 +24,7 @@ A geographical length in meters (rounded at two points). Will give an extra mini ## wikidata -A wikidata identifier, e.g. Q42 +A wikidata identifier, e.g. Q42. Input helper arguments: [ key: the value of this tag will initialize search (default: name), options: { removePrefixes: string[], removePostfixes: string[] } these prefixes and postfixes will be removed from the initial search value] ## int diff --git a/Docs/SpecialRenderings.md b/Docs/SpecialRenderings.md index f5ca4d6e8..7fff50797 100644 --- a/Docs/SpecialRenderings.md +++ b/Docs/SpecialRenderings.md @@ -14,7 +14,7 @@ name | default | description ------ | --------- | ------------- -image key/prefix | image | The keys given to the images, e.g. if image is given, the first picture URL will be added as image, the second as image:0, the third as image:1, etc... +image key/prefix (multiple values allowed if comma-seperated) | image | The keys given to the images, e.g. if image is given, the first picture URL will be added as image, the second as image:0, the third as image:1, etc... #### Example usage @@ -26,10 +26,11 @@ image key/prefix | image | The keys given to the images, e.g. if { return (features) => ExtraFunction.GetClosestNFeatures(params, feature, features)?.[0]?.feat @@ -132,7 +132,7 @@ export class ExtraFunction { doc: "Given either a list of geojson features or a single layer name, gives the n closest objects which are nearest to the feature (excluding the feature itself). In the case of ways/polygons, only the centerpoint is considered. " + "Returns a list of `{feat: geojson, distance:number}` the empty list if nothing is found (or not yet loaded)\n\n" + "If a 'unique tag key' is given, the tag with this key will only appear once (e.g. if 'name' is given, all features will have a different name)", - args: ["list of features or layer name", "amount of features", "unique tag key (optional)", "maxDistanceInMeters (optional)"] + args: ["list of features or layer name or '*' to get all features", "amount of features", "unique tag key (optional)", "maxDistanceInMeters (optional)"] }, (params, feature) => { diff --git a/Logic/FeatureSource/FeaturePipeline.ts b/Logic/FeatureSource/FeaturePipeline.ts index ee89ee6aa..a24f18d8c 100644 --- a/Logic/FeatureSource/FeaturePipeline.ts +++ b/Logic/FeatureSource/FeaturePipeline.ts @@ -402,6 +402,9 @@ export default class FeaturePipeline { } public GetFeaturesWithin(layerId: string, bbox: BBox): any[][] { + if(layerId === "*"){ + return this.GetAllFeaturesWithin(bbox) + } const requestedHierarchy = this.perLayerHierarchy.get(layerId) if (requestedHierarchy === undefined) { console.warn("Layer ", layerId, "is not defined. Try one of ", Array.from(this.perLayerHierarchy.keys())) diff --git a/Logic/ImageProviders/ImageProvider.ts b/Logic/ImageProviders/ImageProvider.ts index 1dd38c2b7..12e05272e 100644 --- a/Logic/ImageProviders/ImageProvider.ts +++ b/Logic/ImageProviders/ImageProvider.ts @@ -55,7 +55,6 @@ export default abstract class ImageProvider { } seenValues.add(value) this.ExtractUrls(key, value).then(promises => { - console.log("Got ", promises.length, "promises for", value,"by",self.constructor.name) for (const promise of promises ?? []) { if (promise === undefined) { continue diff --git a/Logic/ImageProviders/WikidataImageProvider.ts b/Logic/ImageProviders/WikidataImageProvider.ts index 9c3d6af3e..139201578 100644 --- a/Logic/ImageProviders/WikidataImageProvider.ts +++ b/Logic/ImageProviders/WikidataImageProvider.ts @@ -27,7 +27,6 @@ export class WikidataImageProvider extends ImageProvider { if(entity === undefined){ return [] } - console.log("Entity:", entity) const allImages : Promise[] = [] // P18 is the claim 'depicted in this image' diff --git a/Logic/MetaTagging.ts b/Logic/MetaTagging.ts index 8b7eec75b..83b85f34a 100644 --- a/Logic/MetaTagging.ts +++ b/Logic/MetaTagging.ts @@ -64,12 +64,12 @@ export default class MetaTagging { if(metatag.isLazy){ somethingChanged = true; - metatag.applyMetaTagsOnFeature(feature, freshness) + metatag.applyMetaTagsOnFeature(feature, freshness, layer) }else{ - const newValueAdded = metatag.applyMetaTagsOnFeature(feature, freshness) + const newValueAdded = metatag.applyMetaTagsOnFeature(feature, freshness, layer) /* Note that the expression: * `somethingChanged = newValueAdded || metatag.applyMetaTagsOnFeature(feature, freshness)` * Is WRONG diff --git a/Logic/SimpleMetaTagger.ts b/Logic/SimpleMetaTagger.ts index b0e4d50bf..f6c0b5359 100644 --- a/Logic/SimpleMetaTagger.ts +++ b/Logic/SimpleMetaTagger.ts @@ -6,6 +6,7 @@ import Combine from "../UI/Base/Combine"; import BaseUIElement from "../UI/BaseUIElement"; import Title from "../UI/Base/Title"; import {FixedUiElement} from "../UI/Base/FixedUiElement"; +import LayerConfig from "../Models/ThemeConfig/LayerConfig"; const cardinalDirections = { @@ -62,6 +63,20 @@ export default class SimpleMetaTagger { return true; }) ); + private static layerInfo = new SimpleMetaTagger( + { + doc: "The layer-id to which this feature belongs. Note that this might be return any applicable if `passAllFeatures` is defined.", + keys:["_layer"], + includesDates: false, + }, + (feature, freshness, layer) => { + if(feature.properties._layer === layer.id){ + return false; + } + feature.properties._layer = layer.id + return true; + } + ) private static surfaceArea = new SimpleMetaTagger( { keys: ["_surface", "_surface:ha"], @@ -329,6 +344,7 @@ export default class SimpleMetaTagger { ) public static metatags = [ SimpleMetaTagger.latlon, + SimpleMetaTagger.layerInfo, SimpleMetaTagger.surfaceArea, SimpleMetaTagger.lngth, SimpleMetaTagger.canonicalize, @@ -346,7 +362,7 @@ export default class SimpleMetaTagger { public readonly doc: string; public readonly isLazy: boolean; public readonly includesDates: boolean - public readonly applyMetaTagsOnFeature: (feature: any, freshness: Date) => boolean; + public readonly applyMetaTagsOnFeature: (feature: any, freshness: Date, layer: LayerConfig) => boolean; /*** * A function that adds some extra data to a feature @@ -354,7 +370,7 @@ export default class SimpleMetaTagger { * @param f: apply the changes. Returns true if something changed */ constructor(docs: { keys: string[], doc: string, includesDates?: boolean, isLazy?: boolean }, - f: ((feature: any, freshness: Date) => boolean)) { + f: ((feature: any, freshness: Date, layer: LayerConfig) => boolean)) { this.keys = docs.keys; this.doc = docs.doc; this.isLazy = docs.isLazy diff --git a/UI/Popup/MultiApply.ts b/UI/Popup/MultiApply.ts new file mode 100644 index 000000000..30575cdd5 --- /dev/null +++ b/UI/Popup/MultiApply.ts @@ -0,0 +1,158 @@ +import {UIEventSource} from "../../Logic/UIEventSource"; +import BaseUIElement from "../BaseUIElement"; +import Combine from "../Base/Combine"; +import {SubtleButton} from "../Base/SubtleButton"; +import {Changes} from "../../Logic/Osm/Changes"; +import {FixedUiElement} from "../Base/FixedUiElement"; +import Translations from "../i18n/Translations"; +import {VariableUiElement} from "../Base/VariableUIElement"; +import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction"; +import {Tag} from "../../Logic/Tags/Tag"; +import {ElementStorage} from "../../Logic/ElementStorage"; +import {And} from "../../Logic/Tags/And"; +import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; +import Toggle from "../Input/Toggle"; +import {OsmConnection} from "../../Logic/Osm/OsmConnection"; + + +export interface MultiApplyParams { + featureIds: UIEventSource, + keysToApply: string[], + text: string, + autoapply: boolean, + overwrite: boolean, + tagsSource: UIEventSource, + state: { + changes: Changes, + allElements: ElementStorage, + layoutToUse: LayoutConfig, + osmConnection: OsmConnection + } +} + +class MultiApplyExecutor { + + private readonly originalValues = new Map() + private readonly params: MultiApplyParams; + + private constructor(params: MultiApplyParams) { + this.params = params; + const p = params + + for (const key of p.keysToApply) { + this.originalValues.set(key, p.tagsSource.data[key]) + } + + if (p.autoapply) { + + const self = this; + const relevantValues = p.tagsSource.map(tags => { + const currentValues = p.keysToApply.map(key => tags[key]) + const v = JSON.stringify(currentValues) // By stringifying, we have a very clear ping when they changec + console.log("Values are", v) + return v; + }) + relevantValues.addCallbackD(_ => { + self.applyTaggingOnOtherFeatures() + }) + } + } + + public applyTaggingOnOtherFeatures() { + console.log("Multi-applying changes...") + const featuresToChange = this.params.featureIds.data + const changes = this.params.state.changes + const allElements = this.params.state.allElements + const keysToChange = this.params.keysToApply + const overwrite = this.params.overwrite + const selfTags = this.params.tagsSource.data; + const theme = this.params.state.layoutToUse.id + for (const id of featuresToChange) { + const tagsToApply: Tag[] = [] + const otherFeatureTags = allElements.getEventSourceById(id).data + for (const key of keysToChange) { + const newValue = selfTags[key] + if (newValue === undefined) { + continue + } + const otherValue = otherFeatureTags[key] + if (newValue === otherValue) { + continue;// No changes to be made + } + + if (overwrite) { + tagsToApply.push(new Tag(key, newValue)) + continue; + } + + + if (otherValue === undefined || otherValue === "" || otherValue === this.originalValues.get(key)) { + tagsToApply.push(new Tag(key, newValue)) + } + } + + if (tagsToApply.length == 0) { + continue; + } + + + changes.applyAction( + new ChangeTagAction(id, new And(tagsToApply), otherFeatureTags, { + theme, + changeType: "answer" + })) + } + } + + private static executorCache = new Map() + + public static GetApplicator(id: string, params: MultiApplyParams): MultiApplyExecutor { + if (MultiApplyExecutor.executorCache.has(id)) { + return MultiApplyExecutor.executorCache.get(id) + } + const applicator = new MultiApplyExecutor(params) + MultiApplyExecutor.executorCache.set(id, applicator) + return applicator + } + +} + +export default class MultiApply extends Toggle { + + constructor(params: MultiApplyParams) { + const p = params + const t = Translations.t.multi_apply + + + const featureId = p.tagsSource.data.id + + if (featureId === undefined) { + throw "MultiApply needs a feature id" + } + + const applicator = MultiApplyExecutor.GetApplicator(featureId, params) + + const elems: (string | BaseUIElement)[] = [] + if (p.autoapply) { + elems.push(new Combine([new FixedUiElement(p.text).SetClass("block") ]).SetClass("flex")) + elems.push(new VariableUiElement(p.featureIds.map(featureIds => + t.autoApply.Subs({ + attr_names: p.keysToApply.join(", "), + count: "" + featureIds.length + }))).SetClass("block subtle text-sm")) + } else { + elems.push( + new SubtleButton(undefined, p.text).onClick(() => applicator.applyTaggingOnOtherFeatures()) + ) + } + + + const isShown: UIEventSource = p.state.osmConnection.isLoggedIn.map(loggedIn => { + return loggedIn && p.featureIds.data.length > 0 + }, [p.featureIds]) + super(new Combine(elems), undefined, isShown); + + } + + +} \ No newline at end of file diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index af9a2aa88..3af7df316 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -28,6 +28,7 @@ import Minimap from "./Base/Minimap"; import AllImageProviders from "../Logic/ImageProviders/AllImageProviders"; import WikipediaBox from "./Wikipedia/WikipediaBox"; import SimpleMetaTagger from "../Logic/SimpleMetaTagger"; +import MultiApply from "./Popup/MultiApply"; export interface SpecialVisualization { funcName: string, @@ -484,8 +485,38 @@ There are also some technicalities in your theme to keep in mind: args[2], args[1], tagSource, rewrittenTags, lat, lon, Number(args[3]), state ) } + }, + {funcName: "multi_apply", + docs: "A button to apply the tagging of this object onto a list of other features. This is an advanced feature for which you'll need calculatedTags", + args:[ + {name: "feature_ids", doc: "A JSOn-serialized list of IDs of features to apply the tagging on"}, + {name: "keys", doc: "One key (or multiple keys, seperated by ';') of the attribute that should be copied onto the other features." }, + {name: "text", doc: "The text to show on the button"}, + {name:"autoapply",doc:"A boolean indicating wether this tagging should be applied automatically if the relevant tags on this object are changed. A visual element indicating the multi_apply is still shown"}, + {name:"overwrite",doc:"If set to 'true', the tags on the other objects will always be overwritten. The default behaviour will be to only change the tags on other objects if they are either undefined or had the same value before the change"} + ], + example: "{multi_apply(_features_with_the_same_name_within_100m, name:etymology:wikidata;name:etymology, Apply etymology information on all nearby objects with the same name)}", + constr: (state, tagsSource, args) => { + const featureIdsKey = args[0] + const keysToApply = args[1].split(";") + const text = args[2] + const autoapply = args[3]?.toLowerCase() === "true" + const overwrite = args[4]?.toLowerCase() === "true" + const featureIds : UIEventSource = tagsSource.map(tags => JSON.parse(tags[featureIdsKey])) + return new MultiApply( + { + featureIds, + keysToApply, + text, + autoapply, + overwrite, + tagsSource, + state + } + ); + + } } - ] static HelpMessage: BaseUIElement = SpecialVisualizations.GenHelpMessage(); diff --git a/UI/Wikipedia/WikidataPreviewBox.ts b/UI/Wikipedia/WikidataPreviewBox.ts index d6682326b..feca815fa 100644 --- a/UI/Wikipedia/WikidataPreviewBox.ts +++ b/UI/Wikipedia/WikidataPreviewBox.ts @@ -53,7 +53,6 @@ export default class WikidataPreviewBox extends VariableUiElement { ]).SetClass("flex"), Wikidata.IdToArticle(wikidata.id) ,true).SetClass("must-link") - console.log(wikidata) let info = new Combine( [ new Combine([Translation.fromMap(wikidata.labels).SetClass("font-bold"), link]).SetClass("flex justify-between"), diff --git a/UI/i18n/Translation.ts b/UI/i18n/Translation.ts index fd9b1dacd..a4260a772 100644 --- a/UI/i18n/Translation.ts +++ b/UI/i18n/Translation.ts @@ -217,7 +217,7 @@ export class Translation extends BaseUIElement { static fromMap(transl: Map) { const translations = {} - transl.forEach((value, key) => { + transl?.forEach((value, key) => { translations[key] = value }) return new Translation(translations); diff --git a/assets/layers/etymology/etymology.json b/assets/layers/etymology/etymology.json index d49b45670..df89f5f81 100644 --- a/assets/layers/etymology/etymology.json +++ b/assets/layers/etymology/etymology.json @@ -23,6 +23,10 @@ "en": "All objects which have an etymology known", "nl": "Alle lagen met een gelinkt etymology" }, + "calculatedTags": [ + "_same_name_ids=feat.closestn('*', 250, undefined, 2500)?.filter(f => f.feat.properties.name === feat.properties.name)?.map(f => f.feat.properties.id)??[]", + "_total_segments=JSON.parse(feat.properties._same_name_ids).length + 1 // Plus one for the feature itself" + ], "tagRenderings": [ { "id": "etymology-images-from-wikipedia", @@ -115,6 +119,18 @@ "nl": "{image_carousel(image:streetsign)}
{image_upload(image:streetsign, Voeg afbeelding van straatnaambordje toe)}" } }, + { + "id": "minimap", + "render": { + "*": "{minimap(18, id, _same_name_ids):height:10rem}" + } + }, + { + "id": "etymology_multi_apply", + "render": { + "en": "{multi_apply(_same_name_ids, name:etymology:wikidata;name:etymology, Auto-applying data on all segments with the same name, true)}" + } + }, "wikipedia" ], "icon": { diff --git a/assets/tagRenderings/questions.json b/assets/tagRenderings/questions.json index cb8084ad6..d795c741b 100644 --- a/assets/tagRenderings/questions.json +++ b/assets/tagRenderings/questions.json @@ -198,28 +198,32 @@ "if": "dog=yes", "then": { "en": "Dogs are allowed", - "nl": "honden zijn toegelaten" + "nl": "honden zijn toegelaten", + "pt": "Os cães são permitidos" } }, { "if": "dog=no", "then": { "en": "Dogs are not allowed", - "nl": "honden zijn niet toegelaten" + "nl": "honden zijn niet toegelaten", + "pt": "Os cães não são permitidos" } }, { "if": "dog=leashed", "then": { "en": "Dogs are allowed, but they have to be leashed", - "nl": "honden zijn enkel aan de leiband welkom" + "nl": "honden zijn enkel aan de leiband welkom", + "pt": "Os cães são permitidos, mas têm de ser presos pela trela" } }, { "if": "dog=unleashed", "then": { "en": "Dogs are allowed and can run around freely", - "nl": "honden zijn welkom en mogen vrij rondlopen" + "nl": "honden zijn welkom en mogen vrij rondlopen", + "pt": "Os cães são permitidos e podem correr livremente" } } ] @@ -294,7 +298,8 @@ "en": "Cash is accepted here", "nl": "Cash geld wordt hier aanvaard", "pt": "Aceitam pagamento com dinheiro aqui", - "pt_BR": "Dinheiro é aceito aqui" + "pt_BR": "Dinheiro é aceito aqui", + "id": "Disini menerima pembayaran tunai" } }, { @@ -304,7 +309,8 @@ "en": "Payment cards are accepted here", "nl": "Betalen met bankkaarten kan hier", "pt": "Aceitam pagamento com cartões bancários aqui", - "pt_BR": "Cartões de pagamento são aceitos aqui" + "pt_BR": "Cartões de pagamento são aceitos aqui", + "id": "Disini menerima pembayaran dengan kartu" } } ] @@ -406,7 +412,8 @@ "fr": "Premier étage", "pl": "Znajduje się na pierwszym piętrze", "sv": "Ligger på första våningen", - "pt": "Está no primeiro andar" + "pt": "Está no primeiro andar", + "id": "Berlokasi di lantai pertama" } } ] diff --git a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json index 489c36ed7..ce9864c20 100644 --- a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json +++ b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json @@ -14,7 +14,7 @@ "nl": "Een kaart om toeristisch relevante info op aan te duiden" }, "description": { - "nl": "Op deze kaart kan je info zien die relevant is voor toerisme, zoals:
  • Eetgelegenheden
  • Cafés en bars
  • (Fiets)oplaadpunten
  • Fietspompen, fietserverhuur en fietswinkels
  • Uitkijktorens
  • ...
Zie je fouten op de kaart? Dan kan je zelf makkelijk aanpasingen maken, die zichtbaar zijn voor iedereen. Hiervoor dien je een gratis OpenStreetMap account voor te maken." + "nl": "Op deze kaart kan je info zien die relevant is voor toerisme, zoals:
  • Eetgelegenheden
  • Cafés en bars
  • (Fiets)oplaadpunten
  • Fietspompen, fietserverhuur en fietswinkels
  • Uitkijktorens
  • ...
Zie je fouten op de kaart? Dan kan je zelf makkelijk aanpasingen maken, die zichtbaar zijn voor iedereen. Hiervoor dien je een gratis OpenStreetMap account voor te maken.

Met de steun van Toerisme Vlaanderen" }, "descriptionTail": { "nl": "Met de steun van Toerisme Vlaanderen" diff --git a/langs/en.json b/langs/en.json index 92b0acc67..46afffb99 100644 --- a/langs/en.json +++ b/langs/en.json @@ -36,6 +36,9 @@ "splitTitle": "Choose on the map where to split this road", "hasBeenSplit": "This way has been split" }, + "multi_apply": { + "autoApply": "When changing the attributes {attr_names}, these attributes will automatically be changed on {count} other objects too" + }, "delete": { "delete": "Delete", "cancel": "Cancel", diff --git a/langs/layers/en.json b/langs/layers/en.json index 86eac29b2..96624bc97 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -2504,6 +2504,9 @@ "description": "All objects which have an etymology known", "name": "Has etymolgy", "tagRenderings": { + "etymology_multi_apply": { + "render": "{multi_apply(_same_name_ids, name:etymology:wikidata;name:etymology, Auto-applying data on all segments with the same name, true)}" + }, "simple etymology": { "mappings": { "0": { diff --git a/langs/themes/en.json b/langs/themes/en.json index 142ffcdfa..d5976735d 100644 --- a/langs/themes/en.json +++ b/langs/themes/en.json @@ -1236,6 +1236,57 @@ "shortDescription": "A map with playgrounds", "title": "Playgrounds" }, + "postboxes": { + "description": "On this map you can find and add data of post offices and post boxes. You can use this map to find where you can mail your next postcard! :)
Spotted an error or is a post box missing? You can edit this map with a free OpenStreetMap account. ", + "layers": { + "0": { + "description": "The layer showing postboxes.", + "name": "Postboxes", + "presets": { + "0": { + "title": "postbox" + } + }, + "title": { + "render": "Postbox" + } + }, + "1": { + "description": "A layer showing post offices.", + "filter": { + "0": { + "options": { + "0": { + "question": "Currently open" + } + } + } + }, + "name": "Post offices", + "presets": { + "0": { + "title": "Post Office" + } + }, + "tagRenderings": { + "OH": { + "mappings": { + "0": { + "then": "24/7 opened (including holidays)" + } + }, + "question": "What are the opening hours for this post office?", + "render": "Opening Hours: {opening_hours_table()}" + } + }, + "title": { + "render": "Post Office" + } + } + }, + "shortDescription": "A map showing postboxes and post offices", + "title": "Postbox and Post Office Map" + }, "shops": { "description": "On this map, one can mark basic information about shops, add opening hours and phone numbers", "layers": { @@ -1367,56 +1418,5 @@ "description": "On this map, you'll find waste baskets near you. If a waste basket is missing on this map, you can add it yourself", "shortDescription": "A map with waste baskets", "title": "Waste Basket" - }, - "postboxes": { - "description": "On this map you can find and add data of post offices and post boxes. You can use this map to find where you can mail your next postcard! :)
Spotted an error or is a post box missing? You can edit this map with a free OpenStreetMap account. ", - "layers": { - "0": { - "description": "The layer showing postboxes.", - "name": "Postboxes", - "presets": { - "0": { - "title": "postbox" - } - }, - "title": { - "render": "Postbox" - } - }, - "1": { - "description": "A layer showing post offices.", - "filter": { - "0": { - "options": { - "0": { - "question": "Currently open" - } - } - } - }, - "name": "Post offices", - "presets": { - "0": { - "title": "Post Office" - } - }, - "tagRenderings": { - "OH": { - "mappings": { - "0": { - "then": "24/7 opened (including holidays)" - } - }, - "question": "What are the opening hours for this post office?", - "render": "Opening Hours: {opening_hours_table()}" - } - }, - "title": { - "render": "Post Office" - } - } - }, - "shortDescription": "A map showing postboxes and post offices", - "title": "Postbox and Post Office Map" } } \ No newline at end of file diff --git a/langs/themes/nl.json b/langs/themes/nl.json index 42e1edc56..11bf88734 100644 --- a/langs/themes/nl.json +++ b/langs/themes/nl.json @@ -1021,9 +1021,9 @@ }, "toerisme_vlaanderen": { "description": "Op deze kaart kan je info zien die relevant is voor toerisme, zoals:
  • Eetgelegenheden
  • Cafés en bars
  • (Fiets)oplaadpunten
  • Fietspompen, fietserverhuur en fietswinkels
  • Uitkijktorens
  • ...
Zie je fouten op de kaart? Dan kan je zelf makkelijk aanpasingen maken, die zichtbaar zijn voor iedereen. Hiervoor dien je een gratis OpenStreetMap account voor te maken.

Met de steun van Toerisme Vlaanderen", + "descriptionTail": "Met de steun van Toerisme Vlaanderen", "shortDescription": "Een kaart om toeristisch relevante info op aan te duiden", - "title": "Toeristisch relevante info", - "descriptionTail": "Met de steun van Toerisme Vlaanderen" + "title": "Toeristisch relevante info" }, "toilets": { "description": "Een kaart met openbare toiletten", From 0c9ee8631e3841a12f1cf8f70fecddd16bbea64f Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Tue, 12 Oct 2021 02:25:31 +0200 Subject: [PATCH 23/26] Add parks and forests to etymology --- UI/Popup/MultiApply.ts | 7 +++---- assets/layers/etymology/etymology.json | 3 +-- assets/themes/etymology.json | 24 ++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/UI/Popup/MultiApply.ts b/UI/Popup/MultiApply.ts index 30575cdd5..159bdd321 100644 --- a/UI/Popup/MultiApply.ts +++ b/UI/Popup/MultiApply.ts @@ -48,9 +48,8 @@ class MultiApplyExecutor { const self = this; const relevantValues = p.tagsSource.map(tags => { const currentValues = p.keysToApply.map(key => tags[key]) - const v = JSON.stringify(currentValues) // By stringifying, we have a very clear ping when they changec - console.log("Values are", v) - return v; + // By stringifying, we have a very clear ping when they changec + return JSON.stringify(currentValues); }) relevantValues.addCallbackD(_ => { self.applyTaggingOnOtherFeatures() @@ -134,7 +133,7 @@ export default class MultiApply extends Toggle { const elems: (string | BaseUIElement)[] = [] if (p.autoapply) { - elems.push(new Combine([new FixedUiElement(p.text).SetClass("block") ]).SetClass("flex")) + elems.push(new FixedUiElement(p.text).SetClass("block")) elems.push(new VariableUiElement(p.featureIds.map(featureIds => t.autoApply.Subs({ attr_names: p.keysToApply.join(", "), diff --git a/assets/layers/etymology/etymology.json b/assets/layers/etymology/etymology.json index df89f5f81..dc1ed4ad2 100644 --- a/assets/layers/etymology/etymology.json +++ b/assets/layers/etymology/etymology.json @@ -24,8 +24,7 @@ "nl": "Alle lagen met een gelinkt etymology" }, "calculatedTags": [ - "_same_name_ids=feat.closestn('*', 250, undefined, 2500)?.filter(f => f.feat.properties.name === feat.properties.name)?.map(f => f.feat.properties.id)??[]", - "_total_segments=JSON.parse(feat.properties._same_name_ids).length + 1 // Plus one for the feature itself" + "_same_name_ids=feat.closestn('*', 250, undefined, 2500)?.filter(f => f.feat.properties.name === feat.properties.name)?.map(f => f.feat.properties.id)??[]" ], "tagRenderings": [ { diff --git a/assets/themes/etymology.json b/assets/themes/etymology.json index 3aa346dc3..5829b25f8 100644 --- a/assets/themes/etymology.json +++ b/assets/themes/etymology.json @@ -45,6 +45,30 @@ } } } + }, + { + "builtin": "etymology", + "override": { + "id": "parks_and_forests_without_etymology", + "name": { + "en": "Parks and forests without etymology information", + "nl": "Parken en bossen zonder etymologische informatie" + }, + "minzoom": 18, + "source": { + "osmTags": { + "and": [ + "name~*", + { + "or": [ + "leisure=park", + "landuse=forest" + ] + } + ] + } + } + } } ], "hideFromOverview": true From 69f21f29eb705875871f079b7b5088ba18519b75 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 13 Oct 2021 03:10:46 +0200 Subject: [PATCH 24/26] Dynamic JSON: only request existing tiles if a whitelist is given --- .../TiledFeatureSource/DynamicGeoJsonTileSource.ts | 3 +-- UI/ShowDataLayer/TileHierarchyAggregator.ts | 6 ++---- assets/themes/natuurpunt/natuurpunt.json | 3 +-- .../toerisme_vlaanderen/toerisme_vlaanderen.json | 2 +- assets/themes/uk_addresses/uk_addresses.json | 12 +----------- scripts/generateCache.ts | 3 ++- 6 files changed, 8 insertions(+), 21 deletions(-) diff --git a/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts b/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts index fc110e1c2..67e57ce7f 100644 --- a/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts +++ b/Logic/FeatureSource/TiledFeatureSource/DynamicGeoJsonTileSource.ts @@ -48,8 +48,7 @@ export default class DynamicGeoJsonTileSource extends DynamicTileSource { if(whitelist !== undefined){ const isWhiteListed = whitelist.get(zxy[1])?.has(zxy[2]) if(!isWhiteListed){ - console.log("Not whitelisted:",zxy, isWhiteListed, whitelist) - // return undefined; + return undefined; } } diff --git a/UI/ShowDataLayer/TileHierarchyAggregator.ts b/UI/ShowDataLayer/TileHierarchyAggregator.ts index cdaa5e420..c8a19ab5f 100644 --- a/UI/ShowDataLayer/TileHierarchyAggregator.ts +++ b/UI/ShowDataLayer/TileHierarchyAggregator.ts @@ -159,10 +159,8 @@ export class TileHierarchyAggregator implements FeatureSource { const self = this const empty = [] return new StaticFeatureSource( - locationControl.map(loc => { - const targetZoom = loc.zoom - - if(targetZoom > clusteringConfig.maxZoom){ + locationControl.map(loc => loc.zoom).map(targetZoom => { + if(targetZoom-1 > clusteringConfig.maxZoom){ return empty } diff --git a/assets/themes/natuurpunt/natuurpunt.json b/assets/themes/natuurpunt/natuurpunt.json index 54effec90..ba5930207 100644 --- a/assets/themes/natuurpunt/natuurpunt.json +++ b/assets/themes/natuurpunt/natuurpunt.json @@ -32,7 +32,7 @@ "enablePdfDownload": true, "enableDownload": true, "hideFromOverview": true, - "#": "Disable clustering for this theme", + "#": "Disable clustering for this theme", "clustering": { "maxZoom": 0 }, @@ -71,7 +71,6 @@ ] }, "geoJson": "https://pietervdvn.github.io/natuurpunt_cache/natuurpunt_nature_reserve_points.geojson", - "geoJsonZoomLevel": 0, "isOsmCache": "duplicate" }, "minzoom": 1, diff --git a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json index 489c36ed7..ce9864c20 100644 --- a/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json +++ b/assets/themes/toerisme_vlaanderen/toerisme_vlaanderen.json @@ -14,7 +14,7 @@ "nl": "Een kaart om toeristisch relevante info op aan te duiden" }, "description": { - "nl": "Op deze kaart kan je info zien die relevant is voor toerisme, zoals:
  • Eetgelegenheden
  • Cafés en bars
  • (Fiets)oplaadpunten
  • Fietspompen, fietserverhuur en fietswinkels
  • Uitkijktorens
  • ...
Zie je fouten op de kaart? Dan kan je zelf makkelijk aanpasingen maken, die zichtbaar zijn voor iedereen. Hiervoor dien je een gratis OpenStreetMap account voor te maken." + "nl": "Op deze kaart kan je info zien die relevant is voor toerisme, zoals:
  • Eetgelegenheden
  • Cafés en bars
  • (Fiets)oplaadpunten
  • Fietspompen, fietserverhuur en fietswinkels
  • Uitkijktorens
  • ...
Zie je fouten op de kaart? Dan kan je zelf makkelijk aanpasingen maken, die zichtbaar zijn voor iedereen. Hiervoor dien je een gratis OpenStreetMap account voor te maken.

Met de steun van Toerisme Vlaanderen" }, "descriptionTail": { "nl": "Met de steun van Toerisme Vlaanderen" diff --git a/assets/themes/uk_addresses/uk_addresses.json b/assets/themes/uk_addresses/uk_addresses.json index 67cf0c600..273c5f8d9 100644 --- a/assets/themes/uk_addresses/uk_addresses.json +++ b/assets/themes/uk_addresses/uk_addresses.json @@ -21,19 +21,9 @@ "widenFactor": 1.01, "socialImage": "", "hideFromOverview": true, - "lockLocation": [ - [ - 51.51818357322121, - -0.09293317794799805 - ], - [ - 51.52898437160955, - -0.08147478103637695 - ] - ], "clustering": { "minNeededFeatures": 25, - "maxZoom": 17 + "maxZoom": 16 }, "layers": [ { diff --git a/scripts/generateCache.ts b/scripts/generateCache.ts index c7fc2f04b..9bf879023 100644 --- a/scripts/generateCache.ts +++ b/scripts/generateCache.ts @@ -219,7 +219,7 @@ function sliceToTiles(allFeatures: FeatureSource, theme: LayoutConfig, relations } // Lets save this tile! const [z, x, y] = Tiles.tile_from_index(tile.tileIndex) - console.log("Writing tile ", z, x, y, layerId) + // console.log("Writing tile ", z, x, y, layerId) const targetPath = geoJsonName(targetdir + "_" + layerId, x, y, z) createdTiles.push(tile.tileIndex) // This is the geojson file containing all features for this tile @@ -241,6 +241,7 @@ function sliceToTiles(allFeatures: FeatureSource, theme: LayoutConfig, relations } perX[key].push(y) }) + console.log("Written overview: ", path, "with ", createdTiles.length, "tiles") writeFileSync(path, JSON.stringify(perX)) // And, if needed, to create a points-only layer From 54edcf793b28445e8bed43ad4c508c8b9c6f5afe Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 13 Oct 2021 11:34:25 +0200 Subject: [PATCH 25/26] Handle redirects --- Logic/Web/Wikidata.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Logic/Web/Wikidata.ts b/Logic/Web/Wikidata.ts index 4c9fd5081..571d94859 100644 --- a/Logic/Web/Wikidata.ts +++ b/Logic/Web/Wikidata.ts @@ -295,7 +295,9 @@ export default class Wikidata { } const url = "https://www.wikidata.org/wiki/Special:EntityData/" + id + ".json"; - const response = (await Utils.downloadJson(url)).entities[id] + const entities = (await Utils.downloadJson(url)).entities + const firstKey = Array.from(Object.keys(entities))[0] // Roundabout way to fetch the entity; it might have been a redirect + const response = entities[firstKey] if (id.startsWith("L")) { // This is a lexeme: From ab05979b81b52d029024144bf44cd94e27e4bae8 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Wed, 13 Oct 2021 17:18:14 +0200 Subject: [PATCH 26/26] Fix popup which doesn't show up in the case of duplicate elements on the map --- UI/ShowDataLayer/ShowDataLayer.ts | 10 +++++++--- UI/SpecialVisualizations.ts | 13 ++++++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/UI/ShowDataLayer/ShowDataLayer.ts b/UI/ShowDataLayer/ShowDataLayer.ts index a0244a33f..5e8681bbf 100644 --- a/UI/ShowDataLayer/ShowDataLayer.ts +++ b/UI/ShowDataLayer/ShowDataLayer.ts @@ -6,6 +6,7 @@ import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; import FeatureInfoBox from "../Popup/FeatureInfoBox"; import State from "../../State"; import {ShowDataLayerOptions} from "./ShowDataLayerOptions"; +import {FixedUiElement} from "../Base/FixedUiElement"; export default class ShowDataLayer { @@ -28,9 +29,13 @@ export default class ShowDataLayer { */ private readonly leafletLayersPerId = new Map() + private readonly showDataLayerid : number; + private static dataLayerIds = 0 constructor(options: ShowDataLayerOptions & { layerToShow: LayerConfig }) { this._leafletMap = options.leafletMap; + this.showDataLayerid = ShowDataLayer.dataLayerIds; + ShowDataLayer.dataLayerIds++ this._enablePopups = options.enablePopups ?? true; if (options.features === undefined) { throw "Invalid ShowDataLayer invocation" @@ -221,9 +226,8 @@ export default class ShowDataLayer { let infobox: FeatureInfoBox = undefined; - const id = `popup-${feature.properties.id}-${feature.geometry.type}-${this._cleanCount}` - popup.setContent(`
Popup for ${feature.properties.id} ${feature.geometry.type}
`) - + const id = `popup-${feature.properties.id}-${feature.geometry.type}-${this.showDataLayerid}-${this._cleanCount}` + popup.setContent(`
Popup for ${feature.properties.id} ${feature.geometry.type} ${id} is loading
`) leafletLayer.on("popupopen", () => { if (infobox === undefined) { const tags = State.state.allElements.getEventSourceById(feature.properties.id); diff --git a/UI/SpecialVisualizations.ts b/UI/SpecialVisualizations.ts index 3af7df316..24c87b821 100644 --- a/UI/SpecialVisualizations.ts +++ b/UI/SpecialVisualizations.ts @@ -502,7 +502,18 @@ There are also some technicalities in your theme to keep in mind: const text = args[2] const autoapply = args[3]?.toLowerCase() === "true" const overwrite = args[4]?.toLowerCase() === "true" - const featureIds : UIEventSource = tagsSource.map(tags => JSON.parse(tags[featureIdsKey])) + const featureIds : UIEventSource = tagsSource.map(tags => { + const ids = tags[featureIdsKey] + try{ + if(ids === undefined){ + return [] + } + return JSON.parse(ids); + }catch(e){ + console.warn("Could not parse ", ids, "as JSON to extract IDS which should be shown on the map.") + return [] + } + }) return new MultiApply( { featureIds,