udata 10.0.9.dev33787__py2.py3-none-any.whl → 10.0.9.dev33820__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of udata might be problematic. Click here for more details.

Files changed (48) hide show
  1. udata/commands/fixtures.py +42 -8
  2. udata/commands/tests/test_fixtures.py +12 -2
  3. udata/core/contact_point/api.py +13 -1
  4. udata/core/contact_point/api_fields.py +10 -1
  5. udata/core/contact_point/factories.py +3 -1
  6. udata/core/contact_point/forms.py +1 -0
  7. udata/core/contact_point/models.py +9 -1
  8. udata/core/dataservices/models.py +11 -4
  9. udata/core/dataservices/rdf.py +12 -6
  10. udata/core/dataset/api.py +1 -0
  11. udata/core/dataset/api_fields.py +3 -3
  12. udata/core/dataset/apiv2.py +5 -3
  13. udata/core/dataset/forms.py +4 -4
  14. udata/core/dataset/models.py +1 -1
  15. udata/core/dataset/rdf.py +23 -13
  16. udata/forms/fields.py +1 -4
  17. udata/harvest/tests/dcat/evian.json +1 -1
  18. udata/harvest/tests/test_dcat_backend.py +5 -5
  19. udata/migrations/2024-12-05-contact-point-is-now-a-list.py +33 -0
  20. udata/rdf.py +75 -44
  21. udata/static/chunks/{11.51d706fb9521c16976bc.js → 11.83535504cd650ea08f65.js} +3 -3
  22. udata/static/chunks/{11.51d706fb9521c16976bc.js.map → 11.83535504cd650ea08f65.js.map} +1 -1
  23. udata/static/chunks/{13.f29411b06be1883356a3.js → 13.d9c1735d14038b94c17e.js} +2 -2
  24. udata/static/chunks/{13.f29411b06be1883356a3.js.map → 13.d9c1735d14038b94c17e.js.map} +1 -1
  25. udata/static/chunks/{17.3bd0340930d4a314ce9c.js → 17.81c57c0dedf812e43013.js} +2 -2
  26. udata/static/chunks/{17.3bd0340930d4a314ce9c.js.map → 17.81c57c0dedf812e43013.js.map} +1 -1
  27. udata/static/chunks/{19.8da42e8359d72afc2618.js → 19.df16abde17a42033a7f8.js} +3 -3
  28. udata/static/chunks/{19.8da42e8359d72afc2618.js.map → 19.df16abde17a42033a7f8.js.map} +1 -1
  29. udata/static/chunks/{8.54e44b102164ae5e7a67.js → 8.462bb3029de008497675.js} +2 -2
  30. udata/static/chunks/{8.54e44b102164ae5e7a67.js.map → 8.462bb3029de008497675.js.map} +1 -1
  31. udata/static/common.js +1 -1
  32. udata/static/common.js.map +1 -1
  33. udata/tests/api/test_contact_points.py +36 -5
  34. udata/tests/api/test_dataservices_api.py +2 -2
  35. udata/tests/api/test_datasets_api.py +8 -6
  36. udata/tests/api/test_organizations_api.py +1 -0
  37. udata/tests/api/test_user_api.py +1 -0
  38. udata/tests/contact_point/test_contact_point_models.py +19 -0
  39. udata/tests/dataset/test_dataset_rdf.py +30 -3
  40. udata/tests/organization/test_organization_tasks.py +1 -0
  41. udata/tests/test_rdf.py +41 -7
  42. udata/translations/udata.pot +23 -7
  43. {udata-10.0.9.dev33787.dist-info → udata-10.0.9.dev33820.dist-info}/METADATA +2 -1
  44. {udata-10.0.9.dev33787.dist-info → udata-10.0.9.dev33820.dist-info}/RECORD +48 -46
  45. {udata-10.0.9.dev33787.dist-info → udata-10.0.9.dev33820.dist-info}/LICENSE +0 -0
  46. {udata-10.0.9.dev33787.dist-info → udata-10.0.9.dev33820.dist-info}/WHEEL +0 -0
  47. {udata-10.0.9.dev33787.dist-info → udata-10.0.9.dev33820.dist-info}/entry_points.txt +0 -0
  48. {udata-10.0.9.dev33787.dist-info → udata-10.0.9.dev33820.dist-info}/top_level.txt +0 -0
udata/static/common.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e){function __webpack_require__(c){if(a[c])return a[c].exports;var r=a[c]={exports:{},id:c,loaded:!1};return e[c].call(r.exports,r,r.exports,__webpack_require__),r.loaded=!0,r.exports}var c=window.webpackJsonp;window.webpackJsonp=function(f,d){for(var t,b,_=0,n=[];_<f.length;_++)b=f[_],r[b]&&n.push.apply(n,r[b]),r[b]=0;for(t in d){var i=d[t];switch(typeof i){case"object":e[t]=function(c){var a=c.slice(1),r=c[0];return function(c,f,d){e[r].apply(this,[c,f,d].concat(a))}}(i);break;case"function":e[t]=i;break;default:e[t]=e[i]}}for(c&&c(f,d);n.length;)n.shift().call(null,__webpack_require__);if(d[0])return a[0]=0,__webpack_require__(0)};var a={},r={31:0};__webpack_require__.e=function(e,c){if(0===r[e])return c.call(null,__webpack_require__);if(void 0!==r[e])r[e].push(c);else{r[e]=[c];var a=document.getElementsByTagName("head")[0],f=document.createElement("script");f.type="text/javascript",f.charset="utf-8",f.async=!0,f.src=__webpack_require__.p+"chunks/"+e+"."+{0:"4dd4f378428d1eed85c8",1:"0a96f54313c89e541ccb",2:"c67aa76cc078c193aed5",3:"174a03e48d267820919b",4:"98dca3045c034c154d5f",5:"0fa1408dae4e76b87b2e",6:"d663709d877baa44a71e",7:"896bbffe39433bb598f7",8:"54e44b102164ae5e7a67",9:"07515e5187f475bce828",10:"471164b2a9fe15614797",11:"51d706fb9521c16976bc",12:"1be61e0201691821bff6",13:"f29411b06be1883356a3",14:"bc3f6bc0a67517e7b30f",15:"2f5d8e3d4aa4c46188d7",16:"aaa39ef2d7e82594efc8",17:"3bd0340930d4a314ce9c",18:"56444ebd2456a4ba2201",19:"8da42e8359d72afc2618",20:"3d4e02d1205a3c9e26c5",21:"af1610ce169cf6d1cf4e",22:"6a69068a7dd9d767dea1",23:"663b89b79d755a70deef",24:"d149cf025cbbca231d88",25:"1fafd6424761185cc14b",26:"402064cda3665d56f7fc",27:"997802f273a0c88f7b6d",28:"e68c475c6ca1e2eec92c",29:"2f4a04c61d75f2ef18ab",30:"e97e10c9246818e2b4b2",32:"fbd87316da50d00bed4f",33:"98be721e901eda7ed45c"}[e]+".js",a.appendChild(f)}},__webpack_require__.m=e,__webpack_require__.c=a,__webpack_require__.p="/static/"}(function(e){for(var c in e)if(Object.prototype.hasOwnProperty.call(e,c))switch(typeof e[c]){case"function":break;case"object":e[c]=function(c){var a=c.slice(1),r=e[c[0]];return function(e,c,f){r.apply(this,[e,c,f].concat(a))}}(e[c]);break;default:e[c]=e[e[c]]}return e}([]));
1
+ !function(e){function __webpack_require__(c){if(a[c])return a[c].exports;var r=a[c]={exports:{},id:c,loaded:!1};return e[c].call(r.exports,r,r.exports,__webpack_require__),r.loaded=!0,r.exports}var c=window.webpackJsonp;window.webpackJsonp=function(f,d){for(var t,b,_=0,n=[];_<f.length;_++)b=f[_],r[b]&&n.push.apply(n,r[b]),r[b]=0;for(t in d){var i=d[t];switch(typeof i){case"object":e[t]=function(c){var a=c.slice(1),r=c[0];return function(c,f,d){e[r].apply(this,[c,f,d].concat(a))}}(i);break;case"function":e[t]=i;break;default:e[t]=e[i]}}for(c&&c(f,d);n.length;)n.shift().call(null,__webpack_require__);if(d[0])return a[0]=0,__webpack_require__(0)};var a={},r={31:0};__webpack_require__.e=function(e,c){if(0===r[e])return c.call(null,__webpack_require__);if(void 0!==r[e])r[e].push(c);else{r[e]=[c];var a=document.getElementsByTagName("head")[0],f=document.createElement("script");f.type="text/javascript",f.charset="utf-8",f.async=!0,f.src=__webpack_require__.p+"chunks/"+e+"."+{0:"4dd4f378428d1eed85c8",1:"0a96f54313c89e541ccb",2:"c67aa76cc078c193aed5",3:"174a03e48d267820919b",4:"98dca3045c034c154d5f",5:"0fa1408dae4e76b87b2e",6:"d663709d877baa44a71e",7:"896bbffe39433bb598f7",8:"462bb3029de008497675",9:"07515e5187f475bce828",10:"471164b2a9fe15614797",11:"83535504cd650ea08f65",12:"1be61e0201691821bff6",13:"d9c1735d14038b94c17e",14:"bc3f6bc0a67517e7b30f",15:"2f5d8e3d4aa4c46188d7",16:"aaa39ef2d7e82594efc8",17:"81c57c0dedf812e43013",18:"56444ebd2456a4ba2201",19:"df16abde17a42033a7f8",20:"3d4e02d1205a3c9e26c5",21:"af1610ce169cf6d1cf4e",22:"6a69068a7dd9d767dea1",23:"663b89b79d755a70deef",24:"d149cf025cbbca231d88",25:"1fafd6424761185cc14b",26:"402064cda3665d56f7fc",27:"997802f273a0c88f7b6d",28:"e68c475c6ca1e2eec92c",29:"2f4a04c61d75f2ef18ab",30:"e97e10c9246818e2b4b2",32:"fbd87316da50d00bed4f",33:"98be721e901eda7ed45c"}[e]+".js",a.appendChild(f)}},__webpack_require__.m=e,__webpack_require__.c=a,__webpack_require__.p="/static/"}(function(e){for(var c in e)if(Object.prototype.hasOwnProperty.call(e,c))switch(typeof e[c]){case"function":break;case"object":e[c]=function(c){var a=c.slice(1),r=e[c[0]];return function(e,c,f){r.apply(this,[e,c,f].concat(a))}}(e[c]);break;default:e[c]=e[e[c]]}return e}([]));
2
2
  //# sourceMappingURL=common.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["webpack:///common.js","webpack:///webpack/bootstrap b2cfb2bdd2ebf74cbb17"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","id","loaded","call","parentJsonpFunction","window","chunkIds","moreModules","chunkId","i","callbacks","length","installedChunks","push","apply","_m","args","slice","templateId","a","b","c","this","concat","shift","31","e","callback","undefined","head","document","getElementsByTagName","script","createElement","type","charset","async","src","p","0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","32","33","appendChild","m","Object","prototype","hasOwnProperty","fn"],"mappings":"CAAS,SAAUA,GCwDnB,QAAAC,qBAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAE,OAGA,IAAAC,GAAAF,EAAAD,IACAE,WACAE,GAAAJ,EACAK,QAAA,EAUA,OANAP,GAAAE,GAAAM,KAAAH,EAAAD,QAAAC,IAAAD,QAAAH,qBAGAI,EAAAE,QAAA,EAGAF,EAAAD,QA3EA,GAAAK,GAAAC,OAAA,YACAA,QAAA,sBAAAC,EAAAC,GAIA,IADA,GAAAV,GAAAW,EAAAC,EAAA,EAAAC,KACQD,EAAAH,EAAAK,OAAoBF,IAC5BD,EAAAF,EAAAG,GACAG,EAAAJ,IACAE,EAAAG,KAAAC,MAAAJ,EAAAE,EAAAJ,IACAI,EAAAJ,GAAA,CAEA,KAAAX,IAAAU,GAAA,CACA,GAAAQ,GAAAR,EAAAV,EAGA,cAAAkB,IACA,aAEApB,EAAAE,GAAA,SAAAkB,GACA,GAAAC,GAAAD,EAAAE,MAAA,GAAAC,EAAAH,EAAA,EACA,iBAAAI,EAAAC,EAAAC,GACA1B,EAAAuB,GAAAJ,MAAAQ,MAAAH,EAAAC,EAAAC,GAAAE,OAAAP,MAEMD,EACN,MACA,gBAEApB,EAAAE,GAAAkB,CACA,MACA,SAEApB,EAAAE,GAAAF,EAAAoB,IAKA,IADAX,KAAAE,EAAAC,GACAG,EAAAC,QACAD,EAAAc,QAAArB,KAAA,KAAAP,oBACA,IAAAW,EAAA,GAEA,MADAT,GAAA,KACAF,oBAAA,GAKA,IAAAE,MAKAc,GACAa,GAAA,EA6BA7B,qBAAA8B,EAAA,SAAAlB,EAAAmB,GAEA,OAAAf,EAAAJ,GACA,MAAAmB,GAAAxB,KAAA,KAAAP,oBAGA,IAAAgC,SAAAhB,EAAAJ,GACAI,EAAAJ,GAAAK,KAAAc,OACI,CAEJf,EAAAJ,IAAAmB,EACA,IAAAE,GAAAC,SAAAC,qBAAA,WACAC,EAAAF,SAAAG,cAAA,SACAD,GAAAE,KAAA,kBACAF,EAAAG,QAAA,QACAH,EAAAI,OAAA,EAEAJ,EAAAK,IAAAzC,oBAAA0C,EAAA,UAAA9B,EAAA,KAAsE+B,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,wBAAk5B/D,GAAA,MACx9BqB,EAAA2C,YAAAxC,KAKApC,oBAAA6E,EAAA9E,EAGAC,oBAAAyB,EAAAvB,EAGAF,oBAAA0C,EAAA,YDIW,SAAS3C,GAEnB,IAAI,GAAIc,KAAKd,GACZ,GAAG+E,OAAOC,UAAUC,eAAezE,KAAKR,EAASc,GAChD,aAAcd,GAAQc,IACtB,IAAK,WAAY,KACjB,KAAK,SAEJd,EAAQc,GAAM,SAASM,GACtB,GAAIC,GAAOD,EAAGE,MAAM,GAAI4D,EAAKlF,EAAQoB,EAAG,GACxC,OAAO,UAAUI,EAAEC,EAAEC,GACpBwD,EAAG/D,MAAMQ,MAAOH,EAAEC,EAAEC,GAAGE,OAAOP,MAE9BrB,EAAQc,GACV,MACD,SAECd,EAAQc,GAAKd,EAAQA,EAAQc,IAKhC,MAAOd","file":"common.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// install a JSONP callback for chunk loading\n/******/ \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n/******/ \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules) {\n/******/ \t\t// add \"moreModules\" to the modules object,\n/******/ \t\t// then flag all \"chunkIds\" as loaded and fire callback\n/******/ \t\tvar moduleId, chunkId, i = 0, callbacks = [];\n/******/ \t\tfor(;i < chunkIds.length; i++) {\n/******/ \t\t\tchunkId = chunkIds[i];\n/******/ \t\t\tif(installedChunks[chunkId])\n/******/ \t\t\t\tcallbacks.push.apply(callbacks, installedChunks[chunkId]);\n/******/ \t\t\tinstalledChunks[chunkId] = 0;\n/******/ \t\t}\n/******/ \t\tfor(moduleId in moreModules) {\n/******/ \t\t\tvar _m = moreModules[moduleId];\n/******/\n/******/ \t\t\t// Check if module is deduplicated\n/******/ \t\t\tswitch(typeof _m) {\n/******/ \t\t\tcase \"object\":\n/******/ \t\t\t\t// Module can be created from a template\n/******/ \t\t\t\tmodules[moduleId] = (function(_m) {\n/******/ \t\t\t\t\tvar args = _m.slice(1), templateId = _m[0];\n/******/ \t\t\t\t\treturn function (a,b,c) {\n/******/ \t\t\t\t\t\tmodules[templateId].apply(this, [a,b,c].concat(args));\n/******/ \t\t\t\t\t};\n/******/ \t\t\t\t}(_m));\n/******/ \t\t\t\tbreak;\n/******/ \t\t\tcase \"function\":\n/******/ \t\t\t\t// Normal module\n/******/ \t\t\t\tmodules[moduleId] = _m;\n/******/ \t\t\t\tbreak;\n/******/ \t\t\tdefault:\n/******/ \t\t\t\t// Module is a copy of another module\n/******/ \t\t\t\tmodules[moduleId] = modules[_m];\n/******/ \t\t\t\tbreak;\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);\n/******/ \t\twhile(callbacks.length)\n/******/ \t\t\tcallbacks.shift().call(null, __webpack_require__);\n/******/ \t\tif(moreModules[0]) {\n/******/ \t\t\tinstalledModules[0] = 0;\n/******/ \t\t\treturn __webpack_require__(0);\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// object to store loaded and loading chunks\n/******/ \t// \"0\" means \"already loaded\"\n/******/ \t// Array means \"loading\", array contains callbacks\n/******/ \tvar installedChunks = {\n/******/ \t\t31:0\n/******/ \t};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/ \t// This file contains only the entry chunk.\n/******/ \t// The chunk loading function for additional chunks\n/******/ \t__webpack_require__.e = function requireEnsure(chunkId, callback) {\n/******/ \t\t// \"0\" is the signal for \"already loaded\"\n/******/ \t\tif(installedChunks[chunkId] === 0)\n/******/ \t\t\treturn callback.call(null, __webpack_require__);\n/******/\n/******/ \t\t// an array means \"currently loading\".\n/******/ \t\tif(installedChunks[chunkId] !== undefined) {\n/******/ \t\t\tinstalledChunks[chunkId].push(callback);\n/******/ \t\t} else {\n/******/ \t\t\t// start chunk loading\n/******/ \t\t\tinstalledChunks[chunkId] = [callback];\n/******/ \t\t\tvar head = document.getElementsByTagName('head')[0];\n/******/ \t\t\tvar script = document.createElement('script');\n/******/ \t\t\tscript.type = 'text/javascript';\n/******/ \t\t\tscript.charset = 'utf-8';\n/******/ \t\t\tscript.async = true;\n/******/\n/******/ \t\t\tscript.src = __webpack_require__.p + \"chunks/\" + chunkId + \".\" + {\"0\":\"4dd4f378428d1eed85c8\",\"1\":\"0a96f54313c89e541ccb\",\"2\":\"c67aa76cc078c193aed5\",\"3\":\"174a03e48d267820919b\",\"4\":\"98dca3045c034c154d5f\",\"5\":\"0fa1408dae4e76b87b2e\",\"6\":\"d663709d877baa44a71e\",\"7\":\"896bbffe39433bb598f7\",\"8\":\"54e44b102164ae5e7a67\",\"9\":\"07515e5187f475bce828\",\"10\":\"471164b2a9fe15614797\",\"11\":\"51d706fb9521c16976bc\",\"12\":\"1be61e0201691821bff6\",\"13\":\"f29411b06be1883356a3\",\"14\":\"bc3f6bc0a67517e7b30f\",\"15\":\"2f5d8e3d4aa4c46188d7\",\"16\":\"aaa39ef2d7e82594efc8\",\"17\":\"3bd0340930d4a314ce9c\",\"18\":\"56444ebd2456a4ba2201\",\"19\":\"8da42e8359d72afc2618\",\"20\":\"3d4e02d1205a3c9e26c5\",\"21\":\"af1610ce169cf6d1cf4e\",\"22\":\"6a69068a7dd9d767dea1\",\"23\":\"663b89b79d755a70deef\",\"24\":\"d149cf025cbbca231d88\",\"25\":\"1fafd6424761185cc14b\",\"26\":\"402064cda3665d56f7fc\",\"27\":\"997802f273a0c88f7b6d\",\"28\":\"e68c475c6ca1e2eec92c\",\"29\":\"2f4a04c61d75f2ef18ab\",\"30\":\"e97e10c9246818e2b4b2\",\"32\":\"fbd87316da50d00bed4f\",\"33\":\"98be721e901eda7ed45c\"}[chunkId] + \".js\";\n/******/ \t\t\thead.appendChild(script);\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/static/\";\n/******/ })\n/************************************************************************/\n/******/ ((function(modules) {\n\t// Check all modules for deduplicated modules\n\tfor(var i in modules) {\n\t\tif(Object.prototype.hasOwnProperty.call(modules, i)) {\n\t\t\tswitch(typeof modules[i]) {\n\t\t\tcase \"function\": break;\n\t\t\tcase \"object\":\n\t\t\t\t// Module can be created from a template\n\t\t\t\tmodules[i] = (function(_m) {\n\t\t\t\t\tvar args = _m.slice(1), fn = modules[_m[0]];\n\t\t\t\t\treturn function (a,b,c) {\n\t\t\t\t\t\tfn.apply(this, [a,b,c].concat(args));\n\t\t\t\t\t};\n\t\t\t\t}(modules[i]));\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// Module is a copy of another module\n\t\t\t\tmodules[i] = modules[modules[i]];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn modules;\n}([])));\n\n\n/** WEBPACK FOOTER **\n ** common.js\n **/"," \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, callbacks = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId])\n \t\t\t\tcallbacks.push.apply(callbacks, installedChunks[chunkId]);\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tvar _m = moreModules[moduleId];\n\n \t\t\t// Check if module is deduplicated\n \t\t\tswitch(typeof _m) {\n \t\t\tcase \"object\":\n \t\t\t\t// Module can be created from a template\n \t\t\t\tmodules[moduleId] = (function(_m) {\n \t\t\t\t\tvar args = _m.slice(1), templateId = _m[0];\n \t\t\t\t\treturn function (a,b,c) {\n \t\t\t\t\t\tmodules[templateId].apply(this, [a,b,c].concat(args));\n \t\t\t\t\t};\n \t\t\t\t}(_m));\n \t\t\t\tbreak;\n \t\t\tcase \"function\":\n \t\t\t\t// Normal module\n \t\t\t\tmodules[moduleId] = _m;\n \t\t\t\tbreak;\n \t\t\tdefault:\n \t\t\t\t// Module is a copy of another module\n \t\t\t\tmodules[moduleId] = modules[_m];\n \t\t\t\tbreak;\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);\n \t\twhile(callbacks.length)\n \t\t\tcallbacks.shift().call(null, __webpack_require__);\n \t\tif(moreModules[0]) {\n \t\t\tinstalledModules[0] = 0;\n \t\t\treturn __webpack_require__(0);\n \t\t}\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// \"0\" means \"already loaded\"\n \t// Array means \"loading\", array contains callbacks\n \tvar installedChunks = {\n \t\t31:0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId, callback) {\n \t\t// \"0\" is the signal for \"already loaded\"\n \t\tif(installedChunks[chunkId] === 0)\n \t\t\treturn callback.call(null, __webpack_require__);\n\n \t\t// an array means \"currently loading\".\n \t\tif(installedChunks[chunkId] !== undefined) {\n \t\t\tinstalledChunks[chunkId].push(callback);\n \t\t} else {\n \t\t\t// start chunk loading\n \t\t\tinstalledChunks[chunkId] = [callback];\n \t\t\tvar head = document.getElementsByTagName('head')[0];\n \t\t\tvar script = document.createElement('script');\n \t\t\tscript.type = 'text/javascript';\n \t\t\tscript.charset = 'utf-8';\n \t\t\tscript.async = true;\n\n \t\t\tscript.src = __webpack_require__.p + \"chunks/\" + chunkId + \".\" + {\"0\":\"4dd4f378428d1eed85c8\",\"1\":\"0a96f54313c89e541ccb\",\"2\":\"c67aa76cc078c193aed5\",\"3\":\"174a03e48d267820919b\",\"4\":\"98dca3045c034c154d5f\",\"5\":\"0fa1408dae4e76b87b2e\",\"6\":\"d663709d877baa44a71e\",\"7\":\"896bbffe39433bb598f7\",\"8\":\"54e44b102164ae5e7a67\",\"9\":\"07515e5187f475bce828\",\"10\":\"471164b2a9fe15614797\",\"11\":\"51d706fb9521c16976bc\",\"12\":\"1be61e0201691821bff6\",\"13\":\"f29411b06be1883356a3\",\"14\":\"bc3f6bc0a67517e7b30f\",\"15\":\"2f5d8e3d4aa4c46188d7\",\"16\":\"aaa39ef2d7e82594efc8\",\"17\":\"3bd0340930d4a314ce9c\",\"18\":\"56444ebd2456a4ba2201\",\"19\":\"8da42e8359d72afc2618\",\"20\":\"3d4e02d1205a3c9e26c5\",\"21\":\"af1610ce169cf6d1cf4e\",\"22\":\"6a69068a7dd9d767dea1\",\"23\":\"663b89b79d755a70deef\",\"24\":\"d149cf025cbbca231d88\",\"25\":\"1fafd6424761185cc14b\",\"26\":\"402064cda3665d56f7fc\",\"27\":\"997802f273a0c88f7b6d\",\"28\":\"e68c475c6ca1e2eec92c\",\"29\":\"2f4a04c61d75f2ef18ab\",\"30\":\"e97e10c9246818e2b4b2\",\"32\":\"fbd87316da50d00bed4f\",\"33\":\"98be721e901eda7ed45c\"}[chunkId] + \".js\";\n \t\t\thead.appendChild(script);\n \t\t}\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/static/\";\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap b2cfb2bdd2ebf74cbb17\n **/"],"sourceRoot":""}
1
+ {"version":3,"sources":["webpack:///common.js","webpack:///webpack/bootstrap 00ce89df09d5b69563c2"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","id","loaded","call","parentJsonpFunction","window","chunkIds","moreModules","chunkId","i","callbacks","length","installedChunks","push","apply","_m","args","slice","templateId","a","b","c","this","concat","shift","31","e","callback","undefined","head","document","getElementsByTagName","script","createElement","type","charset","async","src","p","0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","32","33","appendChild","m","Object","prototype","hasOwnProperty","fn"],"mappings":"CAAS,SAAUA,GCwDnB,QAAAC,qBAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAE,OAGA,IAAAC,GAAAF,EAAAD,IACAE,WACAE,GAAAJ,EACAK,QAAA,EAUA,OANAP,GAAAE,GAAAM,KAAAH,EAAAD,QAAAC,IAAAD,QAAAH,qBAGAI,EAAAE,QAAA,EAGAF,EAAAD,QA3EA,GAAAK,GAAAC,OAAA,YACAA,QAAA,sBAAAC,EAAAC,GAIA,IADA,GAAAV,GAAAW,EAAAC,EAAA,EAAAC,KACQD,EAAAH,EAAAK,OAAoBF,IAC5BD,EAAAF,EAAAG,GACAG,EAAAJ,IACAE,EAAAG,KAAAC,MAAAJ,EAAAE,EAAAJ,IACAI,EAAAJ,GAAA,CAEA,KAAAX,IAAAU,GAAA,CACA,GAAAQ,GAAAR,EAAAV,EAGA,cAAAkB,IACA,aAEApB,EAAAE,GAAA,SAAAkB,GACA,GAAAC,GAAAD,EAAAE,MAAA,GAAAC,EAAAH,EAAA,EACA,iBAAAI,EAAAC,EAAAC,GACA1B,EAAAuB,GAAAJ,MAAAQ,MAAAH,EAAAC,EAAAC,GAAAE,OAAAP,MAEMD,EACN,MACA,gBAEApB,EAAAE,GAAAkB,CACA,MACA,SAEApB,EAAAE,GAAAF,EAAAoB,IAKA,IADAX,KAAAE,EAAAC,GACAG,EAAAC,QACAD,EAAAc,QAAArB,KAAA,KAAAP,oBACA,IAAAW,EAAA,GAEA,MADAT,GAAA,KACAF,oBAAA,GAKA,IAAAE,MAKAc,GACAa,GAAA,EA6BA7B,qBAAA8B,EAAA,SAAAlB,EAAAmB,GAEA,OAAAf,EAAAJ,GACA,MAAAmB,GAAAxB,KAAA,KAAAP,oBAGA,IAAAgC,SAAAhB,EAAAJ,GACAI,EAAAJ,GAAAK,KAAAc,OACI,CAEJf,EAAAJ,IAAAmB,EACA,IAAAE,GAAAC,SAAAC,qBAAA,WACAC,EAAAF,SAAAG,cAAA,SACAD,GAAAE,KAAA,kBACAF,EAAAG,QAAA,QACAH,EAAAI,OAAA,EAEAJ,EAAAK,IAAAzC,oBAAA0C,EAAA,UAAA9B,EAAA,KAAsE+B,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,wBAAk5B/D,GAAA,MACx9BqB,EAAA2C,YAAAxC,KAKApC,oBAAA6E,EAAA9E,EAGAC,oBAAAyB,EAAAvB,EAGAF,oBAAA0C,EAAA,YDIW,SAAS3C,GAEnB,IAAI,GAAIc,KAAKd,GACZ,GAAG+E,OAAOC,UAAUC,eAAezE,KAAKR,EAASc,GAChD,aAAcd,GAAQc,IACtB,IAAK,WAAY,KACjB,KAAK,SAEJd,EAAQc,GAAM,SAASM,GACtB,GAAIC,GAAOD,EAAGE,MAAM,GAAI4D,EAAKlF,EAAQoB,EAAG,GACxC,OAAO,UAAUI,EAAEC,EAAEC,GACpBwD,EAAG/D,MAAMQ,MAAOH,EAAEC,EAAEC,GAAGE,OAAOP,MAE9BrB,EAAQc,GACV,MACD,SAECd,EAAQc,GAAKd,EAAQA,EAAQc,IAKhC,MAAOd","file":"common.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// install a JSONP callback for chunk loading\n/******/ \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n/******/ \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules) {\n/******/ \t\t// add \"moreModules\" to the modules object,\n/******/ \t\t// then flag all \"chunkIds\" as loaded and fire callback\n/******/ \t\tvar moduleId, chunkId, i = 0, callbacks = [];\n/******/ \t\tfor(;i < chunkIds.length; i++) {\n/******/ \t\t\tchunkId = chunkIds[i];\n/******/ \t\t\tif(installedChunks[chunkId])\n/******/ \t\t\t\tcallbacks.push.apply(callbacks, installedChunks[chunkId]);\n/******/ \t\t\tinstalledChunks[chunkId] = 0;\n/******/ \t\t}\n/******/ \t\tfor(moduleId in moreModules) {\n/******/ \t\t\tvar _m = moreModules[moduleId];\n/******/\n/******/ \t\t\t// Check if module is deduplicated\n/******/ \t\t\tswitch(typeof _m) {\n/******/ \t\t\tcase \"object\":\n/******/ \t\t\t\t// Module can be created from a template\n/******/ \t\t\t\tmodules[moduleId] = (function(_m) {\n/******/ \t\t\t\t\tvar args = _m.slice(1), templateId = _m[0];\n/******/ \t\t\t\t\treturn function (a,b,c) {\n/******/ \t\t\t\t\t\tmodules[templateId].apply(this, [a,b,c].concat(args));\n/******/ \t\t\t\t\t};\n/******/ \t\t\t\t}(_m));\n/******/ \t\t\t\tbreak;\n/******/ \t\t\tcase \"function\":\n/******/ \t\t\t\t// Normal module\n/******/ \t\t\t\tmodules[moduleId] = _m;\n/******/ \t\t\t\tbreak;\n/******/ \t\t\tdefault:\n/******/ \t\t\t\t// Module is a copy of another module\n/******/ \t\t\t\tmodules[moduleId] = modules[_m];\n/******/ \t\t\t\tbreak;\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);\n/******/ \t\twhile(callbacks.length)\n/******/ \t\t\tcallbacks.shift().call(null, __webpack_require__);\n/******/ \t\tif(moreModules[0]) {\n/******/ \t\t\tinstalledModules[0] = 0;\n/******/ \t\t\treturn __webpack_require__(0);\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// object to store loaded and loading chunks\n/******/ \t// \"0\" means \"already loaded\"\n/******/ \t// Array means \"loading\", array contains callbacks\n/******/ \tvar installedChunks = {\n/******/ \t\t31:0\n/******/ \t};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/ \t// This file contains only the entry chunk.\n/******/ \t// The chunk loading function for additional chunks\n/******/ \t__webpack_require__.e = function requireEnsure(chunkId, callback) {\n/******/ \t\t// \"0\" is the signal for \"already loaded\"\n/******/ \t\tif(installedChunks[chunkId] === 0)\n/******/ \t\t\treturn callback.call(null, __webpack_require__);\n/******/\n/******/ \t\t// an array means \"currently loading\".\n/******/ \t\tif(installedChunks[chunkId] !== undefined) {\n/******/ \t\t\tinstalledChunks[chunkId].push(callback);\n/******/ \t\t} else {\n/******/ \t\t\t// start chunk loading\n/******/ \t\t\tinstalledChunks[chunkId] = [callback];\n/******/ \t\t\tvar head = document.getElementsByTagName('head')[0];\n/******/ \t\t\tvar script = document.createElement('script');\n/******/ \t\t\tscript.type = 'text/javascript';\n/******/ \t\t\tscript.charset = 'utf-8';\n/******/ \t\t\tscript.async = true;\n/******/\n/******/ \t\t\tscript.src = __webpack_require__.p + \"chunks/\" + chunkId + \".\" + {\"0\":\"4dd4f378428d1eed85c8\",\"1\":\"0a96f54313c89e541ccb\",\"2\":\"c67aa76cc078c193aed5\",\"3\":\"174a03e48d267820919b\",\"4\":\"98dca3045c034c154d5f\",\"5\":\"0fa1408dae4e76b87b2e\",\"6\":\"d663709d877baa44a71e\",\"7\":\"896bbffe39433bb598f7\",\"8\":\"462bb3029de008497675\",\"9\":\"07515e5187f475bce828\",\"10\":\"471164b2a9fe15614797\",\"11\":\"83535504cd650ea08f65\",\"12\":\"1be61e0201691821bff6\",\"13\":\"d9c1735d14038b94c17e\",\"14\":\"bc3f6bc0a67517e7b30f\",\"15\":\"2f5d8e3d4aa4c46188d7\",\"16\":\"aaa39ef2d7e82594efc8\",\"17\":\"81c57c0dedf812e43013\",\"18\":\"56444ebd2456a4ba2201\",\"19\":\"df16abde17a42033a7f8\",\"20\":\"3d4e02d1205a3c9e26c5\",\"21\":\"af1610ce169cf6d1cf4e\",\"22\":\"6a69068a7dd9d767dea1\",\"23\":\"663b89b79d755a70deef\",\"24\":\"d149cf025cbbca231d88\",\"25\":\"1fafd6424761185cc14b\",\"26\":\"402064cda3665d56f7fc\",\"27\":\"997802f273a0c88f7b6d\",\"28\":\"e68c475c6ca1e2eec92c\",\"29\":\"2f4a04c61d75f2ef18ab\",\"30\":\"e97e10c9246818e2b4b2\",\"32\":\"fbd87316da50d00bed4f\",\"33\":\"98be721e901eda7ed45c\"}[chunkId] + \".js\";\n/******/ \t\t\thead.appendChild(script);\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/static/\";\n/******/ })\n/************************************************************************/\n/******/ ((function(modules) {\n\t// Check all modules for deduplicated modules\n\tfor(var i in modules) {\n\t\tif(Object.prototype.hasOwnProperty.call(modules, i)) {\n\t\t\tswitch(typeof modules[i]) {\n\t\t\tcase \"function\": break;\n\t\t\tcase \"object\":\n\t\t\t\t// Module can be created from a template\n\t\t\t\tmodules[i] = (function(_m) {\n\t\t\t\t\tvar args = _m.slice(1), fn = modules[_m[0]];\n\t\t\t\t\treturn function (a,b,c) {\n\t\t\t\t\t\tfn.apply(this, [a,b,c].concat(args));\n\t\t\t\t\t};\n\t\t\t\t}(modules[i]));\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// Module is a copy of another module\n\t\t\t\tmodules[i] = modules[modules[i]];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn modules;\n}([])));\n\n\n/** WEBPACK FOOTER **\n ** common.js\n **/"," \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, callbacks = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId])\n \t\t\t\tcallbacks.push.apply(callbacks, installedChunks[chunkId]);\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tvar _m = moreModules[moduleId];\n\n \t\t\t// Check if module is deduplicated\n \t\t\tswitch(typeof _m) {\n \t\t\tcase \"object\":\n \t\t\t\t// Module can be created from a template\n \t\t\t\tmodules[moduleId] = (function(_m) {\n \t\t\t\t\tvar args = _m.slice(1), templateId = _m[0];\n \t\t\t\t\treturn function (a,b,c) {\n \t\t\t\t\t\tmodules[templateId].apply(this, [a,b,c].concat(args));\n \t\t\t\t\t};\n \t\t\t\t}(_m));\n \t\t\t\tbreak;\n \t\t\tcase \"function\":\n \t\t\t\t// Normal module\n \t\t\t\tmodules[moduleId] = _m;\n \t\t\t\tbreak;\n \t\t\tdefault:\n \t\t\t\t// Module is a copy of another module\n \t\t\t\tmodules[moduleId] = modules[_m];\n \t\t\t\tbreak;\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);\n \t\twhile(callbacks.length)\n \t\t\tcallbacks.shift().call(null, __webpack_require__);\n \t\tif(moreModules[0]) {\n \t\t\tinstalledModules[0] = 0;\n \t\t\treturn __webpack_require__(0);\n \t\t}\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// \"0\" means \"already loaded\"\n \t// Array means \"loading\", array contains callbacks\n \tvar installedChunks = {\n \t\t31:0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId, callback) {\n \t\t// \"0\" is the signal for \"already loaded\"\n \t\tif(installedChunks[chunkId] === 0)\n \t\t\treturn callback.call(null, __webpack_require__);\n\n \t\t// an array means \"currently loading\".\n \t\tif(installedChunks[chunkId] !== undefined) {\n \t\t\tinstalledChunks[chunkId].push(callback);\n \t\t} else {\n \t\t\t// start chunk loading\n \t\t\tinstalledChunks[chunkId] = [callback];\n \t\t\tvar head = document.getElementsByTagName('head')[0];\n \t\t\tvar script = document.createElement('script');\n \t\t\tscript.type = 'text/javascript';\n \t\t\tscript.charset = 'utf-8';\n \t\t\tscript.async = true;\n\n \t\t\tscript.src = __webpack_require__.p + \"chunks/\" + chunkId + \".\" + {\"0\":\"4dd4f378428d1eed85c8\",\"1\":\"0a96f54313c89e541ccb\",\"2\":\"c67aa76cc078c193aed5\",\"3\":\"174a03e48d267820919b\",\"4\":\"98dca3045c034c154d5f\",\"5\":\"0fa1408dae4e76b87b2e\",\"6\":\"d663709d877baa44a71e\",\"7\":\"896bbffe39433bb598f7\",\"8\":\"462bb3029de008497675\",\"9\":\"07515e5187f475bce828\",\"10\":\"471164b2a9fe15614797\",\"11\":\"83535504cd650ea08f65\",\"12\":\"1be61e0201691821bff6\",\"13\":\"d9c1735d14038b94c17e\",\"14\":\"bc3f6bc0a67517e7b30f\",\"15\":\"2f5d8e3d4aa4c46188d7\",\"16\":\"aaa39ef2d7e82594efc8\",\"17\":\"81c57c0dedf812e43013\",\"18\":\"56444ebd2456a4ba2201\",\"19\":\"df16abde17a42033a7f8\",\"20\":\"3d4e02d1205a3c9e26c5\",\"21\":\"af1610ce169cf6d1cf4e\",\"22\":\"6a69068a7dd9d767dea1\",\"23\":\"663b89b79d755a70deef\",\"24\":\"d149cf025cbbca231d88\",\"25\":\"1fafd6424761185cc14b\",\"26\":\"402064cda3665d56f7fc\",\"27\":\"997802f273a0c88f7b6d\",\"28\":\"e68c475c6ca1e2eec92c\",\"29\":\"2f4a04c61d75f2ef18ab\",\"30\":\"e97e10c9246818e2b4b2\",\"32\":\"fbd87316da50d00bed4f\",\"33\":\"98be721e901eda7ed45c\"}[chunkId] + \".js\";\n \t\t\thead.appendChild(script);\n \t\t}\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/static/\";\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 00ce89df09d5b69563c2\n **/"],"sourceRoot":""}
@@ -2,6 +2,7 @@ import pytest
2
2
  from flask import url_for
3
3
 
4
4
  from udata.core.contact_point.factories import ContactPointFactory
5
+ from udata.core.contact_point.models import CONTACT_ROLES
5
6
  from udata.core.organization.factories import OrganizationFactory
6
7
  from udata.core.organization.models import Member
7
8
  from udata.i18n import gettext as _
@@ -19,26 +20,31 @@ class ContactPointAPITest:
19
20
 
20
21
  def test_contact_point_api_create(self, api):
21
22
  api.login()
22
- data = {"name": faker.word(), "email": faker.email(), "contact_form": faker.url()}
23
+ data = {
24
+ "name": faker.word(),
25
+ "email": faker.email(),
26
+ "contact_form": faker.url(),
27
+ "role": "contact",
28
+ }
23
29
  response = api.post(url_for("api.contact_points"), data=data)
24
30
  assert201(response)
25
31
  assert ContactPoint.objects.count() == 1
26
32
 
27
33
  def test_contact_point_api_create_email_or_contact_form(self, api):
28
34
  api.login()
29
- data = {"name": faker.word(), "contact_form": faker.url()}
35
+ data = {"name": faker.word(), "contact_form": faker.url(), "role": "contact"}
30
36
  response = api.post(url_for("api.contact_points"), data=data)
31
37
  assert201(response)
32
38
  assert ContactPoint.objects.count() == 1
33
39
 
34
- data = {"name": faker.word(), "email": faker.email()}
40
+ data = {"name": faker.word(), "email": faker.email(), "role": "contact"}
35
41
  response = api.post(url_for("api.contact_points"), data=data)
36
42
  assert201(response)
37
43
  assert ContactPoint.objects.count() == 2
38
44
 
39
45
  def test_contact_point_api_invalid_email(self, api):
40
46
  api.login()
41
- data = {"name": faker.word(), "email": faker.word()}
47
+ data = {"name": faker.word(), "email": faker.word(), "role": "contact"}
42
48
  response = api.post(url_for("api.contact_points"), data=data)
43
49
  assert400(response)
44
50
  assert "email" in response.json["errors"]
@@ -46,7 +52,7 @@ class ContactPointAPITest:
46
52
 
47
53
  def test_contact_point_missing_contact_information(self, api):
48
54
  api.login()
49
- data = {"name": faker.word()}
55
+ data = {"name": faker.word(), "role": "contact"}
50
56
  response = api.post(url_for("api.contact_points"), data=data)
51
57
  assert400(response)
52
58
  assert response.json["message"] == _(
@@ -54,6 +60,25 @@ class ContactPointAPITest:
54
60
  )
55
61
  assert ContactPoint.objects.count() == 0
56
62
 
63
+ def test_contact_point_missing_role(self, api):
64
+ api.login()
65
+ data = {"name": faker.word(), "email": faker.email()}
66
+ response = api.post(url_for("api.contact_points"), data=data)
67
+ assert400(response)
68
+ assert response.json["message"] == _(
69
+ "ValidationError (ContactPoint:None) (Field is required: ['role'])"
70
+ )
71
+ assert ContactPoint.objects.count() == 0
72
+
73
+ def test_contact_point_no_need_for_email_for_role_other_than_contact(self, api):
74
+ api.login()
75
+ roles_other_than_contact = [role_ for role_ in CONTACT_ROLES.keys() if role_ != "contact"]
76
+ for index, role in enumerate(roles_other_than_contact):
77
+ data = {"name": faker.word(), "role": role}
78
+ response = api.post(url_for("api.contact_points"), data=data)
79
+ assert201(response)
80
+ assert ContactPoint.objects.count() == index + 1
81
+
57
82
  def test_contact_point_api_update(self, api):
58
83
  user = api.login()
59
84
  member = Member(user=user, role="editor")
@@ -86,6 +111,12 @@ class ContactPointAPITest:
86
111
  assert204(response)
87
112
  assert ContactPoint.objects.count() == 0
88
113
 
114
+ def test_contact_point_roles_list(self, api):
115
+ """It should fetch the contact point roles list from the API"""
116
+ response = api.get(url_for("api.contact_point_roles"))
117
+ assert200(response)
118
+ assert len(response.json) == len(CONTACT_ROLES)
119
+
89
120
  def test_contact_point_api_delete_forbidden(self, api):
90
121
  api.login()
91
122
  org = OrganizationFactory()
@@ -405,12 +405,12 @@ class DataserviceAPITest(APITestCase):
405
405
  {
406
406
  "title": "My title",
407
407
  "base_api_url": "https://example.org",
408
- "contact_point": "66212433e42ab56639ad516e",
408
+ "contact_points": ["66212433e42ab56639ad516e"],
409
409
  },
410
410
  )
411
411
  self.assert400(response)
412
412
  self.assertEqual(
413
- response.json["errors"]["contact_point"],
413
+ response.json["errors"]["contact_points"],
414
414
  ["Unknown reference '66212433e42ab56639ad516e'"],
415
415
  )
416
416
  self.assertEqual(Dataservice.objects.count(), 0)
@@ -755,6 +755,7 @@ class DatasetAPITest(APITestCase):
755
755
  "email": "mooneywayne@cobb-cochran.com",
756
756
  "name": "Martin Schultz",
757
757
  "organization": str(org.id),
758
+ "role": "contact",
758
759
  }
759
760
  response = self.post(url_for("api.contact_points"), contact_point_data)
760
761
  self.assert201(response)
@@ -767,19 +768,19 @@ class DatasetAPITest(APITestCase):
767
768
  dataset = DatasetFactory(organization=org)
768
769
  data = DatasetFactory.as_dict()
769
770
 
770
- data["contact_point"] = contact_point_id
771
+ data["contact_points"] = [contact_point_id]
771
772
  response = self.put(url_for("api.dataset", dataset=dataset), data)
772
773
  self.assert200(response)
773
774
 
774
775
  dataset = Dataset.objects.first()
775
- self.assertEqual(dataset.contact_point.name, contact_point_data["name"])
776
+ self.assertEqual(dataset.contact_points[0].name, contact_point_data["name"])
776
777
 
777
- data["contact_point"] = None
778
+ data["contact_points"] = None
778
779
  response = self.put(url_for("api.dataset", dataset=dataset), data)
779
780
  self.assert200(response)
780
781
 
781
782
  dataset.reload()
782
- self.assertEqual(dataset.contact_point, None)
783
+ self.assertEqual(dataset.contact_points, [])
783
784
 
784
785
  def test_dataset_api_update_contact_point_error(self):
785
786
  """It should update a dataset from the API"""
@@ -792,6 +793,7 @@ class DatasetAPITest(APITestCase):
792
793
  "email": "mooneywayne@cobb-cochran.com",
793
794
  "name": "Martin Schultz",
794
795
  "organization": str(org.id),
796
+ "role": "contact",
795
797
  }
796
798
  response = self.post(url_for("api.contact_points"), contact_point_data)
797
799
  self.assert201(response)
@@ -804,11 +806,11 @@ class DatasetAPITest(APITestCase):
804
806
  dataset = DatasetFactory(owner=self.user)
805
807
  data = DatasetFactory.as_dict()
806
808
 
807
- data["contact_point"] = contact_point_id
809
+ data["contact_points"] = [contact_point_id]
808
810
  response = self.put(url_for("api.dataset", dataset=dataset), data)
809
811
  self.assert400(response)
810
812
  self.assertEqual(
811
- response.json["errors"]["contact_point"][0],
813
+ response.json["errors"]["contact_points"][0],
812
814
  _("Wrong contact point id or contact point ownership mismatch"),
813
815
  )
814
816
 
@@ -921,6 +921,7 @@ class OrganizationContactPointsAPITest:
921
921
  "email": "mooneywayne@cobb-cochran.com",
922
922
  "name": "Martin Schultz",
923
923
  "organization": str(org.id),
924
+ "role": "contact",
924
925
  }
925
926
  response = api.post(url_for("api.contact_points"), data)
926
927
  assert201(response)
@@ -390,6 +390,7 @@ class UserAPITest(APITestCase):
390
390
  "email": "mooneywayne@cobb-cochran.com",
391
391
  "name": "Martin Schultz",
392
392
  "owner": str(user.id),
393
+ "role": "contact",
393
394
  }
394
395
 
395
396
  response = self.post(url_for("api.contact_points"), data)
@@ -0,0 +1,19 @@
1
+ import pytest
2
+
3
+ from udata.core.contact_point.factories import ContactPointFactory
4
+ from udata.models import db
5
+
6
+
7
+ @pytest.mark.usefixtures("clean_db")
8
+ class ContactPointTest:
9
+ def test_validate_contact_role_needs_email_or_contact_form(self):
10
+ with pytest.raises(db.ValidationError):
11
+ ContactPointFactory(role="contact", email=None, contact_form=None)
12
+ # The ContactPointFactory provides an email by default, so the following should not raise.
13
+ ContactPointFactory(role="contact", contact_form=None)
14
+ # The ContactPointFactory provides a contact_form by default, so the following should not raise.
15
+ ContactPointFactory(role="contact", email=None)
16
+
17
+ def test_validate_other_role_doesnt_need_an_email_or_contact_form(self):
18
+ ContactPointFactory(role="creator", email=None, contact_form=None)
19
+ ContactPointFactory(role="publisher", email=None, contact_form=None)
@@ -38,6 +38,7 @@ from udata.rdf import (
38
38
  DCATAP,
39
39
  DCT,
40
40
  FREQ,
41
+ GEODCAT,
41
42
  HVD_LEGISLATION,
42
43
  SCHEMA,
43
44
  SKOS,
@@ -95,6 +96,7 @@ class DatasetToRdfTest:
95
96
  name="Organization contact",
96
97
  email="hello@its.me",
97
98
  contact_form="https://data.support.com",
99
+ role="contact",
98
100
  )
99
101
  remote_url = "https://somewhere.org/dataset"
100
102
  dataset = DatasetFactory(
@@ -103,7 +105,7 @@ class DatasetToRdfTest:
103
105
  frequency="daily",
104
106
  acronym="acro",
105
107
  organization=org,
106
- contact_point=contact,
108
+ contact_points=[contact],
107
109
  harvest=HarvestDatasetMetadata(
108
110
  remote_url=remote_url, dct_identifier="foobar-identifier"
109
111
  ),
@@ -144,6 +146,31 @@ class DatasetToRdfTest:
144
146
  assert contact_rdf.value(VCARD.hasEmail).identifier == URIRef("mailto:hello@its.me")
145
147
  assert contact_rdf.value(VCARD.hasUrl).identifier == URIRef("https://data.support.com")
146
148
 
149
+ def test_dataset_with_publisher_contact_point(self, app):
150
+ org = OrganizationFactory(name="organization")
151
+ contact = ContactPointFactory(
152
+ name="Publisher Contact",
153
+ role="publisher",
154
+ )
155
+ remote_url = "https://somewhere.org/dataset"
156
+ dataset = DatasetFactory(
157
+ organization=org,
158
+ contact_points=[contact],
159
+ harvest=HarvestDatasetMetadata(
160
+ remote_url=remote_url, dct_identifier="foobar-identifier"
161
+ ),
162
+ )
163
+ app.config["SITE_TITLE"] = "Test site title"
164
+ d = dataset_to_rdf(dataset)
165
+
166
+ contact_rdf = d.value(DCT.publisher)
167
+ assert contact_rdf.value(RDF.type).identifier == VCARD.Kind
168
+ assert contact_rdf.value(VCARD.fn) == Literal("Publisher Contact")
169
+
170
+ org_rdf = d.value(GEODCAT.distributor)
171
+ assert org_rdf.value(RDF.type).identifier == FOAF.Organization
172
+ assert org_rdf.value(FOAF.name) == Literal("organization")
173
+
147
174
  def test_map_unkownn_frequencies(self):
148
175
  assert frequency_to_rdf("hourly") == FREQ.continuous
149
176
 
@@ -210,9 +237,9 @@ class DatasetToRdfTest:
210
237
  resource_2 = ResourceFactory(
211
238
  url="https://services.data.shom.fr/INSPIRE/wms/r?service=WMS&request=GetCapabilities&version=1.3.0",
212
239
  )
213
- contact = ContactPointFactory()
240
+ contact = ContactPointFactory(role="contact")
214
241
  dataset = DatasetFactory(
215
- resources=[resource_1, resource_2], license=license, contact_point=contact
242
+ resources=[resource_1, resource_2], license=license, contact_points=[contact]
216
243
  )
217
244
 
218
245
  r = resource_to_rdf(resource_1, dataset)
@@ -19,6 +19,7 @@ class OrganizationTasksTest(APITestCase):
19
19
  "email": "mooneywayne@cobb-cochran.com",
20
20
  "name": "Martin Schultz",
21
21
  "organization": str(org.id),
22
+ "role": "contact",
22
23
  }
23
24
  response = self.post(url_for("api.contact_points"), data)
24
25
  self.assert201(response)
udata/tests/test_rdf.py CHANGED
@@ -7,10 +7,12 @@ from rdflib import (
7
7
  from udata.models import ContactPoint
8
8
  from udata.rdf import (
9
9
  ACCEPTED_MIME_TYPES,
10
+ DCAT,
11
+ DCT,
10
12
  FORMAT_MAP,
11
13
  RDF,
12
14
  VCARD,
13
- contact_point_to_rdf,
15
+ contact_points_to_rdf,
14
16
  guess_format,
15
17
  negociate_content,
16
18
  want_rdf,
@@ -82,16 +84,48 @@ class GuessFormatTest(object):
82
84
 
83
85
 
84
86
  class ContactToRdfTest:
85
- def test_contact_point_to_rdf(self):
87
+ def test_contact_points_to_rdf(self):
86
88
  contact = ContactPoint(
87
89
  name="Organization contact",
88
90
  email="hello@its.me",
89
91
  contact_form="https://data.support.com",
90
92
  )
91
93
 
92
- contact_rdf = contact_point_to_rdf(contact, None)
94
+ contact_rdfs = contact_points_to_rdf([contact], None)
95
+
96
+ for contact_point, predicate in contact_rdfs:
97
+ assert contact_point.value(RDF.type).identifier == VCARD.Kind
98
+ assert contact_point.value(VCARD.fn) == Literal("Organization contact")
99
+ assert contact_point.value(VCARD.hasEmail).identifier == URIRef("mailto:hello@its.me")
100
+ assert contact_point.value(VCARD.hasUrl).identifier == URIRef(
101
+ "https://data.support.com"
102
+ )
103
+ # Default predicate is "contact"
104
+ assert predicate == DCAT.contactPoint
105
+
106
+ @pytest.mark.parametrize(
107
+ "role,predicate",
108
+ [
109
+ ("contact", DCAT.contactPoint),
110
+ ("publisher", DCT.publisher),
111
+ ("creator", DCT.creator),
112
+ ],
113
+ )
114
+ def test_contact_points_to_rdf_roles(self, role, predicate):
115
+ contact = ContactPoint(
116
+ name="Organization contact",
117
+ email="hello@its.me",
118
+ contact_form="https://data.support.com",
119
+ role=role,
120
+ )
121
+
122
+ contact_rdfs = contact_points_to_rdf([contact], None)
93
123
 
94
- assert contact_rdf.value(RDF.type).identifier == VCARD.Kind
95
- assert contact_rdf.value(VCARD.fn) == Literal("Organization contact")
96
- assert contact_rdf.value(VCARD.hasEmail).identifier == URIRef("mailto:hello@its.me")
97
- assert contact_rdf.value(VCARD.hasUrl).identifier == URIRef("https://data.support.com")
124
+ for contact_point, contact_point_predicate in contact_rdfs:
125
+ assert contact_point.value(RDF.type).identifier == VCARD.Kind
126
+ assert contact_point.value(VCARD.fn) == Literal("Organization contact")
127
+ assert contact_point.value(VCARD.hasEmail).identifier == URIRef("mailto:hello@its.me")
128
+ assert contact_point.value(VCARD.hasUrl).identifier == URIRef(
129
+ "https://data.support.com"
130
+ )
131
+ assert contact_point_predicate == predicate
@@ -8,8 +8,8 @@ msgid ""
8
8
  msgstr ""
9
9
  "Project-Id-Version: udata 10.0.8.dev0\n"
10
10
  "Report-Msgid-Bugs-To: i18n@opendata.team\n"
11
- "POT-Creation-Date: 2025-01-31 10:00+0100\n"
12
- "PO-Revision-Date: 2025-01-31 10:00+0100\n"
11
+ "POT-Creation-Date: 2025-01-28 11:37+0100\n"
12
+ "PO-Revision-Date: 2025-01-28 11:37+0100\n"
13
13
  "Last-Translator: Open Data Team <i18n@opendata.team>\n"
14
14
  "Language: en\n"
15
15
  "Language-Team: Open Data Team <i18n@opendata.team>\n"
@@ -252,7 +252,23 @@ msgstr ""
252
252
  msgid "Publish as"
253
253
  msgstr ""
254
254
 
255
- #: udata/core/contact_point/models.py:18 udata/tests/api/test_contact_points.py:50
255
+ #: udata/core/contact_point/forms.py:21 udata/core/organization/forms.py:94
256
+ msgid "Role"
257
+ msgstr ""
258
+
259
+ #: udata/core/contact_point/models.py:9
260
+ msgid "Contact"
261
+ msgstr ""
262
+
263
+ #: udata/core/contact_point/models.py:10
264
+ msgid "Creator"
265
+ msgstr ""
266
+
267
+ #: udata/core/contact_point/models.py:11
268
+ msgid "Publisher"
269
+ msgstr ""
270
+
271
+ #: udata/core/contact_point/models.py:26 udata/tests/api/test_contact_points.py:56
256
272
  msgid "At least an email or a contact form is required for a contact point"
257
273
  msgstr ""
258
274
 
@@ -709,10 +725,6 @@ msgstr ""
709
725
  msgid "Business identification number"
710
726
  msgstr ""
711
727
 
712
- #: udata/core/organization/forms.py:94
713
- msgid "Role"
714
- msgstr ""
715
-
716
728
  #: udata/core/organization/models.py:35
717
729
  msgid "Public Service"
718
730
  msgstr ""
@@ -1628,6 +1640,10 @@ msgstr ""
1628
1640
  msgid "Here"
1629
1641
  msgstr ""
1630
1642
 
1643
+ #: udata/tests/api/test_contact_points.py:66
1644
+ msgid "ValidationError (ContactPoint:None) (Field is required: ['role'])"
1645
+ msgstr ""
1646
+
1631
1647
  #: udata/tests/forms/test_model_field.py:165
1632
1648
  msgid "Expect a \"Target\" class but \"Wrong\" was found"
1633
1649
  msgstr ""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: udata
3
- Version: 10.0.9.dev33787
3
+ Version: 10.0.9.dev33820
4
4
  Summary: Open data portal
5
5
  Home-page: https://github.com/opendatateam/udata
6
6
  Author: Opendata Team
@@ -140,6 +140,7 @@ It is collectively taken care of by members of the
140
140
 
141
141
  ## Current (in progress)
142
142
 
143
+ - Harvest attribution roles [#3149](https://github.com/opendatateam/udata/pull/3149)
143
144
  - Allow super-admins to change objects' owners [#3260](https://github.com/opendatateam/udata/pull/3260)
144
145
  - Fix contact point permissions [#3253](https://github.com/opendatateam/udata/pull/3253)
145
146