package nl.ipo.cds.dao; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.sql.Timestamp; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityNotFoundException; import javax.persistence.PersistenceContext; import javax.sql.DataSource; import junit.framework.Assert; import nl.idgis.commons.jobexecutor.AbstractJob; import nl.idgis.commons.jobexecutor.Job; import nl.idgis.commons.jobexecutor.JobLogger.LogLevel; import nl.idgis.commons.utils.DateTimeUtils; import nl.ipo.cds.categories.IntegrationTests; import nl.ipo.cds.domain.Bronhouder; import nl.ipo.cds.domain.BronhouderThema; import nl.ipo.cds.domain.Dataset; import nl.ipo.cds.domain.DatasetType; import nl.ipo.cds.domain.EtlJob; import nl.ipo.cds.domain.ImportJob; import nl.ipo.cds.domain.JobLog; import nl.ipo.cds.domain.Thema; import nl.ipo.cds.domain.TransformJob; import nl.ipo.cds.domain.ValidateJob; import org.deegree.geometry.Geometry; import org.deegree.geometry.multi.MultiPolygon; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.orm.jpa.JpaObjectRetrievalFailureException; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.transaction.TransactionConfiguration; @RunWith(SpringJUnit4ClassRunner.class) @TransactionConfiguration(defaultRollback = true, transactionManager = "transactionManager") @Category(IntegrationTests.class) public class ManagerDaoTest extends BaseManagerDaoTest { @Autowired private DataSource dataSource; @PersistenceContext private EntityManager entityManager; public ManagerDaoTest() { super(); } /** * build up a database with base tables to be used in the testcases * @throws Exception */ // when using @BeforeClass with 'public static void buildDB()' the managerDao==null @Before public void buildDB() throws Exception { super.buildDB (); } @Test public void testStamTabellen() { System.out.println("------------- testStamTabellen ---------------"); Assert.assertEquals(managerDao.getThema(thema.getId()).getNaam(), managerDao.getDatasetType(datasetType1.getId()).getThema().getNaam()); Assert.assertEquals(managerDao.getThema(thema.getId()), managerDao.getDatasetType(datasetType2.getId()).getThema()); Assert.assertEquals("IMPORT", managerDao.getJobType(jobTypeI.getId()).getNaam()); Assert.assertEquals("IDgis", managerDao.getBronhouder(bronhouderOV.getId()).getContactNaam()); } @Test public void testCreateJob() { logger.info("------------- testCreateJob ---------------"); System.out.println("------------- testCreateJob ---------------"); Dataset dataset = new Dataset(); dataset.setUuid("123uuid321"); dataset.setDatasetType(datasetType2); dataset.setBronhouder(bronhouderOV); dataset.setActief(true); managerDao.create(dataset); Assert.assertFalse((dataset.getId()==null)); managerDao.update(dataset); ValidateJob job = new ValidateJob(); // copy properties from dataset to job job.setBronhouder(dataset.getBronhouder()); job.setDatasetType(dataset.getDatasetType()); job.setUuid(dataset.getUuid()); job.setStatus(Job.Status.CREATED); managerDao.create(job); // build job Assert.assertFalse((job.getId()==null)); job.setStatus(Job.Status.STARTED); job.setStatus(Job.Status.FINISHED); managerDao.update(job); System.out.println(job); // job built // test order of creatie-, start-, eindtijd Assert.assertTrue(managerDao.getJob(job.getId()).getCreateTime().getTime() <= managerDao.getJob(job.getId()).getStartTime().getTime()); Assert.assertTrue(managerDao.getJob(job.getId()).getStartTime().getTime() <= managerDao.getJob(job.getId()).getFinishTime().getTime()); // test nesting (Primary and foreign keys) Assert.assertNotNull(managerDao.getJob(job.getId())); } @Test public void testUUID() { testUUID("utrecht","WAV","5c1c398d-d7d7-44e1-bf8a-caee7c2ba3f5"); testUUID("noordholland","AW","E0C183FB-BB18-4C5B-B1AC-E3423B266002"); testUUID("zuidholland","EHS","30583498-5ED1-46C3-A0C7-92A19B9696D0"); testUUID("zeeland","NL","9404865D-946F-4FBF-99D4-D059B2D678E1"); } @Test public void testLog() { ValidateJob job = new ValidateJob(); JobLog log = new JobLog(); log.setLogLevel(LogLevel.ERROR); log.setJob(job); managerDao.create(job); managerDao.create(log); entityManager.flush(); } private void testUUID(String commonName, String typenaam, String uuidStr) { Dataset dataset1, dataset2; dataset1 = createNewDataset(commonName, typenaam, uuidStr); dataset2 = managerDao.getDatasetsByUUID(uuidStr).get(0); Assert.assertEquals(dataset1.getUuid(), dataset2.getUuid()); } private Dataset createNewDataset(String commonName, String typenaam, String uuidStr) { Dataset dataset = new Dataset(); dataset.setBronhouder(managerDao.getBronhouderByCommonName(commonName)); dataset.setDatasetType(managerDao.getDatasetTypeByName(typenaam)); dataset.setUuid(uuidStr); managerDao.create(dataset); createNewJob(dataset); return dataset; } private AbstractJob createNewJob(Dataset dataset) { ValidateJob job = new ValidateJob(); // copy properties from dataset to job job.setBronhouder(dataset.getBronhouder()); job.setDatasetType(dataset.getDatasetType()); job.setUuid(dataset.getUuid()); job.setStatus(Job.Status.STARTED); job.setMetadataUpdateDatum(new Timestamp(0)); job.setStatus(Job.Status.FINISHED); managerDao.create(job); return job; } private <T extends EtlJob> T createJob (final T job, final Job.Status status) { final Dataset dataset = managerDao.getAllDatasets().get(0); job.setBronhouder (dataset.getBronhouder ()); job.setDatasetType (dataset.getDatasetType ()); job.setUuid (dataset.getUuid ()); job.setStatus (Job.Status.STARTED); job.setMetadataUpdateDatum (new Timestamp (0)); job.setStatus (status); managerDao.create (job); return job; } @Test public void testGetLastTransformJob() { final TransformJob transformJob = new TransformJob (); managerDao.create (transformJob); entityManager.flush(); EtlJob refoundJob = managerDao.getLastTransformJob(Job.Status.CREATED); Assert.assertEquals(transformJob, refoundJob); } @Test public void testGetJobsByDataset(){ createJob (new ImportJob (), Job.Status.STARTED); Dataset dataset = managerDao.getAllDatasets().get(0); Assert.assertNotNull("No dataset Found", dataset); List<EtlJob> jobs = this.managerDao.getJobsByDataset(dataset.getBronhouder(), dataset.getDatasetType(), dataset.getUuid()); Assert.assertNotNull("No joblist found", jobs); Assert.assertTrue("No jobs found", jobs.size() > 0); jobs = this.managerDao.getJobsByDataset(dataset.getBronhouder(), dataset.getDatasetType(), null); Assert.assertNotNull("No joblist found", jobs); Assert.assertTrue("No jobs found", jobs.size() > 0); } @Test public void testGetAllJobs () { int initialJobsize = managerDao.getAllJobs ().size(); createJob (new ImportJob (), Job.Status.FINISHED); createJob (new ValidateJob (), Job.Status.ABORTED); final List<AbstractJob> jobs = managerDao.getAllJobs (); assertEquals (initialJobsize+2, jobs.size ());//BuildDB adds one job } @Test public void testGetJobsByStatus () { int initialFinishedJobsize = managerDao.getJobsByStatus (Job.Status.FINISHED).size (); int initialAbortedJobsize = managerDao.getJobsByStatus (Job.Status.ABORTED).size (); createJob (new ImportJob (), Job.Status.FINISHED); createJob (new ValidateJob (), Job.Status.ABORTED); assertEquals (initialFinishedJobsize + 1, managerDao.getJobsByStatus (Job.Status.FINISHED).size ()); assertEquals (initialAbortedJobsize + 1, managerDao.getJobsByStatus (Job.Status.ABORTED).size ()); } @Test public void testGetLastCompletedJob () { final Dataset dataset = managerDao.getAllDatasets().get(0); final EtlJob job = createJob (new ImportJob (), Job.Status.FINISHED); job.setVerversen (true); job.setFinishTime (DateTimeUtils.now ()); managerDao.update (job); final EtlJob completedJob = managerDao.getLastCompletedJob (dataset.getBronhouder (), dataset.getDatasetType (), dataset.getUuid ()); assertNotNull (completedJob); assertNotNull (job.getId ()); assertEquals (job.getId (), completedJob.getId ()); } @Test public void testGetLastValidationJob () { final Dataset dataset = managerDao.getAllDatasets().get(0); final EtlJob job = createJob (new ValidateJob (), Job.Status.FINISHED); job.setVerversen (true); job.setFinishTime (DateTimeUtils.now ()); managerDao.update (job); final EtlJob validateJob = managerDao.getLastValidationJob (dataset.getBronhouder (), dataset.getDatasetType (), dataset.getUuid ()); assertNotNull (validateJob); assertNotNull (job.getId ()); assertEquals (job.getId (), validateJob.getId ()); } @Test public void testGetLastJobThatValidated () { final Dataset dataset = managerDao.getAllDatasets().get(0); final EtlJob job = createJob (new ValidateJob (), Job.Status.FINISHED); job.setVerversen (true); job.setFinishTime (DateTimeUtils.now ()); managerDao.update (job); final EtlJob validateJob = managerDao.getLastJobThatValidated (dataset.getBronhouder (), dataset.getDatasetType (), dataset.getUuid ()); assertNotNull (validateJob); assertNotNull (job.getId ()); assertEquals (job.getId (), validateJob.getId ()); } @Test public void testGetLastImportJob () { final Dataset dataset = managerDao.getAllDatasets().get(0); final ImportJob job = createJob (new ImportJob (), Job.Status.FINISHED); job.setVerversen (true); job.setFinishTime (DateTimeUtils.now ()); managerDao.update (job); final EtlJob importJob = managerDao.getLastImportJob (dataset.getBronhouder (), dataset.getDatasetType (), dataset.getUuid ()); assertNotNull (importJob); assertNotNull (job.getId ()); assertEquals (job.getId (), importJob.getId ()); } @Test public void testGetLastSuccessfullImportJob () { final Dataset dataset = managerDao.getAllDatasets().get(0); final ImportJob job = createJob (new ImportJob (), Job.Status.FINISHED); job.setVerversen (true); job.setFinishTime (DateTimeUtils.now ()); managerDao.update (job); final EtlJob importJob = managerDao.getLastSuccessfullImportJob (dataset.getBronhouder (), dataset.getDatasetType (), dataset.getUuid ()); assertNotNull (importJob); assertNotNull (job.getId ()); assertEquals (job.getId (), importJob.getId ()); } @Test public void testGetPendingJob () { final ImportJob job = createJob (new ImportJob (), Job.Status.STARTED); job.setVerversen (true); managerDao.update (job); final EtlJob pendingJob = managerDao.getPendingJob (job); assertNotNull (pendingJob); assertNotNull (job.getId ()); assertEquals (job.getId (), pendingJob.getId ()); } @Test public void testGetLastCompletedJobs () { int initialJobsize = managerDao.getJobsByStatus (Job.Status.FINISHED).size (); initialJobsize += managerDao.getJobsByStatus (Job.Status.ABORTED).size (); // Should report only the last instance of both the import and the validate job: createJob (new ImportJob (), Job.Status.STARTED); final ImportJob finishedJob = createJob (new ImportJob (), Job.Status.FINISHED); final ImportJob finishedJob2 = createJob (new ImportJob (), Job.Status.FINISHED); final ValidateJob abortedJob = createJob (new ValidateJob (), Job.Status.ABORTED); final ValidateJob abortedJob2 = createJob (new ValidateJob (), Job.Status.ABORTED); finishedJob.setVerversen (true); finishedJob2.setVerversen (true); finishedJob.setFinishTime (DateTimeUtils.now ()); finishedJob2.setFinishTime (new Timestamp (DateTimeUtils.now ().getTime() + 10)); abortedJob.setVerversen (true); abortedJob2.setVerversen (true); abortedJob.setFinishTime (DateTimeUtils.now ()); abortedJob2.setFinishTime (new Timestamp (DateTimeUtils.now ().getTime() + 10)); managerDao.update (finishedJob); managerDao.update (finishedJob2); managerDao.update (abortedJob); managerDao.update (abortedJob2); final List<JobInfo> jobInfos = managerDao.getLastCompletedJobs (); assertNotNull (jobInfos); if (initialJobsize==0){ assertEquals (2, jobInfos.size ()); }else{ assertEquals (initialJobsize, jobInfos.size ()); } } @Test public void testCreateTestJob () { final ImportJob importJob = new ImportJob (); managerDao.create (importJob); assertNotNull (importJob.getId ()); assertNotNull (entityManager.getReference (ImportJob.class, importJob.getId ())); } @Test public void testDeleteJob () { final ImportJob importJob = new ImportJob (); managerDao.create (importJob); final AbstractJob fetchedJob = managerDao.getJob (importJob.getId ()); assertNotNull (fetchedJob); managerDao.delete (fetchedJob); assertNull (managerDao.getJob (importJob.getId ())); try { entityManager.getReference (EtlJob.class, importJob.getId ()); } catch (JpaObjectRetrievalFailureException e) { return; } catch (EntityNotFoundException e) { return; } fail (); } @Test public void testCreateDataset () { final Dataset test = new Dataset (); managerDao.create (test); assertNotNull (test.getId ()); assertNotNull (entityManager.getReference (Dataset.class, test.getId ())); } @Test public void testDeleteDataset () { final Dataset test = new Dataset (); managerDao.create (test); managerDao.delete (test); try { Dataset ref = this.entityManager.getReference(Dataset.class, test.getId()); } catch (JpaObjectRetrievalFailureException e) { return; } catch (EntityNotFoundException e) { return; } fail (); } @Test public void testCreateDatasetType () { final DatasetType test = new DatasetType (); managerDao.create (test); assertNotNull (test.getId ()); assertNotNull (entityManager.getReference (DatasetType.class, test.getId ())); } @Test public void testDeleteDatasetType () { final DatasetType test = new DatasetType (); managerDao.create (test); managerDao.delete (test); try { DatasetType ref = this.entityManager.getReference(DatasetType.class, test.getId()); } catch (JpaObjectRetrievalFailureException e) { return; } catch (EntityNotFoundException e) { return; } fail (); } @Test public void testCreateBronhouder () { final Bronhouder test = new Bronhouder (); managerDao.create (test); assertNotNull (test.getId ()); assertNotNull (entityManager.getReference (Bronhouder.class, test.getId ())); } @Test public void testDeleteBronhouder () { final Bronhouder test = new Bronhouder (); managerDao.create (test); managerDao.delete (test); try { Bronhouder ref = this.entityManager.getReference(Bronhouder.class, test.getId()); } catch (JpaObjectRetrievalFailureException e) { return; } catch (EntityNotFoundException e) { return; } fail (); } @Test public void testCreateThema () { final Thema test = new Thema (); managerDao.create (test); assertNotNull (test.getId ()); assertNotNull (entityManager.getReference (Thema.class, test.getId ())); } @Test public void testDeleteThema () { final Thema test = new Thema (); managerDao.create (test); managerDao.delete (test); try { Thema ref = this.entityManager.getReference(Thema.class, test.getId()); } catch (JpaObjectRetrievalFailureException e) { return; } catch (EntityNotFoundException e) { return; } fail (); } @Test public void testCreateJobLog () { final JobLog test = new JobLog (); managerDao.create (test); assertNotNull (test.getId ()); assertNotNull (entityManager.getReference (JobLog.class, test.getId ())); } @Test public void testDeleteJobLog () { final JobLog test = new JobLog (); managerDao.create (test); managerDao.delete (test); try { JobLog ref = this.entityManager.getReference(JobLog.class, test.getId()); } catch (JpaObjectRetrievalFailureException e) { return; } catch (EntityNotFoundException e) { return; } fail (); } @Test public void testGetBronhouderGeometry () { entityManager.flush (); // Insert a geometry: final JdbcTemplate template = new JdbcTemplate (dataSource); template.execute ("INSERT INTO manager.bronhouder_geometry (bronhouder_id, geom) VALUES ((select id from manager.bronhouder where code = '9927'), '0106000020407100000100000001030000000100000053030000000000008090FC400000000010BB214100000000A02C004100000000907C2141A4703D0A01180141EC51B81EA6002141295C8FC237220141713D0A57B1FD20410000000040B301410000000030922041C3F5285CC5D60241713D0A57203320411F85EB51ACB40241D7A3703D61CB1F4185EB51B814A40241295C8FC271D01F419A999999F5360241295C8FC276E81F419A999999952A0241295C8FC232E91F419A9999995719024185EB51B824E71F4100000000DC1602413333333317E21F4100000000E61302413D0AD7A3C2E21F41000000006001024100000000E8D91F4100000000B0E301410000000068CD1F4146B6F3FDBFD8014123DBF9FE27951F41000000009037004100000000E0231F4100000000F08B00410000000070A81E410000000030F6004100000000C85F1E41B81E85EBE33E01410000000080071E410000000080D800410000000080071E41AE47E17A6E5C00410AD7A370F9D81D41AE47E17A6E5C00419A99999940B91D41A4703D0AF57D00410AD7A3709DA41D419A99999991D800413D0AD7A3406C1D41295C8FC289E5004114AE47E10D641D41EC51B81E21EA00411F85EB51C6601D4100000000F2EF0041C3F5285C215F1D4185EB51B8BEF400413D0AD7A3FA5E1D4185EB51B8F867014185EB51B872681D415C8FC2F576780141B81E85EBF8691D418FC2F5286888014185EB51B8A66B1D41A4703D0A138F014185EB51B8546B1D4114AE47E1649B01411F85EB513E6A1D419A999999BF0902415C8FC2F5635B1D411F85EB5112170241E17A14AE66581D4114AE47E1343402418FC2F528044F1D410AD7A3705D410241D7A3703D014A1D419A9999991D57024152B81E8521401D4148E17A146E7D0241713D0AD72A2D1D4193180456363E02419A999999C9161D41D9CEF7535F2C02410000000091181D41D7A3703D461E02418B6CE7FBD2191D41508D976EC9160241C976BE9FA11A1D41FED478E90C1602413F355EBAD41A1D411D5A643BAB1202418D976E92EE1A1D4179E92631AC0F02419CC420B04C1B1D410E2DB29DF20E02411D5A643B481B1D41508D976E3CE90141E7FBA9F1D61E1D413BDF4F8D23BA0141F2D24D6243EF1C41C1CAA14583BC0141BC74939814EF1C41295C8FC270BC0141AC1C5A64FFEE1C41022B8716EE8C01418716D94E6BBC1C41CBA145B6D5900141068195C34DBC1C41295C8FC287890141C520B0F24EAF1C4133333333147F014177BE9F9A969B1C416F1283C0A180014146B6F37D5A9B1C41EE7C3F35C24B014191ED7C3F0C6A1C41F6285C8FC4440141B81E85EBCA691C41C3F5285C90E20041AE47E17A716E1C4148E17A143DE2004108AC1CDADC6D1C418FC2F52806DF004114AE47E11E6E1C414260E5D0C6D10041643BDFCF986E1C416ABC74936CD100418FC2F5A8B66E1C41C74B37899ACE00418D976E12D56E1C4154E3A59B8DCB00413108AC9CD66E1C4121B072683FC800418B6CE77B096F1C418FC2F52826C200415C8FC2F5246F1C410AD7A37029B300411F85EB51B46F1C41355EBA49D69D00415EBA498CA76C1C41A01A2FDD4A600041FCA9F1D283631C4177BE9F1A484700412DB29DEF055F1C41F6285C8F12460041DF4F8D17F85E1C41CDCCCCCC10460041B81E85EBD55E1C41713D0AD7AD440041E17A142E955E1C415EBA490CED310041FED478695F5B1C41A8C64B37F4150041C976BE9F5E561C415EBA490C2413004100000000EE551C4189F61606B8120041EDB32D4914561C410AD7A3709F1100418FC2F5A803591C413F355EBA331100411283C0CA3F5B1C41F6285C8FE90E004162105839DE601C41A245B6F3130E00417B14AE4701651C41C74B3789490D0041B29DEFA7E8661C4148E17A14150A0041BC74939845741C411904560E05090041F6285C0FF0741C418B6CE7FB7FFBFF40295C8F4235751C41A01A2FDD62EBFF400C022B079D751C4185EB51B896EBFF4023DBF97EF6751C41508D976E64EDFF40FCA9F1D23D761C4160E5D02261EEFF4079E926B1A8761C41C74B378949F0FF40DF4F8D17F9781C41CDCCCCCC76F1FF401283C04A54791C411904560E83F4FF40CBA145B6BB791C411D5A643B0DF6FF409CC420B0467A1C41BE9F1A2FE1F6FF40E9263188037D1C416891ED7C41F9FF406F1283C0707E1C41B07268910FF8FF40B6F3FDD4BF7F1C41D578E926B7F7FF4046B6F37D0C811C41713D0AD785FBFF408B6CE77B6A821C41A4703D0ADBFCFF400C022B0700861C41E9263108FCFDFF40BE9F1A2F8A861C413BDF4F8D2B01004114AE4761AB871C417F6ABC74E9010041D578E926CB881C4139B4C876E60100412FDD2486AF891C41105839B425010041C74B37893B8B1C412FDD24068DFFFF40D9CEF753578B1C41931804566E000041E7FBA9F1B58C1C418FC2F528EEFFFF40A8C64B37A48D1C4152B81E859BFFFF40E7FBA971D28D1C4104888AD2B1F3FF40149E14FDEE8D1C415839B4C89AF0FF400C022B07508E1C4171BD9B0697EAFF40E09BDE81B08E1C41648B6028FAE8FF402141BE72848E1C41646E12516CE8FF406420EBAFE68E1C4134C51E7D79E5FF40D899AF15108F1C41BE9F1A2F29E3FF403F355EBAE88F1C41E926310892E0FF400AD7A3706F901C41D7A3703D4ADFFF40CBA145367D901C41E17A14AE05DCFF4096438B6C03911C418716D9CE6FD8FF4083C0CAA12E911C418716D9CE79D8FF409EEFA7C667911C415839B4C87AD5FF40B0726811F7911C41CDCCCCCC72D0FF40A01A2F5DA7931C41F2D24D629ECEFF408FC2F5A8CE931C4108AC1C5A62C5FF40713D0AD7ED931C41E17A14AE1DC4FF40BC7493180E941C4191ED7C3F63C2FF402731082CF3931C418716D9CE17BCFF408FC2F5A891941C41894160E5B0BCFF40FA7E6A3CD4941C412B8716D97CC2FF40B4C876BE42941C41F6285C8F6EC3FF4052B81E8551941C4177BE9F1A15C1FF4039B4C8F625951C41508D976E5EBDFF409A99999997951C411283C0CA71BDFF40355EBA49B5951C41E5D022DBC9BEFF40E9263188A2951C418FC2F52806C2FF40B4C876BE2D951C419CC420B080C3FF40F4FDD478D3941C410F53F5D7E2C3FF402B702ECD0C961C4166BF86C163C1FF405D32A59DEF951C41F853E3A515C1FF4048E17A942D961C41B6F3FDD4D6C1FF40CBA145B622981C41B4C876BE4DC5FF409EEFA746EF971C418B6CE7FBC5C4FF408941606595961C41E17A14AEA3CAFF40BA490C0278961C415C8FC2F592CAFF40621058B93F961C415C8FC2F5F2CBFF4023DBF9FE36961C4160E5D02223CCFF407F6ABCF4F4961C419EEFA7C6D1CDFF40A245B6F3ED961C41643BDF4F91CEFF4085EB51B830981C4106819543B7FDFF409CC42030ED941C41AE47E17A8D000041DF4F8D17D6991C41BC7493181EF8FF4062105839509A1C41E3A59BC416FDFF4077BE9F1AD8A11C41E926310818F0FF40A4703D8A53A21C41F6285C8F20F1FF40BA490C022FA31C410C022B8720F3FF4023DBF97E51A61C41643BDF4F99F3FF402B8716D94FA61C41A8C64B3735F4FF404E6210D8A5A71C41894160E546F4FF401904568E06A81C41508D976E9CF1FF407D3F35DE09A81C417B14AE47E1F1FF401283C0CA10A91C41A69BC42050FEFF40D34D6290EFA81C41E7FBA9F1DAFEFF4017D9CEF795A91C41B29DEFA730FEFF4077BE9F9AE3A91C4185EB51B86D00004133333333EBA91C41FA7E6ABC5B000041355EBAC91BAA1C417D3F355E98FFFF403D0AD7A341AA1C411F85EB510AF9FF4054E3A59B38AA1C416891ED7C7DF8FF404C3789C15BAA1C41AC1C5A6461FAFF402DB29D6F85AA1C411B2FDD2406FAFF4048E17A1482AB1C4114AE47E142FFFF405839B4488EAB1C410AD7A3705BFEFF40F4FDD4F87CAC1C4100000000C6FFFF40931804D6DCAC1C41B4C876BE260000413BDF4F0D60AD1C410C022B8754FFFF406F1283C072AD1C41BC74931820000041AC1C5A64FAAD1C417D3F355E0EFFFF403789416018AF1C41DBF97E6AB0FDFF40E3A59BC46FAF1C41B81E85EBCFFAFF407F6ABCF4AFAF1C413BDF4F8D87FEFF40F4FDD4F88EBB1C416DE7FBA9A9040041A01A2FDDF5BA1C41CBA145B6FA0400416F128340A2BB1C41B6F3FDD4720A004177BE9F9AE4BA1C410E2DB29D7F0A00414C3789410FBB1C41DBF97E6AD2FFFF4039B4C87647BC1C41DBF97E6A360000411058393443BD1C412FDD2406B0030041C3F528DCF8BC1C41A8C64B379E04004185EB51B86ABE1C41A4703D0A870600417D3F355E2FC01C41295C8FC27807004104560E2D07C01C415839B4C87F0800411283C04A0CC11C41D122DBF93C0800413BDF4F8D54C11C411B2FDD24560900416210583903C21C41DBF97E6ACF0A004104560E2D8CC21C414A0C022BC30B0041FCA9F15236C31C41FA7E6ABCD1080041355EBA4929C41C411D5A643B46090041EE7C3FB575C41C41AAF1D24DFA0700418195430B8EC41C41B29DEFA794070041508D97EE0DC51C41BC7493185A090041A245B6F378C51C418716D9CEE0090041F0A7C6CBE1C61C418B6CE7FB9A0B004117D9CEF748C61C411B2FDD246B0D0041736891EDC0C61C412B8716D91C0E0041508D976E45C71C41A245B6F3A70E004146B6F3FD18C71C41E5D022DBC11F0041A4703D0A7BCB1C41F4FDD478F11F0041AAF1D2CDB9CB1C41C976BE9FAA2000410E2DB29DFDCB1C41022B8716212100412B871659D4CB1C41D7A3703D2022004177BE9F9A19CC1C4139B4C876E7220041EE7C3FB5A7CC1C417D3F355E6F2300411283C0CA6FCC1C415EBA490C322900418D976E92EBCD1C410AD7A370452800414A0C02AB54CE1C410E2DB29D52290041273108AC9ECE1C41105839B47A290041250681158BCE1C41068195435A2A0041FA7E6A3CFCCE1C411283C0CAE32B00410C022B874FCE1C41F2D24D626A2C0041560E2D3290CE1C41C74B3789EF2B0041508D976E67CF1C4191ED7C3F452B0041E7FBA9F1B2CF1C4154E3A59BA62A00411F85EBD19FD01C41BE9F1A2F57290041C1CAA1C5A7D11C41E17A14AE071B0041E17A142E97D81C415A643BDF7418004191ED7C3F26DA1C41B6F3FDD4FD160041378941608BDA1C418D976E12BB140041E17A142EA0DB1C413108AC1C32130041AC1C5A6494DC1C41F2D24D62AD1400417B14AE47D1E21C416F1283C0F11400419A9999998BE51C41273108AC6B1400415EBA490C2DE61C418195438B1A120041CDCCCC4CE0E71C4160E5D022121100416891ED7C3FE91C411283C0CA570F00416DE7FB295AEC1C411F85EB513C0F00412FDD2406EAED1C41C74B3789850E00413D0AD7A391EF1C4183C0CAA1500E00418716D94E5FF11C41B4C876BEE60D0041D7A3703DF5F11C41CFF753E3300D004183C0CAA17DF21C41F6285C8F7D0B00415C8FC2F553F31C4185EB51B8DD0900419CC420B0C0F31C416ABC74935D080041B4C876BEBFF31C41C3F5285C0D07004104560EAD69F31C41B29DEFA7B5050041F6285C0FC4F21C418716D9CE81040041C976BE9FD8F11C41F2D24D628E020041560E2DB278EF1C41022B871687010041D578E9A68AEE1C418D976E120FFFFF40BC7493985DED1C410000000080FBFF408716D94EC0EC1C41F2D24D6208F8FF4008AC1CDACDEC1C41EC51B81E3BF6FF4077BE9F9A1FED1C41AE47E17AA0EFFF400E2DB21D41EF1C413BDF4F8D0DEBFF40DD2406810DF11C41E17A14AE25E8FF404A0C022BA2F21C41736891ED52E7FF40355EBAC904F41C4139B4C8764CE8FF4062105839E0F41C41643BDF4F1DECFF40F4FDD4784CF61C415EBA490CBAEDFF4054E3A51B4AF71C41CDCCCCCCAAEEFF40D9CEF7D39EF81C41A8C64B37E9EDFF409A999999D3F91C41E5D022DBA7EBFF4039B4C8F610FB1C41DD24068107E8FF408FC2F5A840FC1C41A4703D0A49E4FF408195438B2EFD1C41A4703D0A7FD8FF40AAF1D2CDA2FF1C41B81E85EBD7D4FF407D3F35DEC7001D41B4C876BE87D4FF401F85EB5136011D41BE9F1A2FDFD4FF40DF4F8D97A0011D411904560E9DD8FF40EE7C3F3503031D414E62105819DAFF4014AE47E110041D41AAF1D24D9CDAFF4054E3A51B8C051D411B2FDD24F2D9FF40DBF97EEABA061D4191ED7C3F59D7FF40D122DB79DF071D41295C8FC293D0FF401F85EBD155091D41022B871681CDFF40560E2D32530A1D41F4FDD478D9C7FF4025068115110D1D4108AC1C5A5EC5FF408195438B4A0F1D41713D0AD7F3C5FF4039B4C876EC0F1D4104560E2D52C7FF40AE47E17A50101D418B6CE7FBE7C8FF407F6ABCF48B101D413108AC1C7ACAFF40D9CEF7D397101D41C1CAA14594DCFF40B6F3FD54940E1D418716D9CEB9E1FF40AC1C5A64700E1D41CDCCCCCC2CE6FF4062105839D70E1D417F6ABC74B1E7FF407B14AE47480F1D418B6CE7FB17E9FF4077BE9F1A72101D4183C0CAA141EFFF400C022B8789131D419318045602F2FF40F2D24DE25E141D419EEFA7C6E3F4FF401B2FDDA4DB141D4152B81E857FF9FF401D5A643B37151D418B6CE7FB780300413333333303171D41F0A7C64BC60B0041000000008E181D41713D0AD77A0D0041C3F5285CB4181D41000000003D0F00417368916D9D181D418B6CE7FB84110041355EBA493A181D4152B81E85A61600418D976E120A171D41E3A59BC43F180041DF4F8D17EB161D41EC51B81E9B190041355EBAC90F171D41B29DEFA7FF1A004183C0CAA19F171D4117D9CEF7CA1B004183C0CAA163181D414C3789410F1C0041AE47E1FA161D1D414A0C022BC81C004100000080331E1D41E17A14AE451E0041E9263108601F1D41BC749318122000411D5A64BB06201D41A245B6F38E2500413BDF4F8DE2201D41986E1283F82700413D0AD7236B211D41C74B3789B32F0041E3A59BC42F241D41BE9F1A2F263300418FC2F52827251D411283C0CA6D340041E3A59BC43A251D4114AE47E1FF350041CBA1453614251D41E3A59BC453370041A4703D0AD2241D41894160E516380041931804567F241D4123DBF97E42380041AAF1D24DC8231D4160E5D022F9370041894160E5A0201D41560E2DB289380041BE9F1A2F5B1F1D416ABC74939D3900419EEFA7466C1E1D41A69BC420523B00413108AC1C741D1D41CFF753E3F13C0041B0726891171D1D416891ED7C823E00411904560E161D1D41355EBA49853E0041C520B0F2591E1D414A0C022BB13D0041273108AC5A1E1D41B6F3FDD4113E0041621058B9D2201D41FCA9F1D2B53D0041621058392E251D4137894160423C0041105839B4FA241D41BC749318013B0041B6F3FDD416271D4196438B6C133900417F6ABC74A9281D4185EB51B820310041A245B6F35F2C1D41B6F3FDD41027004104560EAD51291D411D5A643BA52200413F355EBA7A271D41CFF753E31E200041068195C3EE281D413108AC1CA01D0041378941E0E6291D41643BDF4F5A170041BE9F1A2FF5241D416F1283C0CC0F0041FCA9F15286211D41A245B6F3460D004148E17A9494201D41B81E85EBD40A0041B4C8763E1E221D410AD7A37011090041E7FBA9F102231D41CBA145B625060041EC51B81EE9211D41713D0AD71DFAFF40D9CEF7D3E6251D410AD7A370C5F2FF40FCA9F1D247271D418FC2F528E2F1FF4017D9CEF72E271D417F6ABC7483E6FF4077BE9F9A122B1D4114AE47E136D5FF40BE9F1A2F41231D413F355EBA0DCCFF4008AC1CDAB51E1D410000000060C1FF4000000000FA201D410000000098C1FF4000000000C02C1D410000000028C1FF400000000042411D4100000000B0C0FF400000000068431D41B81E85EB97B7FF40931804D67E431D418195438BE8B0FF40B0726891C8431D41AAF1D24DFEABFF407368916D2B441D41B81E85EBB3A1FF40B29DEF2791451D41E17A14AE8BA1FF402B8716596A451D41CDCCCCCC689AFF402506819562451D4179E926310E97FF409CC4203016451D41273108ACFA93FF4046B6F37D75441D413D0AD7A31A8FFF40FED478E9D6421D41E17A14AE058BFF4046B6F37D34421D41FED478E97486FF4025068115DB411D415A643BDFF384FF408716D94EB8401D41736891ED247BFF40EE7C3F356E3C1D41D122DBF90C75FF4054E3A51BA43C1D41448B6CE77172FF40560E2D32B23A1D4185EB51B85E72FF40C74B370965381D4152B81E85336FFF40333333B358381D41C74B37897F6CFF404C37894114381D41E3A59BC41E6CFF406891EDFCB6321D41DF4F8D97565FFF40D7A370BD4A2E1D4177BE9F1A375EFF4017D9CEF7482E1D411283C0CAC75DFF401904560E992D1D41B6F3FDD41E5DFF40D9CEF7D38E2D1D41B29DEFA79659FF40736891ED592C1D41AAF1D24D464BFF4091ED7C3FAA2C1D41DBF97E6AB03BFF4077BE9F1A3C2D1D41F0A7C64B111EFF4023DBF9FE9A2E1D415C8FC2F5681BFF40F0A7C6CB582D1D416F1283C044FAFE40EE7C3F35A8271D415C8FC2F520F2FE40B81E85EBBE251D418D976E125DF1FE405EBA498C5F251D416210583964EFFE40355EBA4912251D41BA490C0205E3FE40894160E516221D41BE9F1A2F7BE1FE403108AC9CC61F1D41B07268910BDFFE402B8716595C1E1D41CFF753E3C5DEFE40B0726891EE1D1D41448B6CE7F1DCFE40986E1283631D1D41D7A3703D20DAFE401F85EB51F31B1D411B2FDD24B4D9FE409CC42030EA1B1D4148E17A1496D6FE4048E17A14781C1D41B81E85EB19D5FE4000000000DA1C1D414E621058BFD3FE4004560EAD631E1D415C8FC2F5C8D1FE400AD7A370B11D1D419A99999919D0FE401F85EB51781D1D41D7A3703D4AC4FE401F85EB51341D1D410AD7A370FDC2FE40295C8FC2111D1D4123DBF97ED4BDFE409CC420308B191D410681954335B9FE400AD7A370D9191D41CDCCCCCCA4B3FE40D578E926DA191D41B81E85EB01B0FE4014AE4761531A1D4117D9CEF797ABFE409CC420306F1A1D41D34D6210E09EFE4021B0726855191D4117D9CEF7639BFE409EEFA746AD191D412FDD24061795FE401F85EBD1C2191D418716D9CE538EFE40BA490C02151A1D41C976BE9F7C8AFE40C520B072681A1D41508D976E1886FE40AE47E1FAFA1A1D419EEFA7C6D582FE405EBA490C131B1D4123DBF97E407FFE405839B4C8041B1D412FDD2406AB7BFE40C520B0F2C61A1D41E92631089475FE40A01A2FDDD6191D416F1283C0826FFE40EC51B89EAD191D415A643BDFB16DFE40AC1C5AE4E3191D41BC7493182067FE40C1CAA145351B1D41068195430965FE40560E2DB2661B1D4160E5D0222161FE40D7A3703D6F1B1D41295C8FC2455EFE4060E5D0A2D71B1D41986E12834459FE40D34D6290151C1D416F1283C08A54FE40A4703D0A2C1D1D41C74B3789B549FE40C3F5285C721E1D41378941603F45FE403BDF4F0D111E1D4179E92631663FFE40AAF1D24DCA1D1D41A69BC4206A33FE404260E5D0401C1D41D578E926A32EFE4048E17A143C1C1D41DBF97E6A482AFE400AD7A3708F1C1D41E9263108E028FE40A69BC420651B1D41CBA145B62328FE40295C8F42CF191D41DD2406819B2BFE400E2DB29D79171D412B8716D9682BFE4025068195E7141D41D578E926852DFE40B6F3FDD496131D41B29DEFA7342FFE4083C0CA2101121D4152B81E85532EFE40448B6CE74E111D41D578E926EB2AFE4048E17A1425101D416891ED7CD72AFE404C3789C1CE0F1D418195438B482CFE40B29DEFA7530F1D41355EBA49A030FE4079E926B1930E1D4146B6F3FD0A31FE4075931884890D1D41736891EDAA32FE405C8FC2F55A0C1D41448B6CE74136FE4075931884590B1D417F6ABC748337FE40378941E0390A1D414E6210587B36FE405A643B5FC3081D41A8C64B37C131FE40C520B0F209081D41F4FDD4781127FE4048E17A143F071D41E7FBA9F17A22FE40B29DEF275B061D4154E3A59B4020FE40D578E926C4041D41986E1283781EFE40333333B3B3001D4106819543431DFE40355EBA49F6FF1C416DE7FBA9F11BFE40A4703D8A91FF1C41C3F5285C1F17FE40355EBAC9C6FE1C413D0AD7A32A10FE408195438B5EFE1C41CBA145B67D09FE40E9263188C8FD1C41B29DEFA7F405FE404C3789C12DFD1C41A4703D0A6305FE405C8FC275DDFC1C41E5D022DB5F05FE40A01A2F5D56FC1C41AE47E17AEC07FE40D122DB7928F91C41986E12830C08FE401904568E63F81C41105839B40807FE40B6F3FDD42BF71C4139B4C8768A03FE402506811527F51C4183C0CAA15DFFFD4091ED7C3FF6F31C41CDCCCCCCA2FAFD401B2FDD243FF31C41E7FBA9F16AF5FD40295C8F422AF21C417B14AE475BF1FD407B14AE4706F11C41F2D24D6238EFFD405C8FC27510F01C4154E3A59B56E6FD40A69BC42071ED1C41D578E926EDE3FD40105839B42EED1C41F4FDD478ADE1FD403108AC1C28ED1C4139B4C876FCDEFD409EEFA7464AED1C411904560E53DAFD40FCA9F1D2D7ED1C4133333333CBD6FD40EE7C3FB5F5ED1C41F6285C8FA0D0FD403108AC1C6FEE1C41C1CAA145DCCAFD406F12834096EE1C41D122DBF960C5FD40736891ED85EE1C413108AC1C48C3FD408D976E125EEE1C41C520B072E4BFFD4075931804C0ED1C41F0A7C64B63B7FD40508D976E20EB1C41643BDF4F75B3FD406DE7FBA9A7EA1C41DD24068109B2FD4096438BEC9AEA1C41DD24068197A8FD4046B6F3FD3EEB1C414E621058A3A5FD40CDCCCCCCCBEB1C4108AC1C5AD4A3FD409A9999998CEC1C41CBA145B6479DFD40DBF97EEAA4ED1C41D34D62108C9AFD40000000803EEE1C419CC420B03C93FD40448B6C67C7EE1C413108AC1CBC90FD406666666670EE1C412DB29DEF078BFD40DBF97EEA6FEC1C4160E5D0227188FD4054E3A59BE7EB1C41E7FBA9F11286FD401904568E23EB1C4160E5D0222F82FD40FA7E6A3CADEA1C41B0726891BB80FD40B0726891A1EA1C4148E17A14967EFD403BDF4F0DD2EA1C41CDCCCCCC307BFD407D3F35DEA2EB1C41621058398A77FD40E3A59BC4A1ED1C41D7A3703D5474FD4046B6F3FDEAEE1C41FA7E6ABC7871FD40022B879672EF1C41A01A2FDD866EFD407F6ABC748DEF1C4148E17A143059FD406891ED7C08EE1C41A8C64B373F51FD40F0A7C6CB6DEC1C4139B4C8766C4BFD40BC749318F0EA1C41378941608B48FD402731082C75EA1C418D976E12A543FD408195430BDBEA1C41736891EDE441FD404C3789C13BEB1C412B8716D96238FD4023DBF9FE09EF1C415A643BDFB533FD404C3789C180EC1C41CBA145B61732FD40A8C64BB7F3EB1C417B14AE47FF2EFD40D578E926A2EB1C4160E5D022CD2AFD40E5D022DB65EB1C4121B072681F28FD40F0A7C6CB11EB1C4154E3A59BC625FD408B6CE77B8EEA1C4117D9CEF7AD21FD4008AC1CDA33E91C41CBA145B62720FD40E5D022DBE1E81C4125068195F10FFD406891EDFC2AE61C410AD7A370230AFD40AC1C5AE470E51C41736891EDB002FD40FED4786955E51C41EE7C3F351401FD404A0C022BAEE41C41986E1283CEFFFC401904560E06E31C411D5A643B21FBFC40FCA9F1526FE21C414A0C022BE9F9FC4077BE9F1A1CE21C41295C8FC225F9FC401B2FDD24ABE11C4121B0726875F8FC405A643BDFBFDC1C41B6F3FDD460F7FC4089416065A8DB1C41DD24068123F6FC40D122DB795ADB1C41508D976E48F4FC40FED4786930DB1C41CBA145B66BE9FC40666666E67EDB1C41E17A14AE75E8FC40A8C64BB76EDB1C41295C8FC2A3E7FC405839B4C833DB1C41E17A14AE65E7FC4083C0CA21A2DA1C4179E92631D4E7FC401B2FDD242FDA1C4146B6F3FD28E9FC4021B072680BD91C41A8C64B3785EBFC40AC1C5A64BFD71C418716D9CE07EBFC4054E3A51B03D71C41713D0AD713E9FC40378941E034D61C412FDD24064BE7FC40F4FDD4F8B3D51C41BE9F1A2F9DE5FC401283C0CA86D51C416F1283C020E1FC40643BDFCF3AD61C41C3F5285C77DBFC40666666666CD71C4177BE9F1AE3D8FC4025068115A8D71C4139B4C87690D6FC400C022B8794D71C41C520B07258D5FC4048E17A943CD71C4152B81E851FD4FC4014AE47614CD61C41C520B0725CD3FC4085EB5138F7D41C41E7FBA9F17AD2FC407B14AE4761D41C4114AE47E15AD1FC402506811508D41C41D9CEF753C3CEFC408B6CE7FB7FD31C413BDF4F8DE7C6FC4052B81E0505D31C416ABC7493E0C3FC40666666665AD21C41FA7E6ABCEEC2FC40448B6C6788D11C41FED478E9C0C3FC40DD2406012FD01C41EE7C3F3552C3FC40713D0AD7EBCF1C41CBA145B623BDFC4039B4C876A3CF1C4166666666F0B3FC402FDD240626D01C417D3F355EA6B1FC40C976BE1F00D01C41D7A3703D82ADFC40894160654ACF1C414A0C022B9DA6FC4083C0CA218CCD1C4139B4C8764CA1FC409A999999B5CB1C41B6F3FDD4689FFC40F0A7C6CB78CB1C4114AE47E1309AFC40CBA145B652CB1C41D7A3703D3897FC4093180456E9CA1C411283C0CA8D94FC40D578E9264FCA1C41000000008090FC40B6F3FD5402C91C41AE47E17AC88CFC40D7A3703D54C81C413F355EBAD789FC40B81E85EBFFC71C41B81E85EBE983FC40F0A7C64B9EC71C4191ED7C3F997DFC4091ED7C3FE8C61C410C022B876871FC4077BE9F9A77C61C41273108ACE06BFC40666666E69FC51C410E2DB29DF564FC40FA7E6A3CCAC41C4177BE9F1AD95DFC40E9263108FEC41C41000000008055FC4000000000F0C31C417B14AE47F950FC40F4FDD4F8E9C21C4100000000C049FC40000000000CC21C411283C0CAB945FC4010583934E7C11C419EEFA7C64336FC40D122DBF9DCC11C41FED478E94432FC401F85EB51A1C11C415EBA490C342BFC40A245B6F345C21C411F85EB51CC25FC40DBF97EEA5FC31C411F85EB512423FC4039B4C8F673C31C417B14AE47B519FC40AE47E17A82C21C41000000008013FC408D976E928FC11C41DF4F8D977600FC40355EBAC934C11C41B29DEFA794F9FB4085EB51B832C11C41F4FDD478D5F4FB408195430B5CC11C417D3F355E78E6FB4046B6F37D82C21C41A8C64B376DDEFB409EEFA7C66BC31C4139B4C8767CDBFB40FA7E6A3C79C31C418716D9CE4DD7FB408195438B51C31C4100000000A2D3FB40CDCCCCCC75C31C4114AE47E164D1FB4025068195C4C31C41EC51B81E73CEFB408FC2F5A87FC41C4139B4C876DCC7FB4085EB51B8F0C41C4133333333EBBAFB40986E1283F9C41C4100000000C6B3FB407F6ABC74DAC31C418FC2F52826A8FB40A01A2FDDCAC21C41B6F3FDD460A6FB402B87165956C21C41D9CEF75373A3FB401B2FDDA4C5BF1C4121B072686B9FFB400AD7A370BDBD1C4117D9CEF78B94FB40E3A59B441DBB1C414E621058738BFB40D34D6290D9B91C41FA7E6ABC1080FB40A245B673E8B71C413F355EBA477EFB40F0A7C6CB62B71C41105839B47C7BFB4039B4C8F6F0B61C41BE9F1A2F136EFB40000000807FB31C41F2D24D628869FB40C976BE1FB3B21C41F4FDD478FD5FFB4014AE4761C6B11C412DB29DEFCD5CFB4014AE4761B2B11C41CFF753E33756FB40A8C64BB7DBB11C414260E5D00A46FB409CC420B0C0B11C41B29DEFA70244FB40EC51B81EA1B11C41D7A3703D3841FB40A245B6F334B11C413108AC1CAC38FB40D9CEF7D39DAE1C41713D0AD7AD32FB404A0C02ABF5AD1C417F6ABC74192DFB4008AC1CDA28AD1C4139B4C876D42AFB4008AC1C5A06AD1C410E2DB29D9523FB400E2DB29D20AD1C41EC51B81E8F1FFB40A245B673FDAC1C418D976E12E31BFB40D7A370BD1FAD1C41C976BE9FE619FB402DB29DEFF3AC1C41000000009A10FB4004560EADF2A81C4114AE47E13C09FB40D7A370BD0CA71C41736891ED4402FB40FCA9F152B3A41C414E621058D7F6FA40D122DB7952A01C414A0C022BDBF7FA40BE9F1A2F25A01C416891ED7C2FF5FA40E17A142E339F1C41EC51B81ED5F3FA4023DBF9FE739F1C41D34D62106EEEFA40D122DB79919F1C415A643BDF35EBFA400C022B0713A01C413BDF4F8D8BDBFA405A643B5FF2A41C41F4FDD47831D9FA40105839B4EDA41C41713D0AD73BD6FA4096438B6C5DA51C4117D9CEF7EBD5FA40E7FBA9719CA51C414A0C022B55D4FA40DBF97EEAA3A51C41C74B378967D3FA40D122DB7931A61C41F6285C8FA2D3FA40B81E856B7DA61C4121B0726831D3FA40713D0AD7B2A61C41DBF97E6A94CDFA40E17A142E8BA71C410C022B87A6CCFA403BDF4F8D9CA81C411904560E21CBFA40736891EDF1A81C417D3F355E76C9FA40E3A59BC413A91C410E2DB29D23C8FA40CFF753E36CA91C41448B6CE79DC6FA402506811538AA1C41894160E55EC4FA40A245B6F394AA1C41CDCCCCCC66C5FA408FC2F5288FAB1C41EC51B81EC5C5FA405A643B5FABAC1C4179E9263190C4FA40D7A370BDBDAC1C41D578E926EFC2FA4039B4C8F681AE1C41CBA145B691C5FA40D9CEF7530FB31C410E2DB29D93C2FA4046B6F3FD8DB51C41CDCCCCCC58C2FA404E621058F4B61C4191ED7C3F29C9FA4085EB51B81ACB1C41DD2406817BC8FA40FED478E9D0CB1C41105839B48EC4FA405C8FC275CFCB1C419EEFA7C6A3BAFA40F4FDD4781BCC1C41FCA9F1D24376FA40DF4F8D9783CE1C41F853E3A54D71FA406F1283C07BCE1C4196438B6CC959FA400C022B0791CC1C416891ED7C5F52FA40E9263188D2CB1C41C976BE9FD02AFA40560E2DB207C31C41F6285C8F5829FA402B87165902C31C418716D9CED525FA403D0AD7A32EC21C4177BE9F1A2D21FA400C022B07E8C11C413F355EBAD917FA4075931804C6C11C4133333333B917FA405839B44806C21C4106819543790BFA4077BE9F1A83C21C41FCA9F1D2830AFA40643BDFCF23C21C41DF4F8D97A603FA405A643BDFDAC11C41CDCCCCCCF8FEF9405A643BDF6DC11C41378941606DFDF9409A99991917C11C41CDCCCCCC32EFF9400C022B07F9C51C41E17A14AEA3E2F940CDCCCCCC8DC91C412DB29DEFAFDFF940643BDF4FDFC81C417B14AE477FDFF940448B6C67F0C81C41986E128386CFF9408D976E12E0C41C41736891EDC6CBF9402506811514C41C41713D0AD7F5C7F940250681159EC31C4106819543EBB1F940BA490C02D6C11C41E926310828ACF9408FC2F52820C11C416ABC7493D09CF940C74B3709C8BE1C41250681958990F940986E120332BC1C41273108AC967CF940378941E0CBB81C41EE7C3F352078F940F2D24DE270B81C41666666666672F940D578E92630B81C41A245B6F3356EF9408D976E12AFB71C4196438B6CDB41F94046B6F3FDC6B01C413F355EBA913AF940E3A59BC438B01C418B6CE7FBED08F940BE9F1A2FFCAD1C415839B4C89002F9405EBA498CCFAD1C4104560E2DE6D1F84077BE9F1A23AE1C4108AC1C5AD8C0F8402506819524AE1C413BDF4F8D59BCF84023DBF9FE50AE1C417F6ABC744DAAF8405C8FC2753CB01C41295C8FC28B72F84091ED7CBFABB51C4104560E2D226FF840C1CAA1C5DEB51C41D122DBF95867F840643BDFCFC0B51C41A4703D0AAD43F840621058B905B31C41EE7C3F35103BF840986E1283AFB21C41759318040E36F8401F85EBD1D1B21C4100000000D803F840C3F5285C0AB61C41AE47E17AAAFDF740560E2D3293B61C41A4703D0A37FBF74017D9CE773EB71C419EEFA7C6DBE3F7404260E550E4C11C4166666666A4E2F740A8C64B37D5C21C41BE9F1A2F79E2F74077BE9F9AF3C31C41B4C876BECBE3F74085EB51B822C51C41E9263108DEE9F7408D976E922AC81C41643BDF4F47F0F740D34D629031CB1C4179E92631CEF2F7407F6ABC74FECB1C41DD240681B9F8F74060E5D0220BCD1C41894160E5960DF840931804D6A7CE1C417F6ABC747310F8405A643BDF00CF1C4139B4C8766E15F8405839B4C825D01C4191ED7C3F1F17F8401D5A64BBD7D01C412FDD24065718F840AAF1D2CDBAD11C4139B4C8762C2DF84060E5D0A2CEEA1C4191ED7C3F6736F84093180456FEFC1C41C520B0725436F8400C022B0714FE1C4137894160F32FF840621058B93A0A1D41A245B6F37330F840736891ED940B1D41D122DBF90A32F840C520B0F2690C1D412FDD2406D334F84039B4C8F6360D1D41643BDF4F9386F840C1CAA14540201D4177BE9F1AB988F840F6285C0FF2201D418716D9CE838AF840713D0A57E9211D4133333333C794F8408D976E92FF291D4106819543FFA9F840986E1283BF331D417F6ABC74E3AAF840F4FDD478D3341D41894160E59AABF8408D976E929F381D41BA490C02C9AEF84017D9CEF7EE3B1D41F6285C8F7CB0F8409EEFA746F53C1D4160E5D022E7CEF84066666666104D1D41DD240681B7EBF8400C022B07C2561D41C520B072FAEDF8409CC420304D581D413D0AD7A348EEF840643BDF4F255A1D412DB29DEF87D7F84079E926B18E5C1D41EE7C3F35B8C9F840C1CAA1C5315E1D4123DBF97E76C8F8401F85EBD1905E1D41E7FBA9F122C5F8402FDD2406F25E1D41E3A59BC45AC4F8408D976E12345F1D41D34D62105CC2F84021B072E87F5F1D41273108AC70B8F840C1CAA145B4601D41D578E92619AEF84091ED7C3F8F611D415839B4C852ACF8408716D94EA9611D41F4FDD47899A9F8407D3F355E8A611D41105839B4EEA4F84023DBF9FE93611D41EC51B81EDD9BF840C1CAA1C5D0611D418195438B6896F8408B6CE7FBBC611D4121B072689B75F84052B81E85E1621D41736891ED9E4AF840E5D0225BB75D1D4152B81E85C349F8405A643B5FFB5D1D412B8716D97238F8400AD7A370C75F1D41B29DEFA7142FF840AAF1D24D78591D4185EB51B8F02DF8401283C04A3C591D411904560E812CF840666666669A581D413108AC1C8421F84096438BEC4C531D418195438B320AF8402DB29DEFFB551D41736891EDEC07F840448B6CE76E561D410AD7A370A9F8F7403D0AD72318581D41621058395EF8F740FED478E9FB571D41C976BE9FAAEDF74039B4C8F686591D41355EBA4932DCF740AC1C5A64A75B1D41FCA9F1D21594F7406666666685631D413D0AD7A3CC46F740E17A142E5F6C1D4100000000C0B4F64000000000C07C1D4100000000B0C7F6400000000074871D410000000080D4F64000000000148F1D4100000000B0E4F640000000004C971D410000000080EEF64000000000749D1D4100000000F009F7400000000098AC1D41000000004011F74000000000C0B21D4100000000501BF7400000000008BA1D4100000000A038F7400000000080C91D4100000000B053F7400000000098D91D4100000000C05EF7400000000030E11D4100000000506CF7400000000074E91D4100000000A078F7400000000018F01D4100000000A083F7400000000040F71D41000000009096F74000000000B0021E4100000000C0B8F7400000000088191E410000000000C6F74000000000BC211E410000000070D4F74000000000882E1E410000000080D8F74000000000E0351E4100000000D0D6F7400000000010391E4100000000C0D9F740000000003C421E4100000000F0D5F740000000009C461E4100000000C0CAF7400000000028461E410000000070BCF7400000000018461E410000000010AFF74000000000BC461E4100000000609EF740000000007C481E4100000000308FF740000000004C4B1E4100000000F085F74000000000E04D1E4100000000907BF7400000000074511E41000000004073F7400000000070551E4100000000E06DF7400000000040591E4100000000206AF74000000000885D1E4100000000C069F74000000000E8611E4100000000606EF7400000000024661E41000000006077F74000000000E4691E41000000006084F74000000000E06C1E4100000000C0BCF740000000007C761E410000000090CDF7400000000064781E410000000060E7F74000000000C8791E4100000000C0F0F74000000000C8791E410000000000FFF7400000000060791E4100000000A008F84000000000D0781E4100000000001AF84000000000A47F1E4100000000B023F8400000000004851E4100000000F031F84000000000448C1E41000000008046F8400000000094991E4100000000B059F8400000000058A81E41000000007069F84000000000BCB61E41000000003074F84000000000F0C41E4100000000F081F84000000000A4D41E41000000003090F840000000000CE41E4100000000C092F8400000000044F11E410000000010A3F8400000000014031F410000000070B6F84000000000AC201F410000000080C2F840000000007C301F4100000000A0C9F84000000000F83E1F4100000000C0D3F84000000000F84E1F410000000040DAF84000000000D45D1F410000000010E5F84000000000186E1F410000000010E7F84000000000D87B1F410000000040F3F84000000000588D1F410000000080F9F84000000000CC9B1F4100000000E006F94000000000A4AC1F41000000004006F9400000000068B91F41000000001020F9400000000020DB1F41000000003021F940000000005CE81F4100000000602DF9400000000014FA1F4100000000D03AF940000000000A0C2041000000000040F940000000005213204100000000905AF94000000000EA232041000000003068F94000000000F82B204100000000C078F94000000000F833204100000000408DF94000000000D43B204100000000D0A8F94000000000764320410000000060B9F94000000000D849204100000000B0CEF9400000000014512041000000006001FA400000000084672041000000002010FA4000000000046F204100000000D022FA40000000008E762041000000000034FA4000000000C87E204100000000C051FA4000000000DA8D2041000000009063FA4000000000C4942041000000007072FA4000000000F89B2041333333332373FA40AE47E17AE89C2041000000000064F94000000000D0A120410000000020AEF940000000005CCE2041000000008025F94000000000D8DF2041000000008025F94000000000F0EF204100000000005EFA40000000007803214100000000005EFA4000000000882A21410000000000DBFA4000000000B04D2141000000008090FC4000000000B89F2141000000008090FC400000000010BB2141');"); // Locate the geometry: final Geometry geometry = managerDao.getBronhouderGeometry (bronhouderNH); assertNotNull (geometry); assertEquals (2, geometry.getCoordinateDimension ()); assertNull (geometry.getCoordinateSystem ()); assertTrue (geometry instanceof MultiPolygon); assertEquals (1, ((MultiPolygon)geometry).size ()); assertTrue (((MultiPolygon)geometry).get (0).getArea (null).getValueAsDouble () > 3420000000.0); } @Test public void testGetAllThemas () { entityManager.flush (); final List<Thema> themas = managerDao.getAllThemas (); assertNotNull (themas); assertEquals (2, themas.size ()); assertEquals ("Protected sites", themas.get(0).getNaam()); assertEquals ("Thema 2", themas.get (1).getNaam ()); } @Test public void testGetBronhouderThemas () { entityManager.flush (); final List<BronhouderThema> bronhouderThemas = managerDao.getBronhouderThemas (); assertEquals (4, bronhouderThemas.size ()); assertEquals ("Drenthe", bronhouderThemas.get (0).getBronhouder ().getNaam ()); assertEquals ("Limburg", bronhouderThemas.get (1).getBronhouder ().getNaam ()); assertEquals ("Noord-Holland", bronhouderThemas.get (2).getBronhouder ().getNaam ()); assertEquals ("Overijssel", bronhouderThemas.get (3).getBronhouder ().getNaam ()); assertEquals ("Protected sites", bronhouderThemas.get (0).getThema ().getNaam ()); assertEquals ("Protected sites", bronhouderThemas.get (1).getThema ().getNaam ()); assertEquals ("Thema 2", bronhouderThemas.get (2).getThema ().getNaam ()); assertEquals ("Thema 2", bronhouderThemas.get (3).getThema ().getNaam ()); } @Test public void testGetBronhouderThemasByBronhouder () { entityManager.flush (); final List<BronhouderThema> bronhouderThemas1 = managerDao.getBronhouderThemas (managerDao.getBronhouderByNaam ("Limburg")); final List<BronhouderThema> bronhouderThemas2 = managerDao.getBronhouderThemas (managerDao.getBronhouderByNaam ("Overijssel")); assertEquals (1, bronhouderThemas1.size ()); assertEquals (1, bronhouderThemas2.size ()); assertEquals ("Limburg", bronhouderThemas1.get (0).getBronhouder ().getNaam ()); assertEquals ("Protected sites", bronhouderThemas1.get (0).getThema ().getNaam ()); assertEquals ("Overijssel", bronhouderThemas2.get (0).getBronhouder ().getNaam ()); assertEquals ("Thema 2", bronhouderThemas2.get (0).getThema ().getNaam ()); } @Test public void testGetBronhouderByThema () { entityManager.flush (); final List<BronhouderThema> bronhouderThemas1 = managerDao.getBronhouderThemas (managerDao.getThemaByName ("Protected sites")); final List<BronhouderThema> bronhouderThemas2 = managerDao.getBronhouderThemas (managerDao.getThemaByName ("Thema 2")); assertEquals (2, bronhouderThemas1.size ()); assertEquals (2, bronhouderThemas2.size ()); assertEquals ("Protected sites", bronhouderThemas1.get (0).getThema ().getNaam ()); assertEquals ("Protected sites", bronhouderThemas1.get (1).getThema ().getNaam ()); assertEquals ("Drenthe", bronhouderThemas1.get (0).getBronhouder ().getNaam ()); assertEquals ("Limburg", bronhouderThemas1.get (1).getBronhouder ().getNaam ()); assertEquals ("Thema 2", bronhouderThemas2.get (0).getThema ().getNaam ()); assertEquals ("Thema 2", bronhouderThemas2.get (1).getThema ().getNaam ()); assertEquals ("Noord-Holland", bronhouderThemas2.get (0).getBronhouder ().getNaam ()); assertEquals ("Overijssel", bronhouderThemas2.get (1).getBronhouder ().getNaam ()); } @Test public void testCreateBronhouderThema () { final BronhouderThema bt = new BronhouderThema (thema, managerDao.getBronhouderByNaam ("Overijssel")); managerDao.create (bt); entityManager.flush (); assertEquals (5, managerDao.getBronhouderThemas ().size ()); } @Test public void testDeleteBronhouderThema () { entityManager.flush (); final BronhouderThema bt = managerDao.getBronhouderThemas ().get (0); managerDao.delete (bt); entityManager.flush (); assertEquals (3, managerDao.getBronhouderThemas ().size ()); } @Test public void testGetBronhouderThema () { entityManager.flush (); final BronhouderThema bronhouderThema = managerDao.getBronhouderThema ( managerDao.getBronhouderByNaam ("Drenthe"), managerDao.getThemaByName ("Protected sites") ); assertNotNull (bronhouderThema); assertEquals ("Drenthe", bronhouderThema.getBronhouder ().getNaam ()); assertEquals ("Protected sites", bronhouderThema.getThema ().getNaam ()); } }