add mapping of geojson IRVE to osm tags
This commit is contained in:
parent
aaf00bd4ba
commit
975850a7e1
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,384 @@
|
||||||
|
{
|
||||||
|
"count": 18,
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"lat": 50.0743484,
|
||||||
|
"lng": 1.537268,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 33
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 49.6465569,
|
||||||
|
"lng": 0.595749,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 31
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 49.9614983,
|
||||||
|
"lng": 1.1935092,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 26
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 50.1074982,
|
||||||
|
"lng": 1.8426746,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 24
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 50.2155533,
|
||||||
|
"lng": 1.628114,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 22
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 49.6115227,
|
||||||
|
"lng": 0.7733023,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 21
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 49.9128304,
|
||||||
|
"lng": 1.0857821,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 49.8144035,
|
||||||
|
"lng": 0.657026,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 16
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 49.8280449,
|
||||||
|
"lng": 0.911511,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 49.5984917,
|
||||||
|
"lng": 1.1111569,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 14
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 49.6525497,
|
||||||
|
"lng": 1.6158921,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 49.7663574,
|
||||||
|
"lng": 1.7457,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 49.9557304,
|
||||||
|
"lng": 1.767372,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 49.8437424,
|
||||||
|
"lng": 1.7790869,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 49.6544685,
|
||||||
|
"lng": 1.832823,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 49.5701447,
|
||||||
|
"lng": 0.4898517,
|
||||||
|
"icon": "cluster.png",
|
||||||
|
"type": "cluster",
|
||||||
|
"count": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 49.5702896,
|
||||||
|
"lng": 1.609848,
|
||||||
|
"icon": "icon-accelerated_on.png",
|
||||||
|
"type": "pool",
|
||||||
|
"pool": {
|
||||||
|
"amenities": [],
|
||||||
|
"city": "Saumont-la-Poterie",
|
||||||
|
"real_time_available": true,
|
||||||
|
"rating": null,
|
||||||
|
"i18n_country_id": 67,
|
||||||
|
"emsps": [],
|
||||||
|
"gps_coordinates": {
|
||||||
|
"lon": 1.609848,
|
||||||
|
"lat": 49.5702896
|
||||||
|
},
|
||||||
|
"street_name": "358 Route de Paris ",
|
||||||
|
"speed": {
|
||||||
|
"icon": "accelerated.svg",
|
||||||
|
"self": "charging_speeds/3.json",
|
||||||
|
"id": 3,
|
||||||
|
"map_icon": "accelerated.png"
|
||||||
|
},
|
||||||
|
"should_check_prices": true,
|
||||||
|
"number": null,
|
||||||
|
"schedules": [],
|
||||||
|
"object_state_id": 2,
|
||||||
|
"is_indoor": false,
|
||||||
|
"id": 285402,
|
||||||
|
"slug": "eco-pi-saumont-la-poterie-358-route-de-paris",
|
||||||
|
"can_remote_start_charge": false,
|
||||||
|
"statistic": {
|
||||||
|
"global_note_average": null,
|
||||||
|
"price_note_average": null,
|
||||||
|
"location_note_average": null,
|
||||||
|
"security_note_average": null,
|
||||||
|
"comments_count": 0,
|
||||||
|
"reports_count": 0,
|
||||||
|
"checkins_count": 0,
|
||||||
|
"material_note_average": null,
|
||||||
|
"creation_date": "2023-07-29T02:04:10+00:00",
|
||||||
|
"ratings_count": 1
|
||||||
|
},
|
||||||
|
"can_update_charging_pool": false,
|
||||||
|
"is_always_open": true,
|
||||||
|
"can_charge_with_chargemap": true,
|
||||||
|
"location_type_id": 21,
|
||||||
|
"network_id": 2340,
|
||||||
|
"evse_emi3_ids": [
|
||||||
|
"FR*EPI*E11734505*1"
|
||||||
|
],
|
||||||
|
"charging_connectors": [
|
||||||
|
{
|
||||||
|
"count": 5,
|
||||||
|
"available_count": 3,
|
||||||
|
"evse_ids": [
|
||||||
|
701375,
|
||||||
|
701376,
|
||||||
|
701379,
|
||||||
|
701377,
|
||||||
|
701378
|
||||||
|
],
|
||||||
|
"type": "MENNEKES_TYPE_2",
|
||||||
|
"connector_type": {
|
||||||
|
"id": 14,
|
||||||
|
"icon": "type2"
|
||||||
|
},
|
||||||
|
"power_max": 22
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"is_free": false,
|
||||||
|
"name": "Eco-PI - Saumont-la-Poterie - 358 Route de Paris ",
|
||||||
|
"location_type_slug": "unknown",
|
||||||
|
"charging_speed_id": 3,
|
||||||
|
"postal_code": "76440",
|
||||||
|
"country_code": "FR",
|
||||||
|
"is_tesla": false,
|
||||||
|
"evses": [
|
||||||
|
{
|
||||||
|
"id": 701375,
|
||||||
|
"is_available": true,
|
||||||
|
"realtime_state": "AVAILABLE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 701376,
|
||||||
|
"is_available": true,
|
||||||
|
"realtime_state": "AVAILABLE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 701379,
|
||||||
|
"is_available": true,
|
||||||
|
"realtime_state": "AVAILABLE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 701377,
|
||||||
|
"is_available": false,
|
||||||
|
"realtime_state": "OUT_OF_ORDER"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 701378,
|
||||||
|
"is_available": false,
|
||||||
|
"realtime_state": "OUT_OF_ORDER"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lat": 49.5693893,
|
||||||
|
"lng": 0.953997,
|
||||||
|
"icon": "icon-accelerated_on.png",
|
||||||
|
"type": "pool",
|
||||||
|
"pool": {
|
||||||
|
"amenities": [
|
||||||
|
"drinks",
|
||||||
|
"restoration",
|
||||||
|
"shop",
|
||||||
|
"restroom"
|
||||||
|
],
|
||||||
|
"city": "Pavilly",
|
||||||
|
"real_time_available": true,
|
||||||
|
"rating": 4,
|
||||||
|
"i18n_country_id": 67,
|
||||||
|
"emsps": [
|
||||||
|
10,
|
||||||
|
75,
|
||||||
|
77,
|
||||||
|
107,
|
||||||
|
108,
|
||||||
|
112
|
||||||
|
],
|
||||||
|
"gps_coordinates": {
|
||||||
|
"lon": 0.953997,
|
||||||
|
"lat": 49.5693893
|
||||||
|
},
|
||||||
|
"street_name": "Place du Président d'Esneval",
|
||||||
|
"speed": {
|
||||||
|
"icon": "accelerated.svg",
|
||||||
|
"self": "charging_speeds/3.json",
|
||||||
|
"id": 3,
|
||||||
|
"map_icon": "accelerated.png"
|
||||||
|
},
|
||||||
|
"should_check_prices": true,
|
||||||
|
"number": "4",
|
||||||
|
"schedules": [],
|
||||||
|
"object_state_id": 2,
|
||||||
|
"is_indoor": false,
|
||||||
|
"id": 105727,
|
||||||
|
"slug": "sde76-place-du-president-desneval-4-pavilly",
|
||||||
|
"can_remote_start_charge": false,
|
||||||
|
"statistic": {
|
||||||
|
"global_note_average": 4,
|
||||||
|
"price_note_average": 5,
|
||||||
|
"location_note_average": 2,
|
||||||
|
"security_note_average": 5,
|
||||||
|
"comments_count": 0,
|
||||||
|
"reports_count": 0,
|
||||||
|
"checkins_count": 25,
|
||||||
|
"material_note_average": 2,
|
||||||
|
"creation_date": "2023-07-29T02:01:25+00:00",
|
||||||
|
"ratings_count": 1
|
||||||
|
},
|
||||||
|
"can_update_charging_pool": false,
|
||||||
|
"is_always_open": true,
|
||||||
|
"can_charge_with_chargemap": true,
|
||||||
|
"location_type_id": 4,
|
||||||
|
"network_id": 404,
|
||||||
|
"evse_emi3_ids": [
|
||||||
|
"FR*S76*E100*1*1"
|
||||||
|
],
|
||||||
|
"charging_connectors": [
|
||||||
|
{
|
||||||
|
"count": 4,
|
||||||
|
"available_count": 2,
|
||||||
|
"evse_ids": [
|
||||||
|
25003,
|
||||||
|
25004,
|
||||||
|
390745,
|
||||||
|
390747
|
||||||
|
],
|
||||||
|
"type": "DOMESTIC_TYPE_F",
|
||||||
|
"connector_type": {
|
||||||
|
"id": 6,
|
||||||
|
"icon": "schuko"
|
||||||
|
},
|
||||||
|
"power_max": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"count": 7,
|
||||||
|
"available_count": 4,
|
||||||
|
"evse_ids": [
|
||||||
|
25003,
|
||||||
|
25004,
|
||||||
|
390745,
|
||||||
|
390747,
|
||||||
|
390662,
|
||||||
|
390663,
|
||||||
|
390664
|
||||||
|
],
|
||||||
|
"type": "MENNEKES_TYPE_2",
|
||||||
|
"connector_type": {
|
||||||
|
"id": 14,
|
||||||
|
"icon": "type2"
|
||||||
|
},
|
||||||
|
"power_max": 22
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"count": 3,
|
||||||
|
"available_count": 2,
|
||||||
|
"evse_ids": [
|
||||||
|
390662,
|
||||||
|
390663,
|
||||||
|
390664
|
||||||
|
],
|
||||||
|
"type": "DOMESTIC_TYPE_F",
|
||||||
|
"connector_type": {
|
||||||
|
"id": 6,
|
||||||
|
"icon": "schuko"
|
||||||
|
},
|
||||||
|
"power_max": 2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"is_free": false,
|
||||||
|
"name": "SDE76 - Place du Président d'Esneval, 4 - Pavilly",
|
||||||
|
"location_type_slug": "parking",
|
||||||
|
"charging_speed_id": 3,
|
||||||
|
"postal_code": "76570",
|
||||||
|
"country_code": "FR",
|
||||||
|
"is_tesla": false,
|
||||||
|
"evses": [
|
||||||
|
{
|
||||||
|
"id": 25003,
|
||||||
|
"is_available": true,
|
||||||
|
"realtime_state": "AVAILABLE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 25004,
|
||||||
|
"is_available": true,
|
||||||
|
"realtime_state": "AVAILABLE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 390745,
|
||||||
|
"is_available": false,
|
||||||
|
"realtime_state": "OUT_OF_ORDER"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 390747,
|
||||||
|
"is_available": false,
|
||||||
|
"realtime_state": "OUT_OF_ORDER"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 390662,
|
||||||
|
"is_available": false,
|
||||||
|
"realtime_state": "OUT_OF_ORDER"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 390663,
|
||||||
|
"is_available": true,
|
||||||
|
"realtime_state": "AVAILABLE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 390664,
|
||||||
|
"is_available": true,
|
||||||
|
"realtime_state": "AVAILABLE"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
/**
|
||||||
|
* convertisseur de données de bornes de recharge électrique à partir de données Chargemap et open data Etalab
|
||||||
|
*/
|
||||||
|
import fs from 'node-fs';
|
||||||
|
|
||||||
|
|
||||||
|
let show_debug = 0;
|
||||||
|
let limitConversionToFirstPoint = true;
|
||||||
|
// let sourceFileChargemapJson = './chargemap_data/hurepoix.json'
|
||||||
|
let sourceFileIRVEGeoJson = './etalab_data/consolidation-etalab-schema-irve-statique-v-2.2.0-20230727.json'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* plan de conversion des clés du jeu de données vers les tags OSM
|
||||||
|
*/
|
||||||
|
let mappingConfigIRVE = {
|
||||||
|
contact_operateur: "email", // ici, on souhaite convertir la clé contact_operateur=bidule en email=bidule
|
||||||
|
nom_amenageur: "operator",
|
||||||
|
telephone_operateur: "phone",
|
||||||
|
nbre_pdc: "chargin_point:count",
|
||||||
|
id_station_itinerance: "ref:EU:EVSE",
|
||||||
|
id_station_local: "ref",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function debugLog(message) {
|
||||||
|
if (!show_debug) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log('debug: ', ...message)
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertDataForIRVE(sourceFilePath, mapping) {
|
||||||
|
debugLog('convertDataFromChargemap from ', sourceFilePath);
|
||||||
|
|
||||||
|
let convertedGeoJson = {
|
||||||
|
type: 'FeatureCollection',
|
||||||
|
features: []
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.readFile(sourceFilePath, 'utf8', function (err, data) {
|
||||||
|
let pointcounter = 0;
|
||||||
|
if (err) {
|
||||||
|
return debugLog(err);
|
||||||
|
}
|
||||||
|
let dataTransformed = JSON.parse(data);
|
||||||
|
// debug('data keys ', Object.keys(dataTransformed))
|
||||||
|
|
||||||
|
debugLog('debug: properties of point 0', dataTransformed.features[0])
|
||||||
|
if (dataTransformed.features) {
|
||||||
|
|
||||||
|
debugLog('data found, features:', dataTransformed.features.length)
|
||||||
|
|
||||||
|
// find interesting list of points to use
|
||||||
|
let listOfPoints = dataTransformed.features
|
||||||
|
// for each point from the data source, convert with the mapping
|
||||||
|
|
||||||
|
listOfPoints.forEach(featurePoint => {
|
||||||
|
|
||||||
|
|
||||||
|
if (limitConversionToFirstPoint && (pointcounter < 2)) {
|
||||||
|
|
||||||
|
console.log('featurePoint', featurePoint)
|
||||||
|
|
||||||
|
let mappedPoint = mapElementFromConf(featurePoint, mapping)
|
||||||
|
debugLog('map one point', featurePoint, mappedPoint)
|
||||||
|
if (mappedPoint) {
|
||||||
|
convertedGeoJson.features.push(mappedPoint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pointcounter++;
|
||||||
|
|
||||||
|
})
|
||||||
|
// output new geojson
|
||||||
|
// write file on disk
|
||||||
|
writeJsonFile('my_converted_data_set.json', JSON.stringify(convertedGeoJson, null, 2))
|
||||||
|
|
||||||
|
debugLog('mapped output:', convertedGeoJson.features)
|
||||||
|
|
||||||
|
return convertedGeoJson;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* retuns the converted element from mapping config if present, null otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
function mapElementFromConf(featurePoint, mappingConfig) {
|
||||||
|
let mappingKeys = Object.keys(mappingConfig)
|
||||||
|
let featurePointPropertiesKeys = Object.keys(featurePoint.properties)
|
||||||
|
|
||||||
|
console.log('keys', mappingKeys, featurePointPropertiesKeys)
|
||||||
|
|
||||||
|
let newProperties = {}
|
||||||
|
|
||||||
|
// reinit properties of current point
|
||||||
|
let basePoint = Object.create(featurePoint)
|
||||||
|
basePoint.type = featurePoint.type
|
||||||
|
basePoint.geometry = featurePoint.geometry
|
||||||
|
basePoint.properties = newProperties
|
||||||
|
|
||||||
|
// apply new properties if found in mapping config
|
||||||
|
featurePointPropertiesKeys.forEach(pointKeyName => {
|
||||||
|
|
||||||
|
if (mappingKeys.indexOf(pointKeyName) !== -1) {
|
||||||
|
console.log('found element', pointKeyName, '=>', mappingConfig[pointKeyName], 'value : ', featurePoint.properties[pointKeyName])
|
||||||
|
newProperties[mappingConfig[pointKeyName]] = featurePoint.properties[pointKeyName]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('basePoint', basePoint)
|
||||||
|
return basePoint
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function writeJsonFile(fileName, fileContent) {
|
||||||
|
debugLog('write file ', fileName);
|
||||||
|
|
||||||
|
return fs.writeFile(
|
||||||
|
`./output/${fileName}`,
|
||||||
|
fileContent,
|
||||||
|
"utf8",
|
||||||
|
(err) => {
|
||||||
|
if (err) {
|
||||||
|
debugLog(`Error writing file: ${err}`);
|
||||||
|
} else {
|
||||||
|
debugLog(`File ${fileName} is written successfully!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
convertDataForIRVE(sourceFileIRVEGeoJson, mappingConfigIRVE)
|
||||||
|
|
||||||
|
// convertDataFromChargemap(sourceFileChargemapJson, mappingConfigIRVE)
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"type": "FeatureCollection",
|
||||||
|
"features": [
|
||||||
|
{
|
||||||
|
"type": "Feature",
|
||||||
|
"geometry": {
|
||||||
|
"type": "Point",
|
||||||
|
"coordinates": [
|
||||||
|
7.502904,
|
||||||
|
47.608214
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"operator": "ELECTRA",
|
||||||
|
"email": "help@electra.com",
|
||||||
|
"phone": "",
|
||||||
|
"ref:EU:EVSE": "FRELCPBLOHM",
|
||||||
|
"ref": "",
|
||||||
|
"chargin_point:count": "8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Feature",
|
||||||
|
"geometry": {
|
||||||
|
"type": "Point",
|
||||||
|
"coordinates": [
|
||||||
|
2.238392,
|
||||||
|
48.77325
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"operator": "ELECTRA",
|
||||||
|
"email": "help@electra.com",
|
||||||
|
"phone": "",
|
||||||
|
"ref:EU:EVSE": "FRELCPPLRBO",
|
||||||
|
"ref": "",
|
||||||
|
"chargin_point:count": "4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"name": "bornes elec irve osm",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"dependencies": {
|
||||||
|
"node-fs": "^0.1.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/node-fs": {
|
||||||
|
"version": "0.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fs/-/node-fs-0.1.7.tgz",
|
||||||
|
"integrity": "sha512-XqDBlmUKgDGe76+lZ/0sRBF3XW2vVcK07+ZPvdpUTK8jrvtPahUd0aBqJ9+ZjB01ANjZLuvK3O/eoMVmz62rpA==",
|
||||||
|
"os": [
|
||||||
|
"linux",
|
||||||
|
"darwin",
|
||||||
|
"freebsd",
|
||||||
|
"win32",
|
||||||
|
"smartos",
|
||||||
|
"sunos"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.1.97"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"node-fs": "^0.1.7"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue