Return-Path: X-Original-To: apmail-avro-user-archive@www.apache.org Delivered-To: apmail-avro-user-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id AB01217A31 for ; Tue, 24 Feb 2015 17:40:53 +0000 (UTC) Received: (qmail 51392 invoked by uid 500); 24 Feb 2015 17:40:40 -0000 Delivered-To: apmail-avro-user-archive@avro.apache.org Received: (qmail 51324 invoked by uid 500); 24 Feb 2015 17:40:40 -0000 Mailing-List: contact user-help@avro.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: user@avro.apache.org Delivered-To: mailing list user@avro.apache.org Received: (qmail 51314 invoked by uid 99); 24 Feb 2015 17:40:40 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 24 Feb 2015 17:40:40 +0000 X-ASF-Spam-Status: No, hits=1.5 required=5.0 tests=HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of deepujain@gmail.com designates 209.85.223.171 as permitted sender) Received: from [209.85.223.171] (HELO mail-ie0-f171.google.com) (209.85.223.171) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 24 Feb 2015 17:40:15 +0000 Received: by iebtr6 with SMTP id tr6so33937291ieb.7 for ; Tue, 24 Feb 2015 09:38:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type; bh=n8GS2e8xsSzCxPeCQ5A+7clTukN+qYzh9cyk5AkKrYg=; b=krv8/MBCR9qZugMOwajOy32tvATaeJMSEBr95eycK8iBDoEIDZsKCBn4o4dj8FjcIf 0ZOjFdkvJYeGx9L7en5USYeee9gSSZ6Uz4FPvdEo/z+7AnsLmdbiTNOY4IntrgQguH3I NR2g8NTKdmS16AlNxj8gbXdm5Olb6N2W20iaURZSpfsjAN1wxiOeFQp+YPeIQk9ebLiF fKqmZQMZg0wo9kUlEOBb3vqcofwSKPkJIrGmF1OXE/QDEZ20ydfo/cPE6+EVefK0YPaX kovCiADpM+I0WA5Ilk+kKG8O0leWIgz+cpaIwxEV8KvastMTuz6xbBsbiGl98BYZg81X MfmA== X-Received: by 10.50.39.112 with SMTP id o16mr21533074igk.0.1424799523193; Tue, 24 Feb 2015 09:38:43 -0800 (PST) MIME-Version: 1.0 Received: by 10.36.61.148 with HTTP; Tue, 24 Feb 2015 09:38:23 -0800 (PST) In-Reply-To: References: From: =?UTF-8?B?w5DOnuKCrM+BQNKcICjguY/Mr82h4LmPKQ==?= Date: Tue, 24 Feb 2015 23:08:23 +0530 Message-ID: Subject: Re: Avromultiple output To: "user@avro.apache.org" Content-Type: multipart/alternative; boundary=047d7bdca2f474f0d2050fd8fd5d X-Virus-Checked: Checked by ClamAV on apache.org --047d7bdca2f474f0d2050fd8fd5d Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Share your avro dependencies(versions) in case your using maven and hadoop dependencies (version) On Tue, Feb 24, 2015 at 11:06 PM, =C3=90=CE=9E=E2=82=AC=CF=81@=D2=9C (=E0= =B9=8F=CC=AF=CD=A1=E0=B9=8F) wrote: > Check your Hadoop version. In older version JobContext was interface and > in new one its class. > > On Tue, Feb 24, 2015 at 10:28 PM, David Ginzburg > wrote: > >> Thank you for the answer. >> >> Tried but the exception >> * Error: Found interface org.apache.hadoop.mapreduce.JobContext, but >> class was expected* >> persists >> >> On Tue, Feb 24, 2015 at 3:12 PM, Artem Ervits >> wrote: >> >>> try this >>> >>> Job job =3D Job.getInstance(conf); >>> Job.setName(name); >>> >>> Artem Ervits >>> On Feb 21, 2015 10:57 PM, "David Ginzburg" >>> wrote: >>> >>>> Hi, >>>> I am trying to run an MR job on emr with AvromultipleOutput >>>> >>>> >>>> >>>> >>>> I get the following exception when running with AMI with hadoop 2.2 2.= 5 >>>> Found interface org.apache.hadoop.mapreduce.JobContext, but class was >>>> expected >>>> >>>> I read it is related to incompatible hadoop versions, So I modified >>>> >>>> When running with AMI with hadoop 103 I get the following exception: >>>> >>>> java.lang.NullPointerException >>>> at >>>> org.apache.hadoop.io.serializer.SerializationFactory.getSerializer(Ser= ializationFactory.java:73) >>>> at >>>> org.apache.hadoop.mapred.MapTask$MapOutputBuffer.(MapTask.java:9= 81) >>>> at >>>> org.apache.hadoop.mapred.MapTask$NewOutputCollector.(MapTask.jav= a:681) >>>> at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:763) >>>> at org.apache.hadoop.mapred.MapTask.run(MapTask.java:375) >>>> at org.apache.hadoop.mapred.Child$4.run(Child.java:259) >>>> at java.security.AccessController.doPrivileged(Native Method) >>>> at javax.security.auth.Subject.doAs(Subject.java:415) >>>> at >>>> org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformat= ion.java:1140) >>>> at org.apache.hadoop.mapred.Child.main(Child.java:253) >>>> >>>> >>>> The driver code is >>>> >>>> Job job =3D new Job(getConf(), "myad"); >>>> >>>> >>>> >>>> job.setOutputValueClass(NullWritable.class); >>>> >>>> >>>> job.setJarByClass(myAdTextLineMapper.class); >>>> Path inputOflineFiles =3D new Path(args[0]); >>>> Path inputOfUbberFiles =3D new Path(args[1]); >>>> >>>> FileInputFormat.setInputPaths(job, inputOflineFiles); >>>> >>>> job.setMapperClass(myAdTextLineMapper.class); >>>> job.setMapOutputKeyClass(Text.class); >>>> job.setMapOutputValueClass(UberRecord.class); >>>> >>>> job.setOutputFormatClass(AvroSequenceFileOutputFormat.class); >>>> AvroJob.setOutputKeySchema(job, >>>> Schema.create(Schema.Type.STRING)); >>>> AvroJob.setOutputValueSchema(job, UberRecord.SCHEMA$); >>>> >>>> >>>> job.setReducerClass(myAdReducer.class); >>>> job.setOutputKeyClass(Text.class); >>>> job.setOutputValueClass(UberRecord.class); >>>> job.setNumReduceTasks(2); >>>> String baseoutputFolder =3D args[2]; >>>> job.getConfiguration().set(myAdReducer.BASE_OUTPUT_FOLDER, >>>> baseoutputFolder); >>>> ; >>>> >>>> LazyOutputFormat.setOutputFormatClass(job,AvroSequenceFileOutputFormat= .class); >>>> >>>> FileOutputFormat.setOutputPath(job, new Path(baseoutputFolder)= ); >>>> return job.waitForCompletion(true) ? 0 : 1; >>>> >>>> >>>> the mapper and reducers >>>> @Override >>>> public void setup(Context ctx) { >>>> >>>> ubp =3D new UberRecordProcessor(); >>>> } >>>> >>>> @Override >>>> protected void map(LongWritable key, Text value, Context context) >>>> throws IOException, InterruptedException { >>>> try { >>>> handleLineinMap(value); >>>> if(ub!=3Dnull){ >>>> context.write(new Text(ub.getAuctionId().toString()), >>>> ub); >>>> context.getCounter("myAd", >>>> "myAdTextLineMapper").increment(1); >>>> }else{ >>>> context.getCounter("myAd", >>>> "myAdTextLineMapperNull").increment(1); >>>> } >>>> } catch (Exception e) { >>>> context.getCounter("myAd", >>>> "myAdTextLineMapperError").increment(1); >>>> logger.warn("could not parse line "+value.toString(),e); >>>> >>>> >>>> } >>>> } >>>> >>>> public class myAdReducer extends >>>> Reducer, >>>> AvroValue> { >>>> >>>> private static Logger logger =3D Logger.getLogger(myAdReducer.clas= s); >>>> public static final String BASE_OUTPUT_FOLDER =3D >>>> "base.output.folder"; >>>> AvroMultipleOutputs amos; MultipleOutputs output= s; >>>> UberRecordProcessor ubp =3D new UberRecordProcessor(); >>>> // "year=3D%s/month=3D%s/day=3D%s/hour=3D%s" >>>> private String baseOutputPath; >>>> private long reduceAttemptUniqueIdentifier =3D >>>> System.currentTimeMillis(); >>>> >>>> // 2015-02-01T18:00:25.673Z >>>> static DateTimeFormatter dateformat =3D DateTimeFormat >>>> .forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZZ"); >>>> >>>> @Override >>>> protected void setup(Context context) throws IOException, >>>> InterruptedException { >>>> >>>> amos =3D new AvroMultipleOutputs(context); >>>> baseOutputPath =3D >>>> context.getConfiguration().get(BASE_OUTPUT_FOLDER); >>>> >>>> } >>>> >>>> @Override >>>> protected void reduce(Text key, Iterable values, >>>> Context context) >>>> throws IOException, InterruptedException { >>>> >>>> try { >>>> UberRecord ub =3D new UberRecord(); >>>> for (UberRecord ubi : values) { >>>> // enrich >>>> if (ubi.getExchange() =3D=3D null) { >>>> continue; >>>> } >>>> BaseBidRequestEnricher enc =3D BaseBidRequestEnricher >>>> .getEnricher(ubi.getExchange().toString()); >>>> enc.enrich(ubi); >>>> ub =3D mergeUB(ub, ubi); >>>> } >>>> logger.info("Writing UberRecord [" + ub.toString() + "]"); >>>> String partition =3D getPartition(ub); >>>> >>>> // context.write(); >>>> // AvroKey, AvroValue> >>>> amos.write(new AvroKey(key.toString()), >>>> new AvroValue(ub), baseOutputPath + "/= " >>>> + partition + "/p" + >>>> reduceAttemptUniqueIdentifier); >>>> } catch (Exception e) { >>>> // TODO Auto-generated catch block >>>> e.printStackTrace(); >>>> } >>>> } >>>> >>>> public UberRecord mergeUB(UberRecord dest, UberRecord src) { >>>> List fields =3D UberRecord.getClassSchema().getFields()= ; >>>> List engFields =3D EngageData.getClassSchema().getField= s(); >>>> for (Field field : fields) { >>>> if (field.name().equals("engageData") >>>> && dest.getEngageData() !=3D null) { >>>> EngageData mergedEng =3D dest.getEngageData(); >>>> for (Field engField : engFields) { >>>> if (dest.getEngageData().get(engField.name()) =3D= =3D >>>> null) { >>>> mergedEng.put(engField.name(), >>>> >>>> src.getEngageData().get(engField.name())); >>>> } >>>> >>>> } >>>> dest.setEngageData(mergedEng); >>>> } else { >>>> if (dest.get(field.name()) =3D=3D null) { >>>> dest.put(field.name(), src.get(field.name())); >>>> } >>>> } >>>> } >>>> return dest; >>>> } >>>> >>>> >>>> >>>> >> > > > -- > Deepak > > --=20 Deepak --047d7bdca2f474f0d2050fd8fd5d Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+U2hhcmUgeW91ciBhdnJvIGRlcGVuZGVuY2llcyh2ZXJzaW9ucykgaW4g Y2FzZSB5b3VyIHVzaW5nIG1hdmVuIGFuZCBoYWRvb3AgZGVwZW5kZW5jaWVzICh2ZXJzaW9uKTxk aXY+PGJyPjwvZGl2PjxkaXY+PGJyPjwvZGl2PjwvZGl2PjxkaXYgY2xhc3M9ImdtYWlsX2V4dHJh Ij48YnI+PGRpdiBjbGFzcz0iZ21haWxfcXVvdGUiPk9uIFR1ZSwgRmViIDI0LCAyMDE1IGF0IDEx OjA2IFBNLCDDkM6e4oKsz4FA0pwgKOC5j8yvzaHguY8pIDxzcGFuIGRpcj0ibHRyIj4mbHQ7PGEg aHJlZj0ibWFpbHRvOmRlZXB1amFpbkBnbWFpbC5jb20iIHRhcmdldD0iX2JsYW5rIj5kZWVwdWph aW5AZ21haWwuY29tPC9hPiZndDs8L3NwYW4+IHdyb3RlOjxicj48YmxvY2txdW90ZSBjbGFzcz0i Z21haWxfcXVvdGUiIHN0eWxlPSJtYXJnaW46MCAwIDAgLjhleDtib3JkZXItbGVmdDoxcHggI2Nj YyBzb2xpZDtwYWRkaW5nLWxlZnQ6MWV4Ij48ZGl2IGRpcj0ibHRyIj5DaGVjayB5b3VyIEhhZG9v cCB2ZXJzaW9uLiBJbiBvbGRlciB2ZXJzaW9uIEpvYkNvbnRleHQgd2FzIGludGVyZmFjZSBhbmQg aW4gbmV3IG9uZSBpdHMgY2xhc3MuPC9kaXY+PGRpdiBjbGFzcz0iZ21haWxfZXh0cmEiPjxkaXY+ PGRpdiBjbGFzcz0iaDUiPjxicj48ZGl2IGNsYXNzPSJnbWFpbF9xdW90ZSI+T24gVHVlLCBGZWIg MjQsIDIwMTUgYXQgMTA6MjggUE0sIERhdmlkIEdpbnpidXJnIDxzcGFuIGRpcj0ibHRyIj4mbHQ7 PGEgaHJlZj0ibWFpbHRvOmRhdmlkZ2luemJ1cmdAZ21haWwuY29tIiB0YXJnZXQ9Il9ibGFuayI+ ZGF2aWRnaW56YnVyZ0BnbWFpbC5jb208L2E+Jmd0Ozwvc3Bhbj4gd3JvdGU6PGJyPjxibG9ja3F1 b3RlIGNsYXNzPSJnbWFpbF9xdW90ZSIgc3R5bGU9Im1hcmdpbjowIDAgMCAuOGV4O2JvcmRlci1s ZWZ0OjFweCAjY2NjIHNvbGlkO3BhZGRpbmctbGVmdDoxZXgiPjxkaXYgZGlyPSJsdHIiPjxkaXY+ PGRpdj5UaGFuayB5b3UgZm9yIHRoZSBhbnN3ZXIuPGJyPjxicj48L2Rpdj5UcmllZCBidXQgdGhl IGV4Y2VwdGlvbjxicj48aT7CoEVycm9yOiBGb3VuZCBpbnRlcmZhY2Ugb3JnLmFwYWNoZS5oYWRv b3AubWFwcmVkdWNlLkpvYkNvbnRleHQsIGJ1dCBjbGFzcyB3YXMgZXhwZWN0ZWQ8L2k+PGJyPjwv ZGl2PnBlcnNpc3RzwqAgPGJyPjwvZGl2PjxkaXY+PGRpdj48ZGl2IGNsYXNzPSJnbWFpbF9leHRy YSI+PGJyPjxkaXYgY2xhc3M9ImdtYWlsX3F1b3RlIj5PbiBUdWUsIEZlYiAyNCwgMjAxNSBhdCAz OjEyIFBNLCBBcnRlbSBFcnZpdHMgPHNwYW4gZGlyPSJsdHIiPiZsdDs8YSBocmVmPSJtYWlsdG86 YXJ0ZW1lcnZpdHNAZ21haWwuY29tIiB0YXJnZXQ9Il9ibGFuayI+YXJ0ZW1lcnZpdHNAZ21haWwu Y29tPC9hPiZndDs8L3NwYW4+IHdyb3RlOjxicj48YmxvY2txdW90ZSBjbGFzcz0iZ21haWxfcXVv dGUiIHN0eWxlPSJtYXJnaW46MCAwIDAgLjhleDtib3JkZXItbGVmdDoxcHggI2NjYyBzb2xpZDtw YWRkaW5nLWxlZnQ6MWV4Ij48cCBkaXI9Imx0ciI+dHJ5IHRoaXM8L3A+DQo8cCBkaXI9Imx0ciI+ Sm9iIGpvYiA9IEpvYi5nZXRJbnN0YW5jZShjb25mKTs8YnI+DQpKb2Iuc2V0TmFtZShuYW1lKTs8 L3A+DQo8cCBkaXI9Imx0ciI+QXJ0ZW0gRXJ2aXRzPC9wPjxkaXY+PGRpdj4NCjxkaXYgY2xhc3M9 ImdtYWlsX3F1b3RlIj5PbiBGZWIgMjEsIDIwMTUgMTA6NTcgUE0sICZxdW90O0RhdmlkIEdpbnpi dXJnJnF1b3Q7ICZsdDs8YSBocmVmPSJtYWlsdG86ZGF2aWRnaW56YnVyZ0BnbWFpbC5jb20iIHRh cmdldD0iX2JsYW5rIj5kYXZpZGdpbnpidXJnQGdtYWlsLmNvbTwvYT4mZ3Q7IHdyb3RlOjxiciB0 eXBlPSJhdHRyaWJ1dGlvbiI+PGJsb2NrcXVvdGUgY2xhc3M9ImdtYWlsX3F1b3RlIiBzdHlsZT0i bWFyZ2luOjAgMCAwIC44ZXg7Ym9yZGVyLWxlZnQ6MXB4ICNjY2Mgc29saWQ7cGFkZGluZy1sZWZ0 OjFleCI+PGRpdiBkaXI9Imx0ciI+SGksPGJyPkkgYW0gdHJ5aW5nIHRvIHJ1biBhbiBNUiBqb2Ig b24gZW1yIHdpdGggQXZyb211bHRpcGxlT3V0cHV0PGJyPjxicj7CoDxicj48YnI+PGJyPkkgZ2V0 IHRoZSBmb2xsb3dpbmcgZXhjZXB0aW9uIHdoZW4gcnVubmluZyB3aXRoIEFNSSB3aXRoIGhhZG9v cCAyLjIgMi41PGJyPkZvdW5kIGludGVyZmFjZSBvcmcuYXBhY2hlLmhhZG9vcC5tYXByZWR1Y2Uu Sm9iQ29udGV4dCwgYnV0IGNsYXNzIHdhcyBleHBlY3RlZDxicj48YnI+SSByZWFkIGl0IGlzIHJl bGF0ZWQgdG8gaW5jb21wYXRpYmxlIGhhZG9vcCB2ZXJzaW9ucywgU28gSSBtb2RpZmllZDxicj48 YnI+V2hlbiBydW5uaW5nIHdpdGggQU1JIHdpdGggaGFkb29wIDEwMyBJIGdldCB0aGUgZm9sbG93 aW5nIGV4Y2VwdGlvbjogPGJyPjxicj5qYXZhLmxhbmcuTnVsbFBvaW50ZXJFeGNlcHRpb248YnI+ wqDCoMKgIGF0IG9yZy5hcGFjaGUuaGFkb29wLmlvLnNlcmlhbGl6ZXIuU2VyaWFsaXphdGlvbkZh Y3RvcnkuZ2V0U2VyaWFsaXplcihTZXJpYWxpemF0aW9uRmFjdG9yeS5qYXZhOjczKTxicj7CoMKg wqAgYXQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLk1hcFRhc2skTWFwT3V0cHV0QnVmZmVyLiZs dDtpbml0Jmd0OyhNYXBUYXNrLmphdmE6OTgxKTxicj7CoMKgwqAgYXQgb3JnLmFwYWNoZS5oYWRv b3AubWFwcmVkLk1hcFRhc2skTmV3T3V0cHV0Q29sbGVjdG9yLiZsdDtpbml0Jmd0OyhNYXBUYXNr LmphdmE6NjgxKTxicj7CoMKgwqAgYXQgb3JnLmFwYWNoZS5oYWRvb3AubWFwcmVkLk1hcFRhc2su cnVuTmV3TWFwcGVyKE1hcFRhc2suamF2YTo3NjMpPGJyPsKgwqDCoCBhdCBvcmcuYXBhY2hlLmhh ZG9vcC5tYXByZWQuTWFwVGFzay5ydW4oTWFwVGFzay5qYXZhOjM3NSk8YnI+wqDCoMKgIGF0IG9y Zy5hcGFjaGUuaGFkb29wLm1hcHJlZC5DaGlsZCQ0LnJ1bihDaGlsZC5qYXZhOjI1OSk8YnI+wqDC oMKgIGF0IGphdmEuc2VjdXJpdHkuQWNjZXNzQ29udHJvbGxlci5kb1ByaXZpbGVnZWQoTmF0aXZl IE1ldGhvZCk8YnI+wqDCoMKgIGF0IGphdmF4LnNlY3VyaXR5LmF1dGguU3ViamVjdC5kb0FzKFN1 YmplY3QuamF2YTo0MTUpPGJyPsKgwqDCoCBhdCBvcmcuYXBhY2hlLmhhZG9vcC5zZWN1cml0eS5V c2VyR3JvdXBJbmZvcm1hdGlvbi5kb0FzKFVzZXJHcm91cEluZm9ybWF0aW9uLmphdmE6MTE0MCk8 YnI+wqDCoMKgIGF0IG9yZy5hcGFjaGUuaGFkb29wLm1hcHJlZC5DaGlsZC5tYWluKENoaWxkLmph dmE6MjUzKTxicj48YnI+PGJyPlRoZSBkcml2ZXIgY29kZSBpcyDCoMKgwqAgPGJyPjxicj5Kb2Ig am9iID0gbmV3IEpvYihnZXRDb25mKCksICZxdW90O215YWQmcXVvdDspOzxicj7CoMKgwqAgwqDC oMKgIDxicj7CoMKgwqAgwqDCoMKgIDxicj7CoMKgwqAgwqDCoMKgIDxicj7CoMKgwqAgwqDCoMKg IGpvYi5zZXRPdXRwdXRWYWx1ZUNsYXNzKE51bGxXcml0YWJsZS5jbGFzcyk7PGJyPjxicj7CoMKg wqAgwqDCoMKgIDxicj7CoMKgwqAgwqDCoMKgIGpvYi5zZXRKYXJCeUNsYXNzKG15QWRUZXh0TGlu ZU1hcHBlci5jbGFzcyk7PGJyPsKgwqDCoCDCoMKgwqAgUGF0aCBpbnB1dE9mbGluZUZpbGVzID0g bmV3IFBhdGgoYXJnc1swXSk7PGJyPsKgwqDCoCDCoMKgwqAgUGF0aCBpbnB1dE9mVWJiZXJGaWxl cyA9IG5ldyBQYXRoKGFyZ3NbMV0pOzxicj7CoMKgwqAgwqDCoMKgIDxicj7CoMKgwqAgwqDCoMKg IMKgRmlsZUlucHV0Rm9ybWF0LnNldElucHV0UGF0aHMoam9iLCBpbnB1dE9mbGluZUZpbGVzKTs8 YnI+wqDCoMKgIMKgwqDCoCA8YnI+wqDCoMKgIMKgwqDCoCBqb2Iuc2V0TWFwcGVyQ2xhc3MobXlB ZFRleHRMaW5lTWFwcGVyLmNsYXNzKTs8YnI+wqDCoMKgIMKgwqDCoCBqb2Iuc2V0TWFwT3V0cHV0 S2V5Q2xhc3MoVGV4dC5jbGFzcyk7PGJyPsKgwqDCoCDCoMKgwqAgam9iLnNldE1hcE91dHB1dFZh bHVlQ2xhc3MoVWJlclJlY29yZC5jbGFzcyk7PGJyPsKgwqDCoCDCoMKgwqAgPGJyPsKgwqDCoCDC oMKgwqAgam9iLnNldE91dHB1dEZvcm1hdENsYXNzKEF2cm9TZXF1ZW5jZUZpbGVPdXRwdXRGb3Jt YXQuY2xhc3MpOzxicj7CoMKgwqAgwqDCoMKgIEF2cm9Kb2Iuc2V0T3V0cHV0S2V5U2NoZW1hKGpv YiwgU2NoZW1hLmNyZWF0ZShTY2hlbWEuVHlwZS5TVFJJTkcpKTs8YnI+wqDCoMKgIMKgwqDCoCBB dnJvSm9iLnNldE91dHB1dFZhbHVlU2NoZW1hKGpvYiwgVWJlclJlY29yZC5TQ0hFTUEkKTs8YnI+ PGJyPjxicj7CoMKgwqAgwqDCoMKgIGpvYi5zZXRSZWR1Y2VyQ2xhc3MobXlBZFJlZHVjZXIuY2xh c3MpOzxicj7CoMKgwqAgwqDCoMKgIGpvYi5zZXRPdXRwdXRLZXlDbGFzcyhUZXh0LmNsYXNzKTs8 YnI+wqDCoMKgIMKgwqDCoCBqb2Iuc2V0T3V0cHV0VmFsdWVDbGFzcyhVYmVyUmVjb3JkLmNsYXNz KTs8YnI+wqDCoMKgIMKgwqDCoCBqb2Iuc2V0TnVtUmVkdWNlVGFza3MoMik7PGJyPsKgwqDCoCDC oMKgwqAgU3RyaW5nIGJhc2VvdXRwdXRGb2xkZXIgPSBhcmdzWzJdOzxicj7CoMKgwqAgwqDCoMKg IGpvYi5nZXRDb25maWd1cmF0aW9uKCkuc2V0KG15QWRSZWR1Y2VyLkJBU0VfT1VUUFVUX0ZPTERF Uiw8YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqAgwqDCoMKgIGJhc2VvdXRwdXRGb2xkZXIpOzxicj7C oMKgwqAgwqDCoMKgIDs8YnI+wqDCoMKgIMKgwqDCoCBMYXp5T3V0cHV0Rm9ybWF0LnNldE91dHB1 dEZvcm1hdENsYXNzKGpvYixBdnJvU2VxdWVuY2VGaWxlT3V0cHV0Rm9ybWF0LmNsYXNzKTsgPGJy PsKgwqDCoCDCoMKgwqAgRmlsZU91dHB1dEZvcm1hdC5zZXRPdXRwdXRQYXRoKGpvYiwgbmV3IFBh dGgoYmFzZW91dHB1dEZvbGRlcikpOzxicj7CoMKgwqAgwqDCoMKgIHJldHVybiBqb2Iud2FpdEZv ckNvbXBsZXRpb24odHJ1ZSkgPyAwIDogMTs8YnI+PGJyPjxicj50aGUgbWFwcGVyIGFuZCByZWR1 Y2Vyczxicj5AT3ZlcnJpZGU8YnI+wqDCoMKgIHB1YmxpYyB2b2lkIHNldHVwKENvbnRleHQgY3R4 KSB7PGJyPjxicj7CoMKgwqAgwqDCoMKgIHVicCA9IG5ldyBVYmVyUmVjb3JkUHJvY2Vzc29yKCk7 PGJyPsKgwqDCoCB9PGJyPjxicj7CoMKgwqAgQE92ZXJyaWRlPGJyPsKgwqDCoCBwcm90ZWN0ZWQg dm9pZCBtYXAoTG9uZ1dyaXRhYmxlIGtleSwgVGV4dCB2YWx1ZSwgQ29udGV4dCBjb250ZXh0KTxi cj7CoMKgwqAgwqDCoMKgIMKgwqDCoCB0aHJvd3MgSU9FeGNlcHRpb24sIEludGVycnVwdGVkRXhj ZXB0aW9uIHs8YnI+wqDCoMKgIMKgwqDCoCB0cnkgezxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCBo YW5kbGVMaW5laW5NYXAodmFsdWUpOzxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCBpZih1YiE9bnVs bCl7PGJyPsKgwqDCoCDCoMKgwqAgwqDCoMKgIMKgwqDCoCBjb250ZXh0LndyaXRlKG5ldyBUZXh0 KHViLmdldEF1Y3Rpb25JZCgpLnRvU3RyaW5nKCkpLCB1Yik7PGJyPsKgwqDCoCDCoMKgwqAgwqDC oMKgIMKgwqDCoCBjb250ZXh0LmdldENvdW50ZXIoJnF1b3Q7bXlBZCZxdW90OywgJnF1b3Q7bXlB ZFRleHRMaW5lTWFwcGVyJnF1b3Q7KS5pbmNyZW1lbnQoMSk7PGJyPsKgwqDCoCDCoMKgwqAgwqDC oMKgIH1lbHNlezxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqAgY29udGV4dC5nZXRDb3Vu dGVyKCZxdW90O215QWQmcXVvdDssICZxdW90O215QWRUZXh0TGluZU1hcHBlck51bGwmcXVvdDsp LmluY3JlbWVudCgxKTs8YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqAgfTxicj7CoMKgwqAgwqDCoMKg IH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7PGJyPsKgwqDCoCDCoMKgwqAgwqDCoMKgIGNvbnRleHQu Z2V0Q291bnRlcigmcXVvdDtteUFkJnF1b3Q7LCAmcXVvdDtteUFkVGV4dExpbmVNYXBwZXJFcnJv ciZxdW90OykuaW5jcmVtZW50KDEpOzxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCBsb2dnZXIud2Fy bigmcXVvdDtjb3VsZCBub3QgcGFyc2UgbGluZSAmcXVvdDsrdmFsdWUudG9TdHJpbmcoKSxlKTs8 YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqAgPGJyPjxicj7CoMKgwqAgwqDCoMKgIH08YnI+wqDCoMKg IH08YnI+PGJyPnB1YmxpYyBjbGFzcyBteUFkUmVkdWNlciBleHRlbmRzPGJyPsKgwqDCoCDCoMKg wqAgUmVkdWNlciZsdDtUZXh0LCBVYmVyUmVjb3JkLCBBdnJvS2V5Jmx0O0NoYXJTZXF1ZW5jZSZn dDssIEF2cm9WYWx1ZSZsdDtVYmVyUmVjb3JkJmd0OyZndDsgezxicj48YnI+wqDCoMKgIHByaXZh dGUgc3RhdGljIExvZ2dlciBsb2dnZXIgPSBMb2dnZXIuZ2V0TG9nZ2VyKG15QWRSZWR1Y2VyLmNs YXNzKTs8YnI+wqDCoMKgIHB1YmxpYyBzdGF0aWMgZmluYWwgU3RyaW5nIEJBU0VfT1VUUFVUX0ZP TERFUiA9ICZxdW90O2Jhc2Uub3V0cHV0LmZvbGRlciZxdW90Ozs8YnI+wqDCoMKgIEF2cm9NdWx0 aXBsZU91dHB1dHMgYW1vczsgTXVsdGlwbGVPdXRwdXRzJmx0O1RleHQsIFViZXJSZWNvcmQmZ3Q7 IG91dHB1dHM7PGJyPsKgwqDCoCBVYmVyUmVjb3JkUHJvY2Vzc29yIHVicCA9IG5ldyBVYmVyUmVj b3JkUHJvY2Vzc29yKCk7PGJyPsKgwqDCoCAvLyAmcXVvdDt5ZWFyPSVzL21vbnRoPSVzL2RheT0l cy9ob3VyPSVzJnF1b3Q7PGJyPsKgwqDCoCBwcml2YXRlIFN0cmluZyBiYXNlT3V0cHV0UGF0aDs8 YnI+wqDCoMKgIHByaXZhdGUgbG9uZyByZWR1Y2VBdHRlbXB0VW5pcXVlSWRlbnRpZmllciA9IFN5 c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOzxicj48YnI+wqDCoMKgIC8vIDIwMTUtMDItMDFUMTg6 MDA6MjUuNjczWjxicj7CoMKgwqAgc3RhdGljIERhdGVUaW1lRm9ybWF0dGVyIGRhdGVmb3JtYXQg PSBEYXRlVGltZUZvcm1hdDxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCAuZm9yUGF0dGVybigmcXVv dDt5eXl5LU1NLWRkJiMzOTtUJiMzOTtISDptbTpzcy5TU1NaWiZxdW90Oyk7PGJyPjxicj7CoMKg wqAgQE92ZXJyaWRlPGJyPsKgwqDCoCBwcm90ZWN0ZWQgdm9pZCBzZXR1cChDb250ZXh0IGNvbnRl eHQpIHRocm93cyBJT0V4Y2VwdGlvbiw8YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqAgSW50ZXJydXB0 ZWRFeGNlcHRpb24gezxicj7CoMKgwqAgwqDCoMKgIDxicj7CoMKgwqAgwqDCoMKgIGFtb3MgPSBu ZXcgQXZyb011bHRpcGxlT3V0cHV0cyhjb250ZXh0KTs8YnI+wqDCoMKgIMKgwqDCoCBiYXNlT3V0 cHV0UGF0aCA9IGNvbnRleHQuZ2V0Q29uZmlndXJhdGlvbigpLmdldChCQVNFX09VVFBVVF9GT0xE RVIpOzxicj48YnI+wqDCoMKgIH08YnI+PGJyPsKgwqDCoCBAT3ZlcnJpZGU8YnI+wqDCoMKgIHBy b3RlY3RlZCB2b2lkIHJlZHVjZShUZXh0IGtleSwgSXRlcmFibGUmbHQ7VWJlclJlY29yZCZndDsg dmFsdWVzLCBDb250ZXh0IGNvbnRleHQpPGJyPsKgwqDCoCDCoMKgwqAgwqDCoMKgIHRocm93cyBJ T0V4Y2VwdGlvbiwgSW50ZXJydXB0ZWRFeGNlcHRpb24gezxicj48YnI+wqDCoMKgIMKgwqDCoCB0 cnkgezxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCBVYmVyUmVjb3JkIHViID0gbmV3IFViZXJSZWNv cmQoKTs8YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqAgZm9yIChVYmVyUmVjb3JkIHViaSA6IHZhbHVl cykgezxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqAgLy8gZW5yaWNoPGJyPsKgwqDCoCDC oMKgwqAgwqDCoMKgIMKgwqDCoCBpZiAodWJpLmdldEV4Y2hhbmdlKCkgPT0gbnVsbCkgezxicj7C oMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqAgwqDCoMKgIGNvbnRpbnVlOzxicj7CoMKgwqAgwqDC oMKgIMKgwqDCoCDCoMKgwqAgfTxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqAgQmFzZUJp ZFJlcXVlc3RFbnJpY2hlciBlbmMgPSBCYXNlQmlkUmVxdWVzdEVucmljaGVyPGJyPsKgwqDCoCDC oMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqAgwqDCoMKgIC5nZXRFbnJpY2hlcih1YmkuZ2V0RXhj aGFuZ2UoKS50b1N0cmluZygpKTs8YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqAgwqDCoMKgIGVuYy5l bnJpY2godWJpKTs8YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqAgwqDCoMKgIHViID0gbWVyZ2VVQih1 YiwgdWJpKTs8YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqAgfTxicj7CoMKgwqAgwqDCoMKgIMKgwqDC oCA8YSBocmVmPSJodHRwOi8vbG9nZ2VyLmluZm8iIHRhcmdldD0iX2JsYW5rIj5sb2dnZXIuaW5m bzwvYT4oJnF1b3Q7V3JpdGluZyBVYmVyUmVjb3JkIFsmcXVvdDsgKyB1Yi50b1N0cmluZygpICsg JnF1b3Q7XSZxdW90Oyk7PGJyPsKgwqDCoCDCoMKgwqAgwqDCoMKgIFN0cmluZyBwYXJ0aXRpb24g PSBnZXRQYXJ0aXRpb24odWIpOzxicj48YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqAgLy8gY29udGV4 dC53cml0ZSgpOzxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCAvLyBBdnJvS2V5Jmx0O0NoYXJTZXF1 ZW5jZSZndDssIEF2cm9WYWx1ZSZsdDtVYmVyUmVjb3JkJmd0OyZndDs8YnI+wqDCoMKgIMKgwqDC oCDCoMKgwqAgYW1vcy53cml0ZShuZXcgQXZyb0tleSZsdDtDaGFyU2VxdWVuY2UmZ3Q7KGtleS50 b1N0cmluZygpKSw8YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqAgwqDCoMKgIMKgwqDCoCBuZXcgQXZy b1ZhbHVlJmx0O1ViZXJSZWNvcmQmZ3Q7KHViKSwgYmFzZU91dHB1dFBhdGggKyAmcXVvdDsvJnF1 b3Q7PGJyPsKgwqDCoCDCoMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqAgwqDCoMKgIMKgwqDCoCAr IHBhcnRpdGlvbiArICZxdW90Oy9wJnF1b3Q7ICsgcmVkdWNlQXR0ZW1wdFVuaXF1ZUlkZW50aWZp ZXIpOzxicj7CoMKgwqAgwqDCoMKgIH0gY2F0Y2ggKEV4Y2VwdGlvbiBlKSB7PGJyPsKgwqDCoCDC oMKgwqAgwqDCoMKgIC8vIFRPRE8gQXV0by1nZW5lcmF0ZWQgY2F0Y2ggYmxvY2s8YnI+wqDCoMKg IMKgwqDCoCDCoMKgwqAgZS5wcmludFN0YWNrVHJhY2UoKTs8YnI+wqDCoMKgIMKgwqDCoCB9PGJy PsKgwqDCoCB9PGJyPjxicj7CoMKgwqAgcHVibGljIFViZXJSZWNvcmQgbWVyZ2VVQihVYmVyUmVj b3JkIGRlc3QsIFViZXJSZWNvcmQgc3JjKSB7PGJyPsKgwqDCoCDCoMKgwqAgTGlzdCZsdDtGaWVs ZCZndDsgZmllbGRzID0gVWJlclJlY29yZC5nZXRDbGFzc1NjaGVtYSgpLmdldEZpZWxkcygpOzxi cj7CoMKgwqAgwqDCoMKgIExpc3QmbHQ7RmllbGQmZ3Q7IGVuZ0ZpZWxkcyA9IEVuZ2FnZURhdGEu Z2V0Q2xhc3NTY2hlbWEoKS5nZXRGaWVsZHMoKTs8YnI+wqDCoMKgIMKgwqDCoCBmb3IgKEZpZWxk IGZpZWxkIDogZmllbGRzKSB7PGJyPsKgwqDCoCDCoMKgwqAgwqDCoMKgIGlmICg8YSBocmVmPSJo dHRwOi8vZmllbGQubmFtZSIgdGFyZ2V0PSJfYmxhbmsiPmZpZWxkLm5hbWU8L2E+KCkuZXF1YWxz KCZxdW90O2VuZ2FnZURhdGEmcXVvdDspPGJyPsKgwqDCoCDCoMKgwqAgwqDCoMKgIMKgwqDCoCDC oMKgwqAgJmFtcDsmYW1wOyBkZXN0LmdldEVuZ2FnZURhdGEoKSAhPSBudWxsKSB7PGJyPsKgwqDC oCDCoMKgwqAgwqDCoMKgIMKgwqDCoCBFbmdhZ2VEYXRhIG1lcmdlZEVuZyA9IGRlc3QuZ2V0RW5n YWdlRGF0YSgpOzxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqAgZm9yIChGaWVsZCBlbmdG aWVsZCA6IGVuZ0ZpZWxkcykgezxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqAgwqDCoMKg IGlmIChkZXN0LmdldEVuZ2FnZURhdGEoKS5nZXQoZW5nRmllbGQubmFtZSgpKSA9PSBudWxsKSB7 PGJyPsKgwqDCoCDCoMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqAgwqDCoMKgIG1lcmdlZEVuZy5w dXQoZW5nRmllbGQubmFtZSgpLDxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqAgwqDCoMKg IMKgwqDCoCDCoMKgwqAgwqDCoMKgIHNyYy5nZXRFbmdhZ2VEYXRhKCkuZ2V0KGVuZ0ZpZWxkLm5h bWUoKSkpOzxicj7CoMKgwqAgwqDCoMKgIMKgwqDCoCDCoMKgwqAgwqDCoMKgIH08YnI+PGJyPsKg wqDCoCDCoMKgwqAgwqDCoMKgIMKgwqDCoCB9PGJyPsKgwqDCoCDCoMKgwqAgwqDCoMKgIMKgwqDC oCBkZXN0LnNldEVuZ2FnZURhdGEobWVyZ2VkRW5nKTs8YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqAg fSBlbHNlIHs8YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqAgwqDCoMKgIGlmIChkZXN0LmdldCg8YSBo cmVmPSJodHRwOi8vZmllbGQubmFtZSIgdGFyZ2V0PSJfYmxhbmsiPmZpZWxkLm5hbWU8L2E+KCkp ID09IG51bGwpIHs8YnI+wqDCoMKgIMKgwqDCoCDCoMKgwqAgwqDCoMKgIMKgwqDCoCBkZXN0LnB1 dCg8YSBocmVmPSJodHRwOi8vZmllbGQubmFtZSIgdGFyZ2V0PSJfYmxhbmsiPmZpZWxkLm5hbWU8 L2E+KCksIHNyYy5nZXQoPGEgaHJlZj0iaHR0cDovL2ZpZWxkLm5hbWUiIHRhcmdldD0iX2JsYW5r Ij5maWVsZC5uYW1lPC9hPigpKSk7PGJyPsKgwqDCoCDCoMKgwqAgwqDCoMKgIMKgwqDCoCB9PGJy PsKgwqDCoCDCoMKgwqAgwqDCoMKgIH08YnI+wqDCoMKgIMKgwqDCoCB9PGJyPsKgwqDCoCDCoMKg wqAgcmV0dXJuIGRlc3Q7PGJyPsKgwqDCoCB9PGJyPjxicj48YnI+PGJyPjwvZGl2Pg0KPC9ibG9j a3F1b3RlPjwvZGl2Pg0KPC9kaXY+PC9kaXY+PC9ibG9ja3F1b3RlPjwvZGl2Pjxicj48L2Rpdj4N CjwvZGl2PjwvZGl2PjwvYmxvY2txdW90ZT48L2Rpdj48YnI+PGJyIGNsZWFyPSJhbGwiPjxkaXY+ PGJyPjwvZGl2PjwvZGl2PjwvZGl2PjxzcGFuIGNsYXNzPSJIT0VuWmIiPjxmb250IGNvbG9yPSIj ODg4ODg4Ij4tLSA8YnI+PGRpdj48ZGl2IGRpcj0ibHRyIj48ZGl2PkRlZXBhazwvZGl2Pjxicj48 L2Rpdj48L2Rpdj4NCjwvZm9udD48L3NwYW4+PC9kaXY+DQo8L2Jsb2NrcXVvdGU+PC9kaXY+PGJy PjxiciBjbGVhcj0iYWxsIj48ZGl2Pjxicj48L2Rpdj4tLSA8YnI+PGRpdiBjbGFzcz0iZ21haWxf c2lnbmF0dXJlIj48ZGl2IGRpcj0ibHRyIj48ZGl2PkRlZXBhazwvZGl2Pjxicj48L2Rpdj48L2Rp dj4NCjwvZGl2Pg0K --047d7bdca2f474f0d2050fd8fd5d--