ISO-10303-21;
HEADER;
/* Generated by software containing ST-Developer
 * from STEP Tools, Inc. (www.steptools.com)
 */

FILE_DESCRIPTION(
/* description */ (''),
/* implementation_level */ '2;1');

FILE_NAME(
/* name */
'D:\\OpenROV\\2.8\\Github Official\\STEP\\Electronics Tube\\Electronic
s Endcaps\\Non Pass Through\\NPT Flange Inner.stp',
/* time_stamp */ '2015-09-22T15:49:13-07:00',
/* author */ ('Evil Brian'),
/* organization */ (''),
/* preprocessor_version */ 'ST-DEVELOPER v16.1',
/* originating_system */ 'Autodesk Inventor 2016',
/* authorisation */ '');

FILE_SCHEMA (('AUTOMOTIVE_DESIGN { 1 0 10303 214 3 1 1 }'));
ENDSEC;

DATA;
#10=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION('',(#17,#18),
#857);
#11=SHAPE_REPRESENTATION_RELATIONSHIP('SRR','None',#866,#12);
#12=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#13),#856);
#13=MANIFOLD_SOLID_BREP('Solid1',#503);
#14=FACE_BOUND('',#61,.T.);
#15=FACE_BOUND('',#81,.T.);
#16=FACE_BOUND('',#86,.T.);
#17=STYLED_ITEM('',(#876),#479);
#18=STYLED_ITEM('',(#875),#13);
#19=PLANE('',#508);
#20=PLANE('',#509);
#21=PLANE('',#524);
#22=PLANE('',#527);
#23=PLANE('',#530);
#24=PLANE('',#533);
#25=PLANE('',#536);
#26=PLANE('',#539);
#27=PLANE('',#542);
#28=PLANE('',#545);
#29=PLANE('',#548);
#30=PLANE('',#551);
#31=PLANE('',#556);
#32=FACE_OUTER_BOUND('',#58,.T.);
#33=FACE_OUTER_BOUND('',#59,.T.);
#34=FACE_OUTER_BOUND('',#60,.T.);
#35=FACE_OUTER_BOUND('',#62,.T.);
#36=FACE_OUTER_BOUND('',#63,.T.);
#37=FACE_OUTER_BOUND('',#64,.T.);
#38=FACE_OUTER_BOUND('',#65,.T.);
#39=FACE_OUTER_BOUND('',#66,.T.);
#40=FACE_OUTER_BOUND('',#67,.T.);
#41=FACE_OUTER_BOUND('',#68,.T.);
#42=FACE_OUTER_BOUND('',#69,.T.);
#43=FACE_OUTER_BOUND('',#70,.T.);
#44=FACE_OUTER_BOUND('',#71,.T.);
#45=FACE_OUTER_BOUND('',#72,.T.);
#46=FACE_OUTER_BOUND('',#73,.T.);
#47=FACE_OUTER_BOUND('',#74,.T.);
#48=FACE_OUTER_BOUND('',#75,.T.);
#49=FACE_OUTER_BOUND('',#76,.T.);
#50=FACE_OUTER_BOUND('',#77,.T.);
#51=FACE_OUTER_BOUND('',#78,.T.);
#52=FACE_OUTER_BOUND('',#79,.T.);
#53=FACE_OUTER_BOUND('',#80,.T.);
#54=FACE_OUTER_BOUND('',#82,.T.);
#55=FACE_OUTER_BOUND('',#83,.T.);
#56=FACE_OUTER_BOUND('',#84,.T.);
#57=FACE_OUTER_BOUND('',#85,.T.);
#58=EDGE_LOOP('',(#322,#323,#324,#325));
#59=EDGE_LOOP('',(#326,#327,#328,#329));
#60=EDGE_LOOP('',(#330,#331,#332,#333,#334,#335,#336,#337,#338,#339,#340,
#341,#342,#343,#344,#345,#346,#347,#348,#349,#350,#351,#352));
#61=EDGE_LOOP('',(#353));
#62=EDGE_LOOP('',(#354,#355,#356,#357));
#63=EDGE_LOOP('',(#358,#359,#360,#361));
#64=EDGE_LOOP('',(#362,#363,#364,#365));
#65=EDGE_LOOP('',(#366,#367,#368,#369));
#66=EDGE_LOOP('',(#370,#371,#372,#373));
#67=EDGE_LOOP('',(#374,#375,#376,#377));
#68=EDGE_LOOP('',(#378,#379,#380,#381));
#69=EDGE_LOOP('',(#382,#383,#384,#385));
#70=EDGE_LOOP('',(#386,#387,#388,#389));
#71=EDGE_LOOP('',(#390,#391,#392,#393));
#72=EDGE_LOOP('',(#394,#395,#396,#397));
#73=EDGE_LOOP('',(#398,#399,#400,#401));
#74=EDGE_LOOP('',(#402,#403,#404,#405));
#75=EDGE_LOOP('',(#406,#407,#408,#409));
#76=EDGE_LOOP('',(#410,#411,#412,#413));
#77=EDGE_LOOP('',(#414,#415,#416,#417));
#78=EDGE_LOOP('',(#418,#419,#420,#421));
#79=EDGE_LOOP('',(#422,#423,#424,#425));
#80=EDGE_LOOP('',(#426));
#81=EDGE_LOOP('',(#427));
#82=EDGE_LOOP('',(#428,#429,#430,#431));
#83=EDGE_LOOP('',(#432,#433,#434,#435));
#84=EDGE_LOOP('',(#436,#437,#438,#439));
#85=EDGE_LOOP('',(#440,#441,#442,#443,#444,#445,#446,#447,#448,#449,#450,
#451,#452,#453,#454,#455,#456,#457,#458,#459,#460,#461,#462));
#86=EDGE_LOOP('',(#463));
#87=LINE('',#714,#132);
#88=LINE('',#717,#133);
#89=LINE('',#720,#134);
#90=LINE('',#722,#135);
#91=LINE('',#723,#136);
#92=LINE('',#726,#137);
#93=LINE('',#730,#138);
#94=LINE('',#734,#139);
#95=LINE('',#738,#140);
#96=LINE('',#742,#141);
#97=LINE('',#748,#142);
#98=LINE('',#752,#143);
#99=LINE('',#756,#144);
#100=LINE('',#760,#145);
#101=LINE('',#764,#146);
#102=LINE('',#771,#147);
#103=LINE('',#774,#148);
#104=LINE('',#775,#149);
#105=LINE('',#779,#150);
#106=LINE('',#782,#151);
#107=LINE('',#783,#152);
#108=LINE('',#788,#153);
#109=LINE('',#789,#154);
#110=LINE('',#792,#155);
#111=LINE('',#793,#156);
#112=LINE('',#798,#157);
#113=LINE('',#799,#158);
#114=LINE('',#801,#159);
#115=LINE('',#806,#160);
#116=LINE('',#807,#161);
#117=LINE('',#810,#162);
#118=LINE('',#811,#163);
#119=LINE('',#814,#164);
#120=LINE('',#817,#165);
#121=LINE('',#819,#166);
#122=LINE('',#822,#167);
#123=LINE('',#825,#168);
#124=LINE('',#827,#169);
#125=LINE('',#830,#170);
#126=LINE('',#833,#171);
#127=LINE('',#835,#172);
#128=LINE('',#838,#173);
#129=LINE('',#841,#174);
#130=LINE('',#846,#175);
#131=LINE('',#850,#176);
#132=VECTOR('',#563,1.5);
#133=VECTOR('',#566,1.5);
#134=VECTOR('',#569,90.4989623089514);
#135=VECTOR('',#570,1.5);
#136=VECTOR('',#571,90.4989623089514);
#137=VECTOR('',#574,29.);
#138=VECTOR('',#577,4.5);
#139=VECTOR('',#580,11.);
#140=VECTOR('',#583,4.50000000000001);
#141=VECTOR('',#586,10.);
#142=VECTOR('',#591,22.);
#143=VECTOR('',#594,1.49999999999999);
#144=VECTOR('',#597,11.);
#145=VECTOR('',#600,0.810810192574953);
#146=VECTOR('',#603,32.3170363388663);
#147=VECTOR('',#612,1.5);
#148=VECTOR('',#615,1.5);
#149=VECTOR('',#616,32.3170363388663);
#150=VECTOR('',#621,1.5);
#151=VECTOR('',#624,1.5);
#152=VECTOR('',#625,0.810810192574953);
#153=VECTOR('',#630,1.5);
#154=VECTOR('',#631,1.5);
#155=VECTOR('',#634,1.5);
#156=VECTOR('',#635,22.);
#157=VECTOR('',#640,1.5);
#158=VECTOR('',#641,1.5);
#159=VECTOR('',#644,29.);
#160=VECTOR('',#649,1.5);
#161=VECTOR('',#650,1.5);
#162=VECTOR('',#653,10.);
#163=VECTOR('',#654,1.5);
#164=VECTOR('',#657,1.5);
#165=VECTOR('',#660,1.5);
#166=VECTOR('',#663,4.5);
#167=VECTOR('',#666,1.5);
#168=VECTOR('',#669,1.5);
#169=VECTOR('',#672,11.);
#170=VECTOR('',#675,1.5);
#171=VECTOR('',#678,1.5);
#172=VECTOR('',#681,1.49999999999999);
#173=VECTOR('',#684,1.5);
#174=VECTOR('',#689,11.);
#175=VECTOR('',#696,4.50000000000001);
#176=VECTOR('',#701,1.5);
#177=CIRCLE('',#506,5.);
#178=CIRCLE('',#507,5.);
#179=CIRCLE('',#510,1.);
#180=CIRCLE('',#511,0.5);
#181=CIRCLE('',#512,0.5);
#182=CIRCLE('',#513,1.);
#183=CIRCLE('',#514,57.);
#184=CIRCLE('',#515,20.);
#185=CIRCLE('',#516,1.);
#186=CIRCLE('',#517,0.5);
#187=CIRCLE('',#518,0.5);
#188=CIRCLE('',#519,1.);
#189=CIRCLE('',#520,5.);
#190=CIRCLE('',#521,10.);
#191=CIRCLE('',#523,5.);
#192=CIRCLE('',#526,1.);
#193=CIRCLE('',#529,1.);
#194=CIRCLE('',#532,1.);
#195=CIRCLE('',#535,1.);
#196=CIRCLE('',#538,0.5);
#197=CIRCLE('',#541,0.5);
#198=CIRCLE('',#544,0.5);
#199=CIRCLE('',#547,0.5);
#200=CIRCLE('',#550,10.);
#201=CIRCLE('',#553,57.);
#202=CIRCLE('',#555,20.);
#203=VERTEX_POINT('',#710);
#204=VERTEX_POINT('',#711);
#205=VERTEX_POINT('',#713);
#206=VERTEX_POINT('',#715);
#207=VERTEX_POINT('',#719);
#208=VERTEX_POINT('',#721);
#209=VERTEX_POINT('',#725);
#210=VERTEX_POINT('',#727);
#211=VERTEX_POINT('',#729);
#212=VERTEX_POINT('',#731);
#213=VERTEX_POINT('',#733);
#214=VERTEX_POINT('',#735);
#215=VERTEX_POINT('',#737);
#216=VERTEX_POINT('',#739);
#217=VERTEX_POINT('',#741);
#218=VERTEX_POINT('',#743);
#219=VERTEX_POINT('',#745);
#220=VERTEX_POINT('',#747);
#221=VERTEX_POINT('',#749);
#222=VERTEX_POINT('',#751);
#223=VERTEX_POINT('',#753);
#224=VERTEX_POINT('',#755);
#225=VERTEX_POINT('',#757);
#226=VERTEX_POINT('',#759);
#227=VERTEX_POINT('',#761);
#228=VERTEX_POINT('',#763);
#229=VERTEX_POINT('',#766);
#230=VERTEX_POINT('',#769);
#231=VERTEX_POINT('',#773);
#232=VERTEX_POINT('',#777);
#233=VERTEX_POINT('',#781);
#234=VERTEX_POINT('',#785);
#235=VERTEX_POINT('',#786);
#236=VERTEX_POINT('',#791);
#237=VERTEX_POINT('',#795);
#238=VERTEX_POINT('',#796);
#239=VERTEX_POINT('',#803);
#240=VERTEX_POINT('',#804);
#241=VERTEX_POINT('',#809);
#242=VERTEX_POINT('',#813);
#243=VERTEX_POINT('',#815);
#244=VERTEX_POINT('',#821);
#245=VERTEX_POINT('',#823);
#246=VERTEX_POINT('',#829);
#247=VERTEX_POINT('',#831);
#248=VERTEX_POINT('',#837);
#249=VERTEX_POINT('',#843);
#250=VERTEX_POINT('',#848);
#251=EDGE_CURVE('',#203,#204,#177,.T.);
#252=EDGE_CURVE('',#204,#205,#87,.T.);
#253=EDGE_CURVE('',#205,#206,#178,.T.);
#254=EDGE_CURVE('',#206,#203,#88,.T.);
#255=EDGE_CURVE('',#206,#207,#89,.T.);
#256=EDGE_CURVE('',#208,#207,#90,.T.);
#257=EDGE_CURVE('',#203,#208,#91,.T.);
#258=EDGE_CURVE('',#209,#205,#92,.T.);
#259=EDGE_CURVE('',#210,#209,#179,.T.);
#260=EDGE_CURVE('',#211,#210,#93,.T.);
#261=EDGE_CURVE('',#212,#211,#180,.T.);
#262=EDGE_CURVE('',#213,#212,#94,.T.);
#263=EDGE_CURVE('',#214,#213,#181,.T.);
#264=EDGE_CURVE('',#215,#214,#95,.T.);
#265=EDGE_CURVE('',#216,#215,#182,.T.);
#266=EDGE_CURVE('',#217,#216,#96,.T.);
#267=EDGE_CURVE('',#218,#217,#183,.T.);
#268=EDGE_CURVE('',#219,#218,#184,.T.);
#269=EDGE_CURVE('',#220,#219,#97,.T.);
#270=EDGE_CURVE('',#221,#220,#185,.T.);
#271=EDGE_CURVE('',#222,#221,#98,.T.);
#272=EDGE_CURVE('',#223,#222,#186,.T.);
#273=EDGE_CURVE('',#224,#223,#99,.T.);
#274=EDGE_CURVE('',#225,#224,#187,.T.);
#275=EDGE_CURVE('',#226,#225,#100,.T.);
#276=EDGE_CURVE('',#227,#226,#188,.T.);
#277=EDGE_CURVE('',#228,#227,#101,.T.);
#278=EDGE_CURVE('',#207,#228,#189,.T.);
#279=EDGE_CURVE('',#229,#229,#190,.T.);
#280=EDGE_CURVE('',#230,#208,#191,.T.);
#281=EDGE_CURVE('',#228,#230,#102,.T.);
#282=EDGE_CURVE('',#231,#227,#103,.T.);
#283=EDGE_CURVE('',#230,#231,#104,.T.);
#284=EDGE_CURVE('',#232,#231,#192,.T.);
#285=EDGE_CURVE('',#226,#232,#105,.T.);
#286=EDGE_CURVE('',#233,#225,#106,.T.);
#287=EDGE_CURVE('',#232,#233,#107,.T.);
#288=EDGE_CURVE('',#234,#235,#193,.T.);
#289=EDGE_CURVE('',#235,#221,#108,.T.);
#290=EDGE_CURVE('',#220,#234,#109,.T.);
#291=EDGE_CURVE('',#219,#236,#110,.T.);
#292=EDGE_CURVE('',#234,#236,#111,.T.);
#293=EDGE_CURVE('',#237,#238,#194,.T.);
#294=EDGE_CURVE('',#238,#210,#112,.T.);
#295=EDGE_CURVE('',#209,#237,#113,.T.);
#296=EDGE_CURVE('',#237,#204,#114,.T.);
#297=EDGE_CURVE('',#239,#240,#195,.T.);
#298=EDGE_CURVE('',#240,#216,#115,.T.);
#299=EDGE_CURVE('',#215,#239,#116,.T.);
#300=EDGE_CURVE('',#241,#240,#117,.T.);
#301=EDGE_CURVE('',#217,#241,#118,.T.);
#302=EDGE_CURVE('',#211,#242,#119,.T.);
#303=EDGE_CURVE('',#242,#243,#196,.T.);
#304=EDGE_CURVE('',#243,#212,#120,.T.);
#305=EDGE_CURVE('',#242,#238,#121,.T.);
#306=EDGE_CURVE('',#213,#244,#122,.T.);
#307=EDGE_CURVE('',#244,#245,#197,.T.);
#308=EDGE_CURVE('',#245,#214,#123,.T.);
#309=EDGE_CURVE('',#244,#243,#124,.T.);
#310=EDGE_CURVE('',#222,#246,#125,.T.);
#311=EDGE_CURVE('',#246,#247,#198,.T.);
#312=EDGE_CURVE('',#247,#223,#126,.T.);
#313=EDGE_CURVE('',#246,#235,#127,.T.);
#314=EDGE_CURVE('',#224,#248,#128,.T.);
#315=EDGE_CURVE('',#248,#233,#199,.T.);
#316=EDGE_CURVE('',#248,#247,#129,.T.);
#317=EDGE_CURVE('',#249,#249,#200,.T.);
#318=EDGE_CURVE('',#239,#245,#130,.T.);
#319=EDGE_CURVE('',#250,#241,#201,.T.);
#320=EDGE_CURVE('',#218,#250,#131,.T.);
#321=EDGE_CURVE('',#236,#250,#202,.T.);
#322=ORIENTED_EDGE('',*,*,#251,.T.);
#323=ORIENTED_EDGE('',*,*,#252,.T.);
#324=ORIENTED_EDGE('',*,*,#253,.T.);
#325=ORIENTED_EDGE('',*,*,#254,.T.);
#326=ORIENTED_EDGE('',*,*,#254,.F.);
#327=ORIENTED_EDGE('',*,*,#255,.T.);
#328=ORIENTED_EDGE('',*,*,#256,.F.);
#329=ORIENTED_EDGE('',*,*,#257,.F.);
#330=ORIENTED_EDGE('',*,*,#253,.F.);
#331=ORIENTED_EDGE('',*,*,#258,.F.);
#332=ORIENTED_EDGE('',*,*,#259,.F.);
#333=ORIENTED_EDGE('',*,*,#260,.F.);
#334=ORIENTED_EDGE('',*,*,#261,.F.);
#335=ORIENTED_EDGE('',*,*,#262,.F.);
#336=ORIENTED_EDGE('',*,*,#263,.F.);
#337=ORIENTED_EDGE('',*,*,#264,.F.);
#338=ORIENTED_EDGE('',*,*,#265,.F.);
#339=ORIENTED_EDGE('',*,*,#266,.F.);
#340=ORIENTED_EDGE('',*,*,#267,.F.);
#341=ORIENTED_EDGE('',*,*,#268,.F.);
#342=ORIENTED_EDGE('',*,*,#269,.F.);
#343=ORIENTED_EDGE('',*,*,#270,.F.);
#344=ORIENTED_EDGE('',*,*,#271,.F.);
#345=ORIENTED_EDGE('',*,*,#272,.F.);
#346=ORIENTED_EDGE('',*,*,#273,.F.);
#347=ORIENTED_EDGE('',*,*,#274,.F.);
#348=ORIENTED_EDGE('',*,*,#275,.F.);
#349=ORIENTED_EDGE('',*,*,#276,.F.);
#350=ORIENTED_EDGE('',*,*,#277,.F.);
#351=ORIENTED_EDGE('',*,*,#278,.F.);
#352=ORIENTED_EDGE('',*,*,#255,.F.);
#353=ORIENTED_EDGE('',*,*,#279,.T.);
#354=ORIENTED_EDGE('',*,*,#280,.T.);
#355=ORIENTED_EDGE('',*,*,#256,.T.);
#356=ORIENTED_EDGE('',*,*,#278,.T.);
#357=ORIENTED_EDGE('',*,*,#281,.T.);
#358=ORIENTED_EDGE('',*,*,#281,.F.);
#359=ORIENTED_EDGE('',*,*,#277,.T.);
#360=ORIENTED_EDGE('',*,*,#282,.F.);
#361=ORIENTED_EDGE('',*,*,#283,.F.);
#362=ORIENTED_EDGE('',*,*,#284,.T.);
#363=ORIENTED_EDGE('',*,*,#282,.T.);
#364=ORIENTED_EDGE('',*,*,#276,.T.);
#365=ORIENTED_EDGE('',*,*,#285,.T.);
#366=ORIENTED_EDGE('',*,*,#285,.F.);
#367=ORIENTED_EDGE('',*,*,#275,.T.);
#368=ORIENTED_EDGE('',*,*,#286,.F.);
#369=ORIENTED_EDGE('',*,*,#287,.F.);
#370=ORIENTED_EDGE('',*,*,#288,.T.);
#371=ORIENTED_EDGE('',*,*,#289,.T.);
#372=ORIENTED_EDGE('',*,*,#270,.T.);
#373=ORIENTED_EDGE('',*,*,#290,.T.);
#374=ORIENTED_EDGE('',*,*,#290,.F.);
#375=ORIENTED_EDGE('',*,*,#269,.T.);
#376=ORIENTED_EDGE('',*,*,#291,.T.);
#377=ORIENTED_EDGE('',*,*,#292,.F.);
#378=ORIENTED_EDGE('',*,*,#293,.T.);
#379=ORIENTED_EDGE('',*,*,#294,.T.);
#380=ORIENTED_EDGE('',*,*,#259,.T.);
#381=ORIENTED_EDGE('',*,*,#295,.T.);
#382=ORIENTED_EDGE('',*,*,#252,.F.);
#383=ORIENTED_EDGE('',*,*,#296,.F.);
#384=ORIENTED_EDGE('',*,*,#295,.F.);
#385=ORIENTED_EDGE('',*,*,#258,.T.);
#386=ORIENTED_EDGE('',*,*,#297,.T.);
#387=ORIENTED_EDGE('',*,*,#298,.T.);
#388=ORIENTED_EDGE('',*,*,#265,.T.);
#389=ORIENTED_EDGE('',*,*,#299,.T.);
#390=ORIENTED_EDGE('',*,*,#298,.F.);
#391=ORIENTED_EDGE('',*,*,#300,.F.);
#392=ORIENTED_EDGE('',*,*,#301,.F.);
#393=ORIENTED_EDGE('',*,*,#266,.T.);
#394=ORIENTED_EDGE('',*,*,#261,.T.);
#395=ORIENTED_EDGE('',*,*,#302,.T.);
#396=ORIENTED_EDGE('',*,*,#303,.T.);
#397=ORIENTED_EDGE('',*,*,#304,.T.);
#398=ORIENTED_EDGE('',*,*,#294,.F.);
#399=ORIENTED_EDGE('',*,*,#305,.F.);
#400=ORIENTED_EDGE('',*,*,#302,.F.);
#401=ORIENTED_EDGE('',*,*,#260,.T.);
#402=ORIENTED_EDGE('',*,*,#263,.T.);
#403=ORIENTED_EDGE('',*,*,#306,.T.);
#404=ORIENTED_EDGE('',*,*,#307,.T.);
#405=ORIENTED_EDGE('',*,*,#308,.T.);
#406=ORIENTED_EDGE('',*,*,#304,.F.);
#407=ORIENTED_EDGE('',*,*,#309,.F.);
#408=ORIENTED_EDGE('',*,*,#306,.F.);
#409=ORIENTED_EDGE('',*,*,#262,.T.);
#410=ORIENTED_EDGE('',*,*,#272,.T.);
#411=ORIENTED_EDGE('',*,*,#310,.T.);
#412=ORIENTED_EDGE('',*,*,#311,.T.);
#413=ORIENTED_EDGE('',*,*,#312,.T.);
#414=ORIENTED_EDGE('',*,*,#289,.F.);
#415=ORIENTED_EDGE('',*,*,#313,.F.);
#416=ORIENTED_EDGE('',*,*,#310,.F.);
#417=ORIENTED_EDGE('',*,*,#271,.T.);
#418=ORIENTED_EDGE('',*,*,#274,.T.);
#419=ORIENTED_EDGE('',*,*,#314,.T.);
#420=ORIENTED_EDGE('',*,*,#315,.T.);
#421=ORIENTED_EDGE('',*,*,#286,.T.);
#422=ORIENTED_EDGE('',*,*,#312,.F.);
#423=ORIENTED_EDGE('',*,*,#316,.F.);
#424=ORIENTED_EDGE('',*,*,#314,.F.);
#425=ORIENTED_EDGE('',*,*,#273,.T.);
#426=ORIENTED_EDGE('',*,*,#317,.F.);
#427=ORIENTED_EDGE('',*,*,#279,.F.);
#428=ORIENTED_EDGE('',*,*,#299,.F.);
#429=ORIENTED_EDGE('',*,*,#264,.T.);
#430=ORIENTED_EDGE('',*,*,#308,.F.);
#431=ORIENTED_EDGE('',*,*,#318,.F.);
#432=ORIENTED_EDGE('',*,*,#267,.T.);
#433=ORIENTED_EDGE('',*,*,#301,.T.);
#434=ORIENTED_EDGE('',*,*,#319,.F.);
#435=ORIENTED_EDGE('',*,*,#320,.F.);
#436=ORIENTED_EDGE('',*,*,#268,.T.);
#437=ORIENTED_EDGE('',*,*,#320,.T.);
#438=ORIENTED_EDGE('',*,*,#321,.F.);
#439=ORIENTED_EDGE('',*,*,#291,.F.);
#440=ORIENTED_EDGE('',*,*,#251,.F.);
#441=ORIENTED_EDGE('',*,*,#257,.T.);
#442=ORIENTED_EDGE('',*,*,#280,.F.);
#443=ORIENTED_EDGE('',*,*,#283,.T.);
#444=ORIENTED_EDGE('',*,*,#284,.F.);
#445=ORIENTED_EDGE('',*,*,#287,.T.);
#446=ORIENTED_EDGE('',*,*,#315,.F.);
#447=ORIENTED_EDGE('',*,*,#316,.T.);
#448=ORIENTED_EDGE('',*,*,#311,.F.);
#449=ORIENTED_EDGE('',*,*,#313,.T.);
#450=ORIENTED_EDGE('',*,*,#288,.F.);
#451=ORIENTED_EDGE('',*,*,#292,.T.);
#452=ORIENTED_EDGE('',*,*,#321,.T.);
#453=ORIENTED_EDGE('',*,*,#319,.T.);
#454=ORIENTED_EDGE('',*,*,#300,.T.);
#455=ORIENTED_EDGE('',*,*,#297,.F.);
#456=ORIENTED_EDGE('',*,*,#318,.T.);
#457=ORIENTED_EDGE('',*,*,#307,.F.);
#458=ORIENTED_EDGE('',*,*,#309,.T.);
#459=ORIENTED_EDGE('',*,*,#303,.F.);
#460=ORIENTED_EDGE('',*,*,#305,.T.);
#461=ORIENTED_EDGE('',*,*,#293,.F.);
#462=ORIENTED_EDGE('',*,*,#296,.T.);
#463=ORIENTED_EDGE('',*,*,#317,.T.);
#464=CYLINDRICAL_SURFACE('',#505,5.);
#465=CYLINDRICAL_SURFACE('',#522,5.);
#466=CYLINDRICAL_SURFACE('',#525,1.);
#467=CYLINDRICAL_SURFACE('',#528,1.);
#468=CYLINDRICAL_SURFACE('',#531,1.);
#469=CYLINDRICAL_SURFACE('',#534,1.);
#470=CYLINDRICAL_SURFACE('',#537,0.5);
#471=CYLINDRICAL_SURFACE('',#540,0.5);
#472=CYLINDRICAL_SURFACE('',#543,0.5);
#473=CYLINDRICAL_SURFACE('',#546,0.5);
#474=CYLINDRICAL_SURFACE('',#549,10.);
#475=CYLINDRICAL_SURFACE('',#552,57.);
#476=CYLINDRICAL_SURFACE('',#554,20.);
#477=ADVANCED_FACE('',(#32),#464,.T.);
#478=ADVANCED_FACE('',(#33),#19,.T.);
#479=ADVANCED_FACE('',(#34,#14),#20,.F.);
#480=ADVANCED_FACE('',(#35),#465,.T.);
#481=ADVANCED_FACE('',(#36),#21,.T.);
#482=ADVANCED_FACE('',(#37),#466,.T.);
#483=ADVANCED_FACE('',(#38),#22,.T.);
#484=ADVANCED_FACE('',(#39),#467,.T.);
#485=ADVANCED_FACE('',(#40),#23,.T.);
#486=ADVANCED_FACE('',(#41),#468,.T.);
#487=ADVANCED_FACE('',(#42),#24,.T.);
#488=ADVANCED_FACE('',(#43),#469,.T.);
#489=ADVANCED_FACE('',(#44),#25,.T.);
#490=ADVANCED_FACE('',(#45),#470,.F.);
#491=ADVANCED_FACE('',(#46),#26,.T.);
#492=ADVANCED_FACE('',(#47),#471,.F.);
#493=ADVANCED_FACE('',(#48),#27,.T.);
#494=ADVANCED_FACE('',(#49),#472,.F.);
#495=ADVANCED_FACE('',(#50),#28,.T.);
#496=ADVANCED_FACE('',(#51),#473,.F.);
#497=ADVANCED_FACE('',(#52),#29,.T.);
#498=ADVANCED_FACE('',(#53,#15),#474,.F.);
#499=ADVANCED_FACE('',(#54),#30,.T.);
#500=ADVANCED_FACE('',(#55),#475,.T.);
#501=ADVANCED_FACE('',(#56),#476,.T.);
#502=ADVANCED_FACE('',(#57,#16),#31,.T.);
#503=CLOSED_SHELL('',(#477,#478,#479,#480,#481,#482,#483,#484,#485,#486,
#487,#488,#489,#490,#491,#492,#493,#494,#495,#496,#497,#498,#499,#500,#501,
#502));
#504=AXIS2_PLACEMENT_3D('placement',#708,#557,#558);
#505=AXIS2_PLACEMENT_3D('',#709,#559,#560);
#506=AXIS2_PLACEMENT_3D('',#712,#561,#562);
#507=AXIS2_PLACEMENT_3D('',#716,#564,#565);
#508=AXIS2_PLACEMENT_3D('',#718,#567,#568);
#509=AXIS2_PLACEMENT_3D('',#724,#572,#573);
#510=AXIS2_PLACEMENT_3D('',#728,#575,#576);
#511=AXIS2_PLACEMENT_3D('',#732,#578,#579);
#512=AXIS2_PLACEMENT_3D('',#736,#581,#582);
#513=AXIS2_PLACEMENT_3D('',#740,#584,#585);
#514=AXIS2_PLACEMENT_3D('',#744,#587,#588);
#515=AXIS2_PLACEMENT_3D('',#746,#589,#590);
#516=AXIS2_PLACEMENT_3D('',#750,#592,#593);
#517=AXIS2_PLACEMENT_3D('',#754,#595,#596);
#518=AXIS2_PLACEMENT_3D('',#758,#598,#599);
#519=AXIS2_PLACEMENT_3D('',#762,#601,#602);
#520=AXIS2_PLACEMENT_3D('',#765,#604,#605);
#521=AXIS2_PLACEMENT_3D('',#767,#606,#607);
#522=AXIS2_PLACEMENT_3D('',#768,#608,#609);
#523=AXIS2_PLACEMENT_3D('',#770,#610,#611);
#524=AXIS2_PLACEMENT_3D('',#772,#613,#614);
#525=AXIS2_PLACEMENT_3D('',#776,#617,#618);
#526=AXIS2_PLACEMENT_3D('',#778,#619,#620);
#527=AXIS2_PLACEMENT_3D('',#780,#622,#623);
#528=AXIS2_PLACEMENT_3D('',#784,#626,#627);
#529=AXIS2_PLACEMENT_3D('',#787,#628,#629);
#530=AXIS2_PLACEMENT_3D('',#790,#632,#633);
#531=AXIS2_PLACEMENT_3D('',#794,#636,#637);
#532=AXIS2_PLACEMENT_3D('',#797,#638,#639);
#533=AXIS2_PLACEMENT_3D('',#800,#642,#643);
#534=AXIS2_PLACEMENT_3D('',#802,#645,#646);
#535=AXIS2_PLACEMENT_3D('',#805,#647,#648);
#536=AXIS2_PLACEMENT_3D('',#808,#651,#652);
#537=AXIS2_PLACEMENT_3D('',#812,#655,#656);
#538=AXIS2_PLACEMENT_3D('',#816,#658,#659);
#539=AXIS2_PLACEMENT_3D('',#818,#661,#662);
#540=AXIS2_PLACEMENT_3D('',#820,#664,#665);
#541=AXIS2_PLACEMENT_3D('',#824,#667,#668);
#542=AXIS2_PLACEMENT_3D('',#826,#670,#671);
#543=AXIS2_PLACEMENT_3D('',#828,#673,#674);
#544=AXIS2_PLACEMENT_3D('',#832,#676,#677);
#545=AXIS2_PLACEMENT_3D('',#834,#679,#680);
#546=AXIS2_PLACEMENT_3D('',#836,#682,#683);
#547=AXIS2_PLACEMENT_3D('',#839,#685,#686);
#548=AXIS2_PLACEMENT_3D('',#840,#687,#688);
#549=AXIS2_PLACEMENT_3D('',#842,#690,#691);
#550=AXIS2_PLACEMENT_3D('',#844,#692,#693);
#551=AXIS2_PLACEMENT_3D('',#845,#694,#695);
#552=AXIS2_PLACEMENT_3D('',#847,#697,#698);
#553=AXIS2_PLACEMENT_3D('',#849,#699,#700);
#554=AXIS2_PLACEMENT_3D('',#851,#702,#703);
#555=AXIS2_PLACEMENT_3D('',#852,#704,#705);
#556=AXIS2_PLACEMENT_3D('',#853,#706,#707);
#557=DIRECTION('axis',(0.,0.,1.));
#558=DIRECTION('refdir',(1.,0.,0.));
#559=DIRECTION('center_axis',(0.,0.,1.));
#560=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186547,0.));
#561=DIRECTION('center_axis',(0.,0.,-1.));
#562=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186547,0.));
#563=DIRECTION('',(0.,0.,-1.));
#564=DIRECTION('center_axis',(0.,0.,1.));
#565=DIRECTION('ref_axis',(-0.707106781186547,-0.707106781186547,0.));
#566=DIRECTION('',(0.,0.,1.));
#567=DIRECTION('center_axis',(0.,-1.,0.));
#568=DIRECTION('ref_axis',(1.,0.,0.));
#569=DIRECTION('',(1.,0.,0.));
#570=DIRECTION('',(0.,0.,-1.));
#571=DIRECTION('',(1.,0.,0.));
#572=DIRECTION('center_axis',(0.,0.,1.));
#573=DIRECTION('ref_axis',(1.,0.,0.));
#574=DIRECTION('',(0.,-1.,0.));
#575=DIRECTION('center_axis',(0.,0.,1.));
#576=DIRECTION('ref_axis',(-0.707106781186544,0.707106781186551,0.));
#577=DIRECTION('',(-1.,7.40148683083437E-16,0.));
#578=DIRECTION('center_axis',(0.,0.,-1.));
#579=DIRECTION('ref_axis',(0.707106781186554,-0.707106781186541,0.));
#580=DIRECTION('',(0.,-1.,0.));
#581=DIRECTION('center_axis',(0.,0.,-1.));
#582=DIRECTION('ref_axis',(0.707106781186538,0.707106781186557,0.));
#583=DIRECTION('',(1.,3.70074341541718E-16,0.));
#584=DIRECTION('center_axis',(0.,0.,1.));
#585=DIRECTION('ref_axis',(-0.707106781186546,-0.707106781186549,0.));
#586=DIRECTION('',(0.,-1.,0.));
#587=DIRECTION('center_axis',(0.,0.,1.));
#588=DIRECTION('ref_axis',(0.945945945945946,0.324324324324325,0.));
#589=DIRECTION('center_axis',(0.,0.,1.));
#590=DIRECTION('ref_axis',(1.,4.44089209850063E-16,0.));
#591=DIRECTION('',(-3.86164530304403E-16,1.,0.));
#592=DIRECTION('center_axis',(0.,0.,1.));
#593=DIRECTION('ref_axis',(0.707106781186546,-0.707106781186549,0.));
#594=DIRECTION('',(1.,0.,0.));
#595=DIRECTION('center_axis',(0.,0.,-1.));
#596=DIRECTION('ref_axis',(-0.707106781186551,0.707106781186544,0.));
#597=DIRECTION('',(0.,1.,0.));
#598=DIRECTION('center_axis',(0.,0.,-1.));
#599=DIRECTION('ref_axis',(-0.707106781186541,-0.707106781186554,0.));
#600=DIRECTION('',(-1.,0.,0.));
#601=DIRECTION('center_axis',(0.,0.,1.));
#602=DIRECTION('ref_axis',(0.819152044288994,0.573576436351043,0.));
#603=DIRECTION('',(0.342020143325668,0.939692620785909,0.));
#604=DIRECTION('center_axis',(0.,0.,1.));
#605=DIRECTION('ref_axis',(0.573576436351046,-0.819152044288992,0.));
#606=DIRECTION('center_axis',(0.,0.,1.));
#607=DIRECTION('ref_axis',(-1.,0.,0.));
#608=DIRECTION('center_axis',(0.,0.,1.));
#609=DIRECTION('ref_axis',(0.573576436351046,-0.819152044288992,0.));
#610=DIRECTION('center_axis',(0.,0.,-1.));
#611=DIRECTION('ref_axis',(0.573576436351046,-0.819152044288992,0.));
#612=DIRECTION('',(0.,0.,1.));
#613=DIRECTION('center_axis',(0.939692620785909,-0.342020143325668,0.));
#614=DIRECTION('ref_axis',(0.342020143325668,0.939692620785909,0.));
#615=DIRECTION('',(0.,0.,-1.));
#616=DIRECTION('',(0.342020143325668,0.939692620785909,0.));
#617=DIRECTION('center_axis',(0.,0.,1.));
#618=DIRECTION('ref_axis',(0.819152044288994,0.573576436351043,0.));
#619=DIRECTION('center_axis',(0.,0.,-1.));
#620=DIRECTION('ref_axis',(0.819152044288994,0.573576436351043,0.));
#621=DIRECTION('',(0.,0.,1.));
#622=DIRECTION('center_axis',(0.,1.,0.));
#623=DIRECTION('ref_axis',(-1.,0.,0.));
#624=DIRECTION('',(0.,0.,-1.));
#625=DIRECTION('',(-1.,0.,0.));
#626=DIRECTION('center_axis',(0.,0.,1.));
#627=DIRECTION('ref_axis',(0.707106781186546,-0.707106781186549,0.));
#628=DIRECTION('center_axis',(0.,0.,-1.));
#629=DIRECTION('ref_axis',(0.707106781186546,-0.707106781186549,0.));
#630=DIRECTION('',(0.,0.,-1.));
#631=DIRECTION('',(0.,0.,1.));
#632=DIRECTION('center_axis',(1.,3.86164530304402E-16,0.));
#633=DIRECTION('ref_axis',(-7.105427357601E-16,1.,0.));
#634=DIRECTION('',(0.,0.,1.));
#635=DIRECTION('',(-3.86164530304403E-16,1.,0.));
#636=DIRECTION('center_axis',(0.,0.,1.));
#637=DIRECTION('ref_axis',(-0.707106781186544,0.707106781186551,0.));
#638=DIRECTION('center_axis',(0.,0.,-1.));
#639=DIRECTION('ref_axis',(-0.707106781186544,0.707106781186551,0.));
#640=DIRECTION('',(0.,0.,-1.));
#641=DIRECTION('',(0.,0.,1.));
#642=DIRECTION('center_axis',(-1.,0.,0.));
#643=DIRECTION('ref_axis',(0.,-1.,0.));
#644=DIRECTION('',(0.,-1.,0.));
#645=DIRECTION('center_axis',(0.,0.,1.));
#646=DIRECTION('ref_axis',(-0.707106781186546,-0.707106781186549,0.));
#647=DIRECTION('center_axis',(0.,0.,-1.));
#648=DIRECTION('ref_axis',(-0.707106781186546,-0.707106781186549,0.));
#649=DIRECTION('',(0.,0.,-1.));
#650=DIRECTION('',(0.,0.,1.));
#651=DIRECTION('center_axis',(-1.,0.,0.));
#652=DIRECTION('ref_axis',(0.,-1.,0.));
#653=DIRECTION('',(0.,-1.,0.));
#654=DIRECTION('',(0.,0.,1.));
#655=DIRECTION('center_axis',(0.,0.,1.));
#656=DIRECTION('ref_axis',(0.707106781186554,-0.707106781186541,0.));
#657=DIRECTION('',(0.,0.,1.));
#658=DIRECTION('center_axis',(0.,0.,1.));
#659=DIRECTION('ref_axis',(0.707106781186554,-0.707106781186541,0.));
#660=DIRECTION('',(0.,0.,-1.));
#661=DIRECTION('center_axis',(7.40148683083437E-16,1.,0.));
#662=DIRECTION('ref_axis',(-1.,7.105427357601E-16,0.));
#663=DIRECTION('',(-1.,7.40148683083437E-16,0.));
#664=DIRECTION('center_axis',(0.,0.,1.));
#665=DIRECTION('ref_axis',(0.707106781186538,0.707106781186557,0.));
#666=DIRECTION('',(0.,0.,1.));
#667=DIRECTION('center_axis',(0.,0.,1.));
#668=DIRECTION('ref_axis',(0.707106781186538,0.707106781186557,0.));
#669=DIRECTION('',(0.,0.,-1.));
#670=DIRECTION('center_axis',(-1.,0.,0.));
#671=DIRECTION('ref_axis',(0.,-1.,0.));
#672=DIRECTION('',(0.,-1.,0.));
#673=DIRECTION('center_axis',(0.,0.,1.));
#674=DIRECTION('ref_axis',(-0.707106781186551,0.707106781186544,0.));
#675=DIRECTION('',(0.,0.,1.));
#676=DIRECTION('center_axis',(0.,0.,1.));
#677=DIRECTION('ref_axis',(-0.707106781186551,0.707106781186544,0.));
#678=DIRECTION('',(0.,0.,-1.));
#679=DIRECTION('center_axis',(0.,-1.,0.));
#680=DIRECTION('ref_axis',(1.,0.,0.));
#681=DIRECTION('',(1.,0.,0.));
#682=DIRECTION('center_axis',(0.,0.,1.));
#683=DIRECTION('ref_axis',(-0.707106781186541,-0.707106781186554,0.));
#684=DIRECTION('',(0.,0.,1.));
#685=DIRECTION('center_axis',(0.,0.,1.));
#686=DIRECTION('ref_axis',(-0.707106781186541,-0.707106781186554,0.));
#687=DIRECTION('center_axis',(1.,0.,0.));
#688=DIRECTION('ref_axis',(0.,1.,0.));
#689=DIRECTION('',(0.,1.,0.));
#690=DIRECTION('center_axis',(0.,0.,1.));
#691=DIRECTION('ref_axis',(-1.,0.,0.));
#692=DIRECTION('center_axis',(0.,0.,-1.));
#693=DIRECTION('ref_axis',(-1.,0.,0.));
#694=DIRECTION('center_axis',(3.70074341541719E-16,-1.,0.));
#695=DIRECTION('ref_axis',(1.,3.5527136788005E-16,0.));
#696=DIRECTION('',(1.,3.70074341541718E-16,0.));
#697=DIRECTION('center_axis',(0.,0.,1.));
#698=DIRECTION('ref_axis',(0.945945945945946,0.324324324324325,0.));
#699=DIRECTION('center_axis',(0.,0.,1.));
#700=DIRECTION('ref_axis',(0.945945945945946,0.324324324324325,0.));
#701=DIRECTION('',(0.,0.,1.));
#702=DIRECTION('center_axis',(0.,0.,1.));
#703=DIRECTION('ref_axis',(1.,4.44089209850063E-16,0.));
#704=DIRECTION('center_axis',(0.,0.,1.));
#705=DIRECTION('ref_axis',(1.,4.44089209850063E-16,0.));
#706=DIRECTION('center_axis',(0.,0.,1.));
#707=DIRECTION('ref_axis',(1.,0.,0.));
#708=CARTESIAN_POINT('',(0.,0.,0.));
#709=CARTESIAN_POINT('Origin',(-52.,-53.,0.));
#710=CARTESIAN_POINT('',(-52.,-58.,1.5));
#711=CARTESIAN_POINT('',(-57.,-53.,1.5));
#712=CARTESIAN_POINT('Origin',(-52.,-53.,1.5));
#713=CARTESIAN_POINT('',(-57.,-53.,0.));
#714=CARTESIAN_POINT('',(-57.,-53.,0.));
#715=CARTESIAN_POINT('',(-52.,-58.,0.));
#716=CARTESIAN_POINT('Origin',(-52.,-53.,0.));
#717=CARTESIAN_POINT('',(-52.,-58.,0.));
#718=CARTESIAN_POINT('Origin',(-57.,-58.,0.));
#719=CARTESIAN_POINT('',(38.4989623089514,-58.,0.));
#720=CARTESIAN_POINT('',(-57.,-58.,0.));
#721=CARTESIAN_POINT('',(38.4989623089514,-58.,1.5));
#722=CARTESIAN_POINT('',(38.4989623089514,-58.,0.));
#723=CARTESIAN_POINT('',(-57.,-58.,1.5));
#724=CARTESIAN_POINT('Origin',(-3.08188022298012,-12.3817096673894,0.));
#725=CARTESIAN_POINT('',(-57.,-24.,0.));
#726=CARTESIAN_POINT('',(-57.,-23.,0.));
#727=CARTESIAN_POINT('',(-56.,-23.,0.));
#728=CARTESIAN_POINT('Origin',(-56.,-24.,0.));
#729=CARTESIAN_POINT('',(-51.5,-23.,0.));
#730=CARTESIAN_POINT('',(-51.,-23.,0.));
#731=CARTESIAN_POINT('',(-51.,-22.5,0.));
#732=CARTESIAN_POINT('Origin',(-51.5,-22.5,0.));
#733=CARTESIAN_POINT('',(-51.,-11.5,0.));
#734=CARTESIAN_POINT('',(-51.,-11.,0.));
#735=CARTESIAN_POINT('',(-51.5,-11.,0.));
#736=CARTESIAN_POINT('Origin',(-51.5,-11.5,0.));
#737=CARTESIAN_POINT('',(-56.,-11.,0.));
#738=CARTESIAN_POINT('',(-57.,-11.,0.));
#739=CARTESIAN_POINT('',(-57.,-10.,0.));
#740=CARTESIAN_POINT('Origin',(-56.,-10.,0.));
#741=CARTESIAN_POINT('',(-57.,0.,0.));
#742=CARTESIAN_POINT('',(-57.,0.,0.));
#743=CARTESIAN_POINT('',(53.9189189189189,18.4864864864865,0.));
#744=CARTESIAN_POINT('Origin',(0.,0.,0.));
#745=CARTESIAN_POINT('',(55.,12.,0.));
#746=CARTESIAN_POINT('Origin',(35.,12.,0.));
#747=CARTESIAN_POINT('',(55.,-9.99999999999996,0.));
#748=CARTESIAN_POINT('',(55.,-11.,0.));
#749=CARTESIAN_POINT('',(54.,-11.,0.));
#750=CARTESIAN_POINT('Origin',(54.,-9.99999999999996,0.));
#751=CARTESIAN_POINT('',(52.5,-11.,0.));
#752=CARTESIAN_POINT('',(52.,-11.,0.));
#753=CARTESIAN_POINT('',(52.,-11.5,0.));
#754=CARTESIAN_POINT('Origin',(52.5,-11.5,0.));
#755=CARTESIAN_POINT('',(52.,-22.5,0.));
#756=CARTESIAN_POINT('',(52.,-23.,0.));
#757=CARTESIAN_POINT('',(52.5,-23.,0.));
#758=CARTESIAN_POINT('Origin',(52.5,-22.5,0.));
#759=CARTESIAN_POINT('',(53.310810192575,-23.,0.));
#760=CARTESIAN_POINT('',(54.7389581993171,-23.,0.));
#761=CARTESIAN_POINT('',(54.2505028133609,-24.3420201433256,0.));
#762=CARTESIAN_POINT('Origin',(53.310810192575,-24.,0.));
#763=CARTESIAN_POINT('',(43.197425412881,-54.7101007166283,0.));
#764=CARTESIAN_POINT('',(42.,-58.,0.));
#765=CARTESIAN_POINT('Origin',(38.4989623089514,-53.,0.));
#766=CARTESIAN_POINT('',(10.,1.22464679914735E-15,0.));
#767=CARTESIAN_POINT('Origin',(0.,0.,0.));
#768=CARTESIAN_POINT('Origin',(38.4989623089514,-53.,0.));
#769=CARTESIAN_POINT('',(43.197425412881,-54.7101007166283,1.5));
#770=CARTESIAN_POINT('Origin',(38.4989623089514,-53.,1.5));
#771=CARTESIAN_POINT('',(43.197425412881,-54.7101007166283,0.));
#772=CARTESIAN_POINT('Origin',(42.,-58.,0.));
#773=CARTESIAN_POINT('',(54.2505028133609,-24.3420201433256,1.5));
#774=CARTESIAN_POINT('',(54.2505028133609,-24.3420201433256,0.));
#775=CARTESIAN_POINT('',(42.,-58.,1.5));
#776=CARTESIAN_POINT('Origin',(53.310810192575,-24.,0.));
#777=CARTESIAN_POINT('',(53.310810192575,-23.,1.5));
#778=CARTESIAN_POINT('Origin',(53.310810192575,-24.,1.5));
#779=CARTESIAN_POINT('',(53.310810192575,-23.,0.));
#780=CARTESIAN_POINT('Origin',(54.7389581993171,-23.,0.));
#781=CARTESIAN_POINT('',(52.5,-23.,1.5));
#782=CARTESIAN_POINT('',(52.5,-23.,0.));
#783=CARTESIAN_POINT('',(54.7389581993171,-23.,1.5));
#784=CARTESIAN_POINT('Origin',(54.,-9.99999999999996,0.));
#785=CARTESIAN_POINT('',(55.,-9.99999999999996,1.5));
#786=CARTESIAN_POINT('',(54.,-11.,1.5));
#787=CARTESIAN_POINT('Origin',(54.,-9.99999999999996,1.5));
#788=CARTESIAN_POINT('',(54.,-11.,0.));
#789=CARTESIAN_POINT('',(55.,-9.99999999999996,0.));
#790=CARTESIAN_POINT('Origin',(55.,-11.,0.));
#791=CARTESIAN_POINT('',(55.,12.,1.5));
#792=CARTESIAN_POINT('',(55.,12.,0.));
#793=CARTESIAN_POINT('',(55.,-11.,1.5));
#794=CARTESIAN_POINT('Origin',(-56.,-24.,0.));
#795=CARTESIAN_POINT('',(-57.,-24.,1.5));
#796=CARTESIAN_POINT('',(-56.,-23.,1.5));
#797=CARTESIAN_POINT('Origin',(-56.,-24.,1.5));
#798=CARTESIAN_POINT('',(-56.,-23.,0.));
#799=CARTESIAN_POINT('',(-57.,-24.,0.));
#800=CARTESIAN_POINT('Origin',(-57.,-23.,0.));
#801=CARTESIAN_POINT('',(-57.,-23.,1.5));
#802=CARTESIAN_POINT('Origin',(-56.,-10.,0.));
#803=CARTESIAN_POINT('',(-56.,-11.,1.5));
#804=CARTESIAN_POINT('',(-57.,-10.,1.5));
#805=CARTESIAN_POINT('Origin',(-56.,-10.,1.5));
#806=CARTESIAN_POINT('',(-57.,-10.,0.));
#807=CARTESIAN_POINT('',(-56.,-11.,0.));
#808=CARTESIAN_POINT('Origin',(-57.,0.,0.));
#809=CARTESIAN_POINT('',(-57.,0.,1.5));
#810=CARTESIAN_POINT('',(-57.,0.,1.5));
#811=CARTESIAN_POINT('',(-57.,0.,0.));
#812=CARTESIAN_POINT('Origin',(-51.5,-22.5,0.));
#813=CARTESIAN_POINT('',(-51.5,-23.,1.5));
#814=CARTESIAN_POINT('',(-51.5,-23.,0.));
#815=CARTESIAN_POINT('',(-51.,-22.5,1.5));
#816=CARTESIAN_POINT('Origin',(-51.5,-22.5,1.5));
#817=CARTESIAN_POINT('',(-51.,-22.5,0.));
#818=CARTESIAN_POINT('Origin',(-51.,-23.,0.));
#819=CARTESIAN_POINT('',(-51.,-23.,1.5));
#820=CARTESIAN_POINT('Origin',(-51.5,-11.5,0.));
#821=CARTESIAN_POINT('',(-51.,-11.5,1.5));
#822=CARTESIAN_POINT('',(-51.,-11.5,0.));
#823=CARTESIAN_POINT('',(-51.5,-11.,1.5));
#824=CARTESIAN_POINT('Origin',(-51.5,-11.5,1.5));
#825=CARTESIAN_POINT('',(-51.5,-11.,0.));
#826=CARTESIAN_POINT('Origin',(-51.,-11.,0.));
#827=CARTESIAN_POINT('',(-51.,-11.,1.5));
#828=CARTESIAN_POINT('Origin',(52.5,-11.5,0.));
#829=CARTESIAN_POINT('',(52.5,-11.,1.5));
#830=CARTESIAN_POINT('',(52.5,-11.,0.));
#831=CARTESIAN_POINT('',(52.,-11.5,1.5));
#832=CARTESIAN_POINT('Origin',(52.5,-11.5,1.5));
#833=CARTESIAN_POINT('',(52.,-11.5,0.));
#834=CARTESIAN_POINT('Origin',(52.,-11.,0.));
#835=CARTESIAN_POINT('',(52.,-11.,1.5));
#836=CARTESIAN_POINT('Origin',(52.5,-22.5,0.));
#837=CARTESIAN_POINT('',(52.,-22.5,1.5));
#838=CARTESIAN_POINT('',(52.,-22.5,0.));
#839=CARTESIAN_POINT('Origin',(52.5,-22.5,1.5));
#840=CARTESIAN_POINT('Origin',(52.,-23.,0.));
#841=CARTESIAN_POINT('',(52.,-23.,1.5));
#842=CARTESIAN_POINT('Origin',(0.,0.,0.));
#843=CARTESIAN_POINT('',(10.,1.22464679914735E-15,1.5));
#844=CARTESIAN_POINT('Origin',(0.,0.,1.5));
#845=CARTESIAN_POINT('Origin',(-57.,-11.,0.));
#846=CARTESIAN_POINT('',(-57.,-11.,1.5));
#847=CARTESIAN_POINT('Origin',(0.,0.,0.));
#848=CARTESIAN_POINT('',(53.9189189189189,18.4864864864865,1.5));
#849=CARTESIAN_POINT('Origin',(0.,0.,1.5));
#850=CARTESIAN_POINT('',(53.9189189189189,18.4864864864865,0.));
#851=CARTESIAN_POINT('Origin',(35.,12.,0.));
#852=CARTESIAN_POINT('Origin',(35.,12.,1.5));
#853=CARTESIAN_POINT('Origin',(-3.08188022298012,-12.3817096673894,1.5));
#854=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.01),#858,
'DISTANCE_ACCURACY_VALUE',
'Maximum model space distance between geometric entities at asserted c
onnectivities');
#855=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.E-6),#858,
'DISTANCE_ACCURACY_VALUE',
'Maximum model space distance between geometric entities at asserted c
onnectivities');
#856=(
GEOMETRIC_REPRESENTATION_CONTEXT(3)
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#854))
GLOBAL_UNIT_ASSIGNED_CONTEXT((#858,#861,#859))
REPRESENTATION_CONTEXT('','3D')
);
#857=(
GEOMETRIC_REPRESENTATION_CONTEXT(3)
GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#855))
GLOBAL_UNIT_ASSIGNED_CONTEXT((#858,#861,#859))
REPRESENTATION_CONTEXT('','3D')
);
#858=(
LENGTH_UNIT()
NAMED_UNIT(*)
SI_UNIT(.MILLI.,.METRE.)
);
#859=(
NAMED_UNIT(*)
SI_UNIT($,.STERADIAN.)
SOLID_ANGLE_UNIT()
);
#860=DIMENSIONAL_EXPONENTS(0.,0.,0.,0.,0.,0.,0.);
#861=(
CONVERSION_BASED_UNIT('degree',#863)
NAMED_UNIT(#860)
PLANE_ANGLE_UNIT()
);
#862=(
NAMED_UNIT(*)
PLANE_ANGLE_UNIT()
SI_UNIT($,.RADIAN.)
);
#863=PLANE_ANGLE_MEASURE_WITH_UNIT(PLANE_ANGLE_MEASURE(0.01745329252),#862);
#864=SHAPE_DEFINITION_REPRESENTATION(#865,#866);
#865=PRODUCT_DEFINITION_SHAPE('',$,#868);
#866=SHAPE_REPRESENTATION('',(#504),#856);
#867=PRODUCT_DEFINITION_CONTEXT('part definition',#872,'design');
#868=PRODUCT_DEFINITION('NPT Flange Inner','NPT Flange Inner',#869,#867);
#869=PRODUCT_DEFINITION_FORMATION('',$,#874);
#870=PRODUCT_RELATED_PRODUCT_CATEGORY('NPT Flange Inner',
'NPT Flange Inner',(#874));
#871=APPLICATION_PROTOCOL_DEFINITION('international standard',
'automotive_design',2009,#872);
#872=APPLICATION_CONTEXT(
'Core Data for Automotive Mechanical Design Process');
#873=PRODUCT_CONTEXT('part definition',#872,'mechanical');
#874=PRODUCT('NPT Flange Inner','NPT Flange Inner',$,(#873));
#875=PRESENTATION_STYLE_ASSIGNMENT((#877));
#876=PRESENTATION_STYLE_ASSIGNMENT((#878));
#877=SURFACE_STYLE_USAGE(.BOTH.,#879);
#878=SURFACE_STYLE_USAGE(.BOTH.,#880);
#879=SURFACE_SIDE_STYLE('',(#881));
#880=SURFACE_SIDE_STYLE('',(#882));
#881=SURFACE_STYLE_FILL_AREA(#883);
#882=SURFACE_STYLE_FILL_AREA(#884);
#883=FILL_AREA_STYLE('',(#885));
#884=FILL_AREA_STYLE('',(#886));
#885=FILL_AREA_STYLE_COLOUR('',#887);
#886=FILL_AREA_STYLE_COLOUR('',#888);
#887=COLOUR_RGB('',0.749019607843137,0.749019607843137,0.749019607843137);
#888=COLOUR_RGB('',0.945098039215686,0.949019607843137,0.972549019607843);
ENDSEC;
END-ISO-10303-21;


require File.expand_path(File.dirname(__FILE__) + "/test_helper.rb")
require 'logger'

EM.describe EM::Protocols::Redis do
  default_timeout 1

  before do
    @r = EM::Protocols::Redis.connect :db => 14
    @r.flushdb
    @r['foo'] = 'bar'
  end

  should "be able to provide a logger" do
    log = StringIO.new
    r = EM::Protocols::Redis.connect :db => 14, :logger => Logger.new(log)
    r.ping do
      log.string.should.include "ping"
      done
    end
  end

  it "should be able to PING" do
    @r.ping { |r| r.should == 'PONG'; done }
  end

  it "should be able to GET a key" do
    @r.get('foo') { |r| r.should == 'bar'; done }
  end

  it "should be able to SET a key" do
    @r['foo'] = 'nik'
    @r.get('foo') { |r| r.should == 'nik'; done }
  end

  it "should properly handle trailing newline characters" do
    @r['foo'] = "bar\n"
    @r.get('foo') { |r| r.should == "bar\n"; done }
  end

  it "should store and retrieve all possible characters at the beginning and the end of a string" do
    (0..255).each do |char_idx|
      string = "#{char_idx.chr}---#{char_idx.chr}"
      @r['foo'] = string
      @r.get('foo') { |r| r.should == string }
    end
    @r.ping { done }
  end

  it "should be able to SET a key with an expiry" do
    timeout(3)

    @r.set('foo', 'bar', 1)
    @r.get('foo') { |r| r.should == 'bar' }
    EM.add_timer(2) do
      @r.get('foo') { |r| r.should == nil }
      @r.ping { done }
    end
  end

  it "should be able to return a TTL for a key" do
    @r.set('foo', 'bar', 1)
    @r.ttl('foo') { |r| r.should == 1; done }
  end

  it "should be able to SETNX" do
    @r['foo'] = 'nik'
    @r.get('foo') { |r| r.should == 'nik' }
    @r.setnx 'foo', 'bar'
    @r.get('foo') { |r| r.should == 'nik' }

    @r.ping { done }
  end
  #
  it "should be able to GETSET" do
   @r.getset('foo', 'baz') { |r| r.should == 'bar' }
   @r.get('foo') { |r| r.should == 'baz'; done }
  end
  #
  it "should be able to INCR a key" do
    @r.del('counter')
    @r.incr('counter') { |r| r.should == 1 }
    @r.incr('counter') { |r| r.should == 2 }
    @r.incr('counter') { |r| r.should == 3 }

    @r.ping { done }
  end
  #
  it "should be able to INCRBY a key" do
    @r.del('counter')
    @r.incrby('counter', 1) { |r| r.should == 1 }
    @r.incrby('counter', 2) { |r| r.should == 3 }
    @r.incrby('counter', 3) { |r| r.should == 6 }

    @r.ping { done }
  end
  #
  it "should be able to DECR a key" do
    @r.del('counter')
    @r.incr('counter') { |r| r.should == 1 }
    @r.incr('counter') { |r| r.should == 2 }
    @r.incr('counter') { |r| r.should == 3 }
    @r.decr('counter') { |r| r.should == 2 }
    @r.decr('counter', 2) { |r| r.should == 0; done }
  end
  #
  it "should be able to RANDKEY" do
    @r.randkey { |r| r.should.not == nil; done }
  end
  #
  it "should be able to RENAME a key" do
    @r.del 'foo'
    @r.del 'bar'
    @r['foo'] = 'hi'
    @r.rename 'foo', 'bar'
    @r.get('bar') { |r| r.should == 'hi' ; done }
  end
  #
  it "should be able to RENAMENX a key" do
    @r.del 'foo'
    @r.del 'bar'
    @r['foo'] = 'hi'
    @r['bar'] = 'ohai'
    @r.renamenx 'foo', 'bar'
    @r.get('bar') { |r| r.should == 'ohai' ; done }
  end
  #
  it "should be able to get DBSIZE of the database" do
    dbsize_without_foo, dbsize_with_foo = nil
    @r.delete 'foo'
    @r.dbsize { |r| dbsize_without_foo = r }
    @r['foo'] = 0
    @r.dbsize { |r| dbsize_with_foo = r }

    @r.ping do
      dbsize_with_foo.should == dbsize_without_foo + 1
      done
    end
  end
  #
  it "should be able to EXPIRE a key" do
    timeout(3)

    @r['foo'] = 'bar'
    @r.expire 'foo', 1
    @r.get('foo') { |r| r.should == "bar" }
    EM.add_timer(2) do
      @r.get('foo') { |r| r.should == nil }
      @r.ping { done }
    end
  end
  #
  it "should be able to EXISTS" do
    @r['foo'] = 'nik'
    @r.exists('foo') { |r| r.should == true }
    @r.del 'foo'
    @r.exists('foo') { |r| r.should == false ; done }
  end
  #
  it "should be able to KEYS" do
    @r.keys("f*") { |keys| keys.each { |key| @r.del key } }
    @r['f'] = 'nik'
    @r['fo'] = 'nak'
    @r['foo'] = 'qux'
    @r.keys("f*") { |r| r.sort.should == ['f', 'fo', 'foo'].sort }

    @r.ping { done }
  end
  #
  it "should be able to return a random key (RANDOMKEY)" do
    3.times do |i|
      @r.randomkey do |r|
        @r.exists(r) do |e|
          e.should == true
          done if i == 2
        end
      end
    end
  end
  #
  it "should be able to check the TYPE of a key" do
    @r['foo'] = 'nik'
    @r.type('foo') { |r| r.should == "string" }
    @r.del 'foo'
    @r.type('foo') { |r| r.should == "none" ; done }
  end
  #
  it "should be able to push to the head of a list (LPUSH)" do
    @r.lpush "list", 'hello'
    @r.lpush "list", 42
    @r.type('list') { |r| r.should == "list" }
    @r.llen('list') { |r| r.should == 2 }
    @r.lpop('list') { |r| r.should == '42'; done }
  end
  #
  it "should be able to push to the tail of a list (RPUSH)" do
    @r.rpush "list", 'hello'
    @r.type('list') { |r| r.should == "list" }
    @r.llen('list') { |r| r.should == 1 ; done }
  end
  #
  it "should be able to pop the tail of a list (RPOP)" do
    @r.rpush "list", 'hello'
    @r.rpush"list", 'goodbye'
    @r.type('list') { |r| r.should == "list" }
    @r.llen('list') { |r| r.should == 2 }
    @r.rpop('list') { |r| r.should == 'goodbye'; done }
  end
  #
  it "should be able to pop the head of a list (LPOP)" do
    @r.rpush "list", 'hello'
    @r.rpush "list", 'goodbye'
    @r.type('list') { |r| r.should == "list" }
    @r.llen('list') { |r| r.should == 2 }
    @r.lpop('list') { |r| r.should == 'hello'; done }
  end
  #
  it "should be able to get the length of a list (LLEN)" do
    @r.rpush "list", 'hello'
    @r.rpush "list", 'goodbye'
    @r.type('list') { |r| r.should == "list" }
    @r.llen('list') { |r| r.should == 2 ; done }
  end
  #
  it "should be able to get a range of values from a list (LRANGE)" do
    @r.rpush "list", 'hello'
    @r.rpush "list", 'goodbye'
    @r.rpush "list", '1'
    @r.rpush "list", '2'
    @r.rpush "list", '3'
    @r.type('list') { |r| r.should == "list" }
    @r.llen('list') { |r| r.should == 5 }
    @r.lrange('list', 2, -1) { |r| r.should == ['1', '2', '3']; done }
  end
  #
  it "should be able to trim a list (LTRIM)" do
    @r.rpush "list", 'hello'
    @r.rpush "list", 'goodbye'
    @r.rpush "list", '1'
    @r.rpush "list", '2'
    @r.rpush "list", '3'
    @r.type('list') { |r| r.should == "list" }
    @r.llen('list') { |r| r.should == 5 }
    @r.ltrim 'list', 0, 1
    @r.llen('list') { |r| r.should == 2 }
    @r.lrange('list', 0, -1) { |r| r.should == ['hello', 'goodbye']; done }
  end
  #
  it "should be able to get a value by indexing into a list (LINDEX)" do
    @r.rpush "list", 'hello'
    @r.rpush "list", 'goodbye'
    @r.type('list') { |r| r.should == "list" }
    @r.llen('list') { |r| r.should == 2 }
    @r.lindex('list', 1) { |r| r.should == 'goodbye'; done }
  end
  #
  it "should be able to set a value by indexing into a list (LSET)" do
    @r.rpush "list", 'hello'
    @r.rpush "list", 'hello'
    @r.type('list') { |r| r.should == "list" }
    @r.llen('list') { |r| r.should == 2 }
    @r.lset('list', 1, 'goodbye') { |r| r.should == 'OK' }
    @r.lindex('list', 1) { |r| r.should == 'goodbye'; done }
  end
  #
  it "should be able to remove values from a list (LREM)" do
    @r.rpush "list", 'hello'
    @r.rpush "list", 'goodbye'
    @r.type('list') { |r| r.should == "list" }
    @r.llen('list') { |r| r.should == 2 }
    @r.lrem('list', 1, 'hello') { |r| r.should == 1 }
    @r.lrange('list', 0, -1) { |r| r.should == ['goodbye']; done }
  end

  it "should be able to pop values from a list and push them onto a temp list(RPOPLPUSH)" do
    @r.rpush "list", 'one'
    @r.rpush "list", 'two'
    @r.rpush "list", 'three'
    @r.type('list') { |r| r.should == "list" }
    @r.llen('list') { |r| r.should == 3 }
    @r.lrange('list', 0, -1) { |r| r.should == ['one', 'two', 'three'] }
    @r.lrange('tmp', 0, -1) { |r| r.should == [] }
    @r.rpoplpush('list', 'tmp') { |r| r.should == 'three' }
    @r.lrange('tmp', 0, -1) { |r| r.should == ['three'] }
    @r.rpoplpush('list', 'tmp') { |r| r.should == 'two' }
    @r.lrange('tmp', 0, -1) { |r| r.should == ['two', 'three'] }
    @r.rpoplpush('list', 'tmp') { |r| r.should == 'one' }
    @r.lrange('tmp', 0, -1) { |r| r.should == ['one', 'two', 'three']; done }
  end
  #
  it "should be able add members to a set (SADD)" do
    @r.sadd "set", 'key1'
    @r.sadd "set", 'key2'
    @r.type('set') { |r| r.should == "set" }
    @r.scard('set') { |r| r.should == 2 }
    @r.smembers('set') { |r| r.sort.should == ['key1', 'key2'].sort; done }
  end
  #
  it "should be able delete members to a set (SREM)" do
    @r.sadd "set", 'key1'
    @r.sadd "set", 'key2'
    @r.type('set') { |r| r.should == "set" }
    @r.scard('set') { |r| r.should == 2 }
    @r.smembers('set') { |r| r.sort.should == ['key1', 'key2'].sort }
    @r.srem('set', 'key1')
    @r.scard('set') { |r| r.should == 1 }
    @r.smembers('set') { |r| r.should == ['key2']; done }
  end
  #
  it "should be able to return and remove random key from set (SPOP)" do
    @r.sadd "set_pop", "key1"
    @r.sadd "set_pop", "key2"
    @r.spop("set_pop") { |r| r.should.not == nil }
    @r.scard("set_pop") { |r| r.should == 1; done }
  end
  #
  it "should be able to return random key without delete the key from a set (SRANDMEMBER)" do
    @r.sadd "set_srandmember", "key1"
    @r.sadd "set_srandmember", "key2"
    @r.srandmember("set_srandmember") { |r| r.should.not == nil }
    @r.scard("set_srandmember") { |r| r.should == 2; done }
  end
  #
  it "should be able count the members of a set (SCARD)" do
    @r.sadd "set", 'key1'
    @r.sadd "set", 'key2'
    @r.type('set') { |r| r.should == "set" }
    @r.scard('set') { |r| r.should == 2; done }
  end
  #
  it "should be able test for set membership (SISMEMBER)" do
    @r.sadd "set", 'key1'
    @r.sadd "set", 'key2'
    @r.type('set') { |r| r.should == "set" }
    @r.scard('set') { |r| r.should == 2 }
    @r.sismember('set', 'key1') { |r| r.should == true }
    @r.sismember('set', 'key2') { |r| r.should == true }
    @r.sismember('set', 'notthere') { |r| r.should == false; done }
  end
  #
  it "should be able to do set intersection (SINTER)" do
    @r.sadd "set", 'key1'
    @r.sadd "set", 'key2'
    @r.sadd "set2", 'key2'
    @r.sinter('set', 'set2') { |r| r.should == ['key2']; done }
  end
  #
  it "should be able to do set intersection and store the results in a key (SINTERSTORE)" do
    @r.sadd "set", 'key1'
    @r.sadd "set", 'key2'
    @r.sadd "set2", 'key2'
    @r.sinterstore('newone', 'set', 'set2') { |r| r.should == 1 }
    @r.smembers('newone') { |r| r.should == ['key2']; done }
  end
  #
  it "should be able to do set union (SUNION)" do
    @r.sadd "set", 'key1'
    @r.sadd "set", 'key2'
    @r.sadd "set2", 'key2'
    @r.sadd "set2", 'key3'
    @r.sunion('set', 'set2') { |r| r.sort.should == ['key1','key2','key3'].sort; done }
  end
  #
  it "should be able to do set union and store the results in a key (SUNIONSTORE)" do
    @r.sadd "set", 'key1'
    @r.sadd "set", 'key2'
    @r.sadd "set2", 'key2'
    @r.sadd "set2", 'key3'
    @r.sunionstore('newone', 'set', 'set2') { |r| r.should == 3 }
    @r.smembers('newone') { |r| r.sort.should == ['key1','key2','key3'].sort; done }
  end
  #
  it "should be able to do set difference (SDIFF)" do
     @r.sadd "set", 'a'
     @r.sadd "set", 'b'
     @r.sadd "set2", 'b'
     @r.sadd "set2", 'c'
     @r.sdiff('set', 'set2') { |r| r.should == ['a']; done }
   end
  #
  it "should be able to do set difference and store the results in a key (SDIFFSTORE)" do
     @r.sadd "set", 'a'
     @r.sadd "set", 'b'
     @r.sadd "set2", 'b'
     @r.sadd "set2", 'c'
     @r.sdiffstore('newone', 'set', 'set2')
     @r.smembers('newone') { |r| r.should == ['a']; done }
   end
  #
  it "should be able move elements from one set to another (SMOVE)" do
    @r.sadd 'set1', 'a'
    @r.sadd 'set1', 'b'
    @r.sadd 'set2', 'x'
    @r.smove('set1', 'set2', 'a') { |r| r.should == true }
    @r.sismember('set2', 'a') { |r| r.should == true }
    @r.delete('set1') { done }
  end
  #
  it "should be able to do crazy SORT queries" do
    # The 'Dogs' is capitialized on purpose
    @r['dog_1'] = 'louie'
    @r.rpush 'Dogs', 1
    @r['dog_2'] = 'lucy'
    @r.rpush 'Dogs', 2
    @r['dog_3'] = 'max'
    @r.rpush 'Dogs', 3
    @r['dog_4'] = 'taj'
    @r.rpush 'Dogs', 4
    @r.sort('Dogs', :get => 'dog_*', :limit => [0,1]) { |r| r.should == ['louie'] }
    @r.sort('Dogs', :get => 'dog_*', :limit => [0,1], :order => 'desc alpha') { |r| r.should == ['taj'] }
    @r.ping { done }
  end

  it "should be able to handle array of :get using SORT" do
    @r['dog:1:name'] = 'louie'
    @r['dog:1:breed'] = 'mutt'
    @r.rpush 'dogs', 1
    @r['dog:2:name'] = 'lucy'
    @r['dog:2:breed'] = 'poodle'
    @r.rpush 'dogs', 2
    @r['dog:3:name'] = 'max'
    @r['dog:3:breed'] = 'hound'
    @r.rpush 'dogs', 3
    @r['dog:4:name'] = 'taj'
    @r['dog:4:breed'] = 'terrier'
    @r.rpush 'dogs', 4
    @r.sort('dogs', :get => ['dog:*:name', 'dog:*:breed'], :limit => [0,1]) { |r| r.should == ['louie', 'mutt'] }
    @r.sort('dogs', :get => ['dog:*:name', 'dog:*:breed'], :limit => [0,1], :order => 'desc alpha') { |r| r.should == ['taj', 'terrier'] }
    @r.ping { done }
  end
  #
  it "should be able count the members of a zset" do
    @r.set_add "set", 'key1'
    @r.set_add "set", 'key2'
    @r.zset_add 'zset', 1, 'set'
    @r.zset_count('zset') { |r| r.should == 1 }
    @r.delete('set')
    @r.delete('zset') { done }
  end
  #
  it "should be able add members to a zset" do
    @r.set_add "set", 'key1'
    @r.set_add "set", 'key2'
    @r.zset_add 'zset', 1, 'set'
    @r.zset_range('zset', 0, 1) { |r| r.should == ['set'] }
    @r.zset_count('zset') { |r| r.should == 1 }
    @r.delete('set')
    @r.delete('zset') { done }
  end
  #
  it "should be able delete members to a zset" do
    @r.set_add "set", 'key1'
    @r.set_add "set", 'key2'
    @r.type?('set') { |r| r.should == "set" }
    @r.set_add "set2", 'key3'
    @r.set_add "set2", 'key4'
    @r.type?('set2') { |r| r.should == "set" }
    @r.zset_add 'zset', 1, 'set'
    @r.zset_count('zset') { |r| r.should == 1 }
    @r.zset_add 'zset', 2, 'set2'
    @r.zset_count('zset') { |r| r.should == 2 }
    @r.zset_delete 'zset', 'set'
    @r.zset_count('zset') { |r| r.should == 1 }
    @r.delete('set')
    @r.delete('set2')
    @r.delete('zset') { done }
  end
  #
  it "should be able to get a range of values from a zset" do
    @r.set_add "set", 'key1'
    @r.set_add "set", 'key2'
    @r.set_add "set2", 'key3'
    @r.set_add "set2", 'key4'
    @r.set_add "set3", 'key1'
    @r.type?('set') { |r| r.should == 'set' }
    @r.type?('set2') { |r| r.should == 'set' }
    @r.type?('set3') { |r| r.should == 'set' }
    @r.zset_add 'zset', 1, 'set'
    @r.zset_add 'zset', 2, 'set2'
    @r.zset_add 'zset', 3, 'set3'
    @r.zset_count('zset') { |r| r.should == 3 }
    @r.zset_range('zset', 0, 3) { |r| r.should == ['set', 'set2', 'set3'] }
    @r.delete('set')
    @r.delete('set2')
    @r.delete('set3')
    @r.delete('zset') { done }
  end
  #
  it "should be able to get a reverse range of values from a zset" do
    @r.set_add "set", 'key1'
    @r.set_add "set", 'key2'
    @r.set_add "set2", 'key3'
    @r.set_add "set2", 'key4'
    @r.set_add "set3", 'key1'
    @r.type?('set') { |r| r.should == 'set' }
    @r.type?('set2') { |r| r.should == 'set' }
    @r.type?('set3') { |r| r.should == 'set' }
    @r.zset_add 'zset', 1, 'set'
    @r.zset_add 'zset', 2, 'set2'
    @r.zset_add 'zset', 3, 'set3'
    @r.zset_count('zset') { |r| r.should == 3 }
    @r.zset_reverse_range('zset', 0, 3) { |r| r.should == ['set3', 'set2', 'set'] }
    @r.delete('set')
    @r.delete('set2')
    @r.delete('set3')
    @r.delete('zset') { done }
  end
  #
  it "should be able to get a range by score of values from a zset" do
    @r.set_add "set", 'key1'
    @r.set_add "set", 'key2'
    @r.set_add "set2", 'key3'
    @r.set_add "set2", 'key4'
    @r.set_add "set3", 'key1'
    @r.set_add "set4", 'key4'
    @r.zset_add 'zset', 1, 'set'
    @r.zset_add 'zset', 2, 'set2'
    @r.zset_add 'zset', 3, 'set3'
    @r.zset_add 'zset', 4, 'set4'
    @r.zset_count('zset') { |r| r.should == 4 }
    @r.zset_range_by_score('zset', 2, 3) { |r| r.should == ['set2', 'set3'] }
    @r.delete('set')
    @r.delete('set2')
    @r.delete('set3')
    @r.delete('set4')
    @r.delete('zset') { done }
  end
  #
  it "should be able to get a score for a specific value in a zset (ZSCORE)" do
    @r.zset_add "zset", 23, "value"
    @r.zset_score("zset", "value") { |r| r.should == "23" }

    @r.zset_score("zset", "value2") { |r| r.should == nil }
    @r.zset_score("unknown_zset", "value") { |r| r.should == nil }

    @r.delete("zset") { done }
  end
  #
  it "should be able to increment a range score of a zset (ZINCRBY)" do
    # create a new zset
    @r.zset_increment_by "hackers", 1965, "Yukihiro Matsumoto"
    @r.zset_score("hackers", "Yukihiro Matsumoto") { |r| r.should == "1965" }

    # add a new element
    @r.zset_increment_by "hackers", 1912, "Alan Turing"
    @r.zset_score("hackers", "Alan Turing") { |r| r.should == "1912" }

    # update the score
    @r.zset_increment_by "hackers", 100, "Alan Turing" # yeah, we are making Turing a bit younger
    @r.zset_score("hackers", "Alan Turing") { |r| r.should == "2012" }

    # attempt to update a key that's not a zset
    @r["i_am_not_a_zet"] = "value"
    # shouldn't raise error anymore
    @r.zset_incr_by("i_am_not_a_zet", 23, "element") { |r| r.should == nil }

    @r.delete("hackers")
    @r.delete("i_am_not_a_zet") { done }
  end
  #
  it "should provide info (INFO)" do
    @r.info do |r|
      [:last_save_time, :redis_version, :total_connections_received, :connected_clients, :total_commands_processed, :connected_slaves, :uptime_in_seconds, :used_memory, :uptime_in_days, :changes_since_last_save].each do |x|
        r.keys.include?(x).should == true
      end
      done
    end
  end
  #
  it "should be able to flush the database (FLUSHDB)" do
    @r['key1'] = 'keyone'
    @r['key2'] = 'keytwo'
    @r.keys('*') { |r| r.sort.should == ['foo', 'key1', 'key2'].sort } #foo from before
    @r.flushdb
    @r.keys('*') { |r| r.should == []; done }
  end
  #
  it "should be able to SELECT database" do
    @r.select(15)
    @r.get('foo') { |r| r.should == nil; done }
  end
  #
  it "should be able to provide the last save time (LASTSAVE)" do
    @r.lastsave do |savetime|
      Time.at(savetime).class.should == Time
      Time.at(savetime).should <= Time.now
      done
    end
  end

  it "should be able to MGET keys" do
    @r['foo'] = 1000
    @r['bar'] = 2000
    @r.mget('foo', 'bar') { |r| r.should == ['1000', '2000'] }
    @r.mget('foo', 'bar', 'baz') { |r| r.should == ['1000', '2000', nil] }
    @r.ping { done }
  end

  it "should be able to mapped MGET keys" do
    @r['foo'] = 1000
    @r['bar'] = 2000
    @r.mapped_mget('foo', 'bar') { |r| r.should == { 'foo' => '1000', 'bar' => '2000'} }
    @r.mapped_mget('foo', 'baz', 'bar') { |r| r.should == { 'foo' => '1000', 'bar' => '2000'} }
    @r.ping { done }
  end

  it "should be able to MSET values" do
    @r.mset :key1 => "value1", :key2 => "value2"
    @r.get('key1') { |r| r.should == "value1" }
    @r.get('key2') { |r| r.should == "value2"; done }
  end

  it "should be able to MSETNX values" do
    @r.msetnx :keynx1 => "valuenx1", :keynx2 => "valuenx2"
    @r.mget('keynx1', 'keynx2') { |r| r.should == ["valuenx1", "valuenx2"] }

    @r["keynx1"] = "value1"
    @r["keynx2"] = "value2"
    @r.msetnx :keynx1 => "valuenx1", :keynx2 => "valuenx2"
    @r.mget('keynx1', 'keynx2') { |r| r.should == ["value1", "value2"]; done }
  end

  it "should bgsave" do
    @r.bgsave do |r|
      ['OK', 'Background saving started'].include?(r).should == true
      done
    end
  end

  it "should be able to ECHO" do
    @r.echo("message in a bottle\n") { |r| r.should == "message in a bottle\n"; done }
  end

  # Tests are disabled due uncatchable exceptions. We should use on_error callback,
  # intead of raising exceptions in random places.
  #
  # it "should raise error when invoke MONITOR" do
  #   # lambda { @r.monitor }.should.raise
  #   done
  # end
  #
  # it "should raise error when invoke SYNC" do
  #   # lambda { @r.sync }.should.raise
  #   done
  # end

  it "should work with 10 commands" do
    @r.call_commands((1..10).map { |i|
                       ['get', "foo"]
                     }) do |rs|
      rs.length.should == 10
      rs.each { |r| r.should == "bar" }
      done
    end
  end
  it "should work with 1 command" do
    @r.call_commands([['get', "foo"]]) do |rs|
      rs.length.should == 1
      rs[0].should == "bar"
      done
    end
  end
  it "should work with zero commands" do
    @r.call_commands([]) do |rs|
      rs.should == []
      done
    end
  end
end


function vl_demo_print(varargin)
% VL_DEMO_PRINT
%   VL_DEMO_PRINT(NAME) prints the current figure to the documentation
%   directory with the specified filename, assuming that the global
%   variable VL_DEMO_PRINT is defined and non-empty when MATLAB is
%   started (our using SETENV() from MATLAB). Otherwise the function
%   flushes the displays and returns.
%
%   VL_DEMO_PRINT(NAME, R) specifies a magnification factor R, setting
%   the figure width relatively to the page width. If not specified, R
%   is assumed to be 1/2.
%
%   Remarks:: The figure paper type is set to letter, that has size 8.5 x
%     11 inches. When converted for web viewing, images are rasterized
%     at either 75 or 95 DPI, The documentation system converts images
%     to bitmap with a resolution of 75 DPI, which makes a letter size
%     page 637 or 808 pixels large, repsectively.
%
%     In MATLAB font sizes are usually expressed in points, where a
%     point is a 1/72 inch. Thus a 12pt font sampled at 75 DPI is
%     about 12.5 pixels high.

% Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
% All rights reserved.
%
% This file is part of the VLFeat library and is made available under
% the terms of the BSD license (see the COPYING file).

if isempty(getenv('VL_DEMO_PRINT'))
  drawnow ;
  return ;
end

if isa(varargin{1}, 'double')
  fig = varargin{1} ;
  varargin(1) = [] ;
else
  fig = gcf ;
end

name = varargin{1} ;

if length(varargin) < 2
  figurePaperSize = 0.5 ;
else
  figurePaperSize = varargin{2} ;
end

vl_printsize(fig, figurePaperSize) ;

figDir = fullfile(vl_root,'doc','demo') ;
if ~ exist(figDir, 'dir')
  mkdir(figDir) ;
end

if 0
  filePath = fullfile(figDir, [name '.eps']) ;
  print(fig, '-depsc2', filePath) ;
else
  filePath = fullfile(figDir, [name '.jpg']) ;
  print(fig, '-djpeg95', filePath, '-r95') ;
end
fprintf('%s: wrote file ''%s''\n', mfilename,  filePath) ;


import numpy as np
import theano
import theano.tensor as T
from utils.mymath import fourier_matrix, inverse_fourier_matrix
from lasagne.layers import Layer

# Ugly but works for now
try:
    import pygpu
    import pycuda.driver
    import skcuda
    from skcuda import fft
    cufft_available = True
except ImportError:
    cufft_available = False

if theano.config.device == 'cuda' and cufft_available:
    from cascadenet.network.theano_extensions.gpuarray.fft2 import cufft2 as fft2g
    from cascadenet.network.theano_extensions.gpuarray.fft2 import cuifft2 as ifft2g
    use_cuda = True
    print "Using GPU version of fft layers"
else:
    from cascadenet.network.theano_extensions.fft2_lasagne import fft2, ifft2
    use_cuda = False
    print "Using CPU version of fft layers"

from cascadenet.network.theano_extensions.fft_helper import fftshift, ifftshift
from cascadenet.network.theano_extensions.fft import fft, ifft

class FFTLayer(Layer):
    def __init__(self, incoming, data_shape, inv=False, **kwargs):
        '''
        Need to take input shape of the fft, since it needs to
        precompute fft matrix
        '''
        super(FFTLayer, self).__init__(incoming, **kwargs)
        self.data_shape = data_shape
        n, _, nx, ny = data_shape
        # create matrix which performs fft

        if inv:
            fourier_mat = inverse_fourier_matrix(nx, ny)
        else:
            fourier_mat = fourier_matrix(nx, ny)

        self.real_fft = np.real(fourier_mat)
        self.complex_fft = np.imag(fourier_mat)

    def transform(self, input):
        '''
        Perform fourier transform using Fourier matrix

        Parameters
        ------------------------------
        input must be of 4d tensor
        with shape [n, 2, nx, ny] where [nx, ny] == self.data_shape. n means
        number of data. 2 means channels for real and complex part of the input
        (channel 1 == real, channel 2 = complex)
        uses real values to simulate the complex operation

        Returns
        ------------------------------
        tensor of the shape [n, 2, nx, ny] which is equivalent to
        fourier transform

        '''
        in_r = input[0]
        in_c = input[1]
        real_fft = self.real_fft
        complex_fft = self.complex_fft
        out_r = T.dot(real_fft, in_r) - T.dot(complex_fft, in_c)
        out_c = T.dot(complex_fft, in_r) + T.dot(real_fft, in_c)
        return T.stack([out_r, out_c])

    def get_output_for(self, input, **kwargs):
        '''
        Computes FFT. Input layer must have dimension [n, 2, nx, ny]
        '''
        out, updates = theano.scan(self.transform, sequences=input)
        return out

class FFT2CPULayer(Layer):
    def __init__(self, incoming, data_shape, inv=False,
                 norm='ortho', **kwargs):
        '''
        Need to take input shape of the fft,
        since it needs to precompute fft matrix

        if nx != ny, we need to matrices

        '''
        super(FFT2Layer, self).__init__(incoming, **kwargs)
        self.fn = fft2 if not inv else ifft2
        self.norm = norm

    def get_output_for(self, input, **kwargs):
        '''
        Computes 2D FFT. Input layer must have dimension (n, 2, nx, ny[, nt])
        '''
        return self.fn(input, norm=self.norm)

class FFT2GPULayer(Layer):
    def __init__(self, incoming, data_shape, inv=False,
                 norm='ortho', **kwargs):
        '''
        Need to take input shape of the fft,
        since it needs to precompute fft matrix

        if nx != ny, we need to matrices

        '''
        super(FFT2Layer, self).__init__(incoming, **kwargs)
        self.fn = fft2g if not inv else ifft2g
        self.is_3d = len(data_shape) == 5
        self.norm = norm

    def get_output_for(self, input, **kwargs):
        '''
        Computes 2D FFT. Input layer must have dimension (n, 2, nx, ny[, nt])
        '''
        if self.is_3d:
            input_fft = input.dimshuffle((0, 4, 2, 3, 1))
            res = self.fn(input_fft, norm=self.norm)
            return res.dimshuffle((0, 4, 2, 3, 1))
        else:
            input_fft = input.dimshuffle((0, 2, 3, 1))
            res = self.fn(input_fft, norm=self.norm)
            return res.dimshuffle((0, 3, 1, 2))

class FT2Layer(Layer):
    def __init__(self, incoming, data_shape, inv=False, **kwargs):
        '''
        Need to take input shape of the fft,
        since it needs to precompute fft matrix

        if nx != ny, we need to matrices

        '''
        super(FFT2Layer, self).__init__(incoming, **kwargs)
        self.is_3d = len(data_shape) == 5
        self.data_shape = data_shape
        if self.is_3d:
            n, _, nx, ny, nt = data_shape
        else:
            n, _, nx, ny = data_shape
        # create matrix which performs fft

        if inv:
            fourier_mat_x = inverse_fourier_matrix(nx, nx)
            fourier_mat_y = inverse_fourier_matrix(ny, ny) if nx != ny else fourier_mat_x
        else:
            fourier_mat_x = fourier_matrix(nx, nx)
            fourier_mat_y = fourier_matrix(ny, ny) if nx != ny else fourier_mat_x

        self.real_fft_x = np.real(fourier_mat_x).astype(theano.config.floatX)
        self.complex_fft_x = np.imag(fourier_mat_x).astype(theano.config.floatX)
        self.real_fft_y = np.real(fourier_mat_y).astype(theano.config.floatX)
        self.complex_fft_y = np.imag(fourier_mat_y).astype(theano.config.floatX)

    def transform(self, input):
        '''
        Perform fourier transform using Fourier matrix

        Parameters
        ------------------------------
        input must be of 4d tensor
        with shape [n, 2, nx, ny] where [nx, ny] == self.data_shape. n means
        number of data. 2 means channels for real and complex part of the input
        (channel 1 == real, channel 2 = complex)
        uses real values to simulate the complex operation

        Returns
        ------------------------------
        tensor of the shape [n, 2, nx, ny] which is equivalent to fourier
        transform
        '''
        u = input[0]
        v = input[1]
        real_fft_x = self.real_fft_x
        complex_fft_x = self.complex_fft_x
        real_fft_y = self.real_fft_y
        complex_fft_y = self.complex_fft_y

        out_u = T.dot(u, real_fft_y.T) - T.dot(v, complex_fft_y.T)
        out_v = T.dot(u, complex_fft_y.T) + T.dot(v, real_fft_y.T)
        out_u2 = T.dot(real_fft_x, out_u) - T.dot(complex_fft_x, out_v)
        out_v2 = T.dot(complex_fft_x, out_u) + T.dot(real_fft_x, out_v)

        return T.stack([out_u2, out_v2])

    def get_output_for(self, input, **kwargs):
        '''
        Computes 2D FFT. Input layer must have dimension [n, 2, nx, ny]
        '''
        if self.is_3d:

            n, nc, nx, ny, nt = self.data_shape
            lin = T.transpose(input, axes=(0, 4, 1, 2, 3))
            lin = lin.reshape((-1, nc, nx, ny))
            lout, updates = theano.scan(self.transform, sequences=lin)
            lout = lout.reshape((-1, nt, nc, nx, ny))
            out = T.transpose(lout, axes=(0, 2, 3, 4, 1))
            return out

            # def loop_over_n(i, arr):
            #     out, updates = theano.scan(self.transform,
            #                                sequences=arr[:, :, i])[0]
            #     return out

            # nt = self.data_shape[-1]
            # out, updates = theano.scan(loop_over_n,
            #                            non_sequences=input,
            #                            sequences=xrange(nt))
            # return out

        out, updates = theano.scan(self.transform, sequences=input)
        return out

class FFTCLayer(Layer):
    def __init__(self, incoming, data_shape, norm=None,
                 inv=False, **kwargs):
        '''

        Assumes data is in the format of (n, 2, nx, ny[, nt])

        Applies FFTC along the last axis

        '''
        super(FFTCLayer, self).__init__(incoming, **kwargs)
        self.fn = fft if not inv else ifft
        self.is_3d = len(data_shape) == 5
        self.norm = norm
        # if isinstance(axes, int):
        #     axes = (axes,)

        # # Note that because we are simulating complex number, with 2 channels,
        # # we need to be careful when we invoke axes=(-1) and so we need to make
        # # sure we fix all -n to -n-1.
        # axes_list = []
        # for ax in axes:
        #     if ax < 0:
        #         axes_list.append(ax-1)
        #     else:
        #         axes_list.append(ax)
        # axes = tuple(axes_list)
        # print(axes)

        # self.axes = axes

    def get_output_for(self, input, **kwargs):
        '''
        Computes FFTC. Input layer must have dimension
        '''
        if self.is_3d:
            #  Convert to (n, nx, ny[, nt], 2) for fft
            tmp = input.dimshuffle((0, 2, 3, 4, 1))
            tmp_shifted = ifftshift(tmp, axes=(-2,))
            tmp_tfx_shifted = self.fn(tmp_shifted, norm=self.norm)
            tmp_tfx = fftshift(tmp_tfx_shifted, axes=(-2,))
            #  Convert back to (n, 2, nx, ny[, nt])
            return tmp_tfx.dimshuffle((0, 4, 1, 2, 3))

        else:
            # shape: [n, nc, nx, nt]
            tmp = input.dimshuffle((0, 2, 3, 1))
            data_xf = ifftshift(tmp, axes=(-2,))
            data_xt = self.fn(data_xf, norm=self.norm)
            data_xt = fftshift(data_xt, axes=(-2,))
            return data_xt.dimshuffle((0, 3, 1, 2))

if use_cuda:
    FFT2Layer = FFT2GPULayer
else:
    # FFT2Layer = FT2Layer
    FFT2Layer = FFT2CPULayer

# def FT2Layer(incoming, data_shape):
#     net = FFTLayer(incoming, data_shape)
#     net = TransposeLayer(net)
#     net = FFTLayer(net, data_shape)
#     net = TransposeLayer(net)
#     return net

# def IFT2Layer(incoming, data_shape):
#     net = FFTLayer(incoming, data_shape, inv=True)
#     net = TransposeLayer(net)
#     net = FFTLayer(net, data_shape, inv=True)
#     net = TransposeLayer(net)
#     return net

# def fftshift(x):
#     return x

# def ifftshift(x):
#     return x


/*
 * ntddcdrm.h
 *
 * CDROM IOCTL interface.
 *
 * This file is part of the w32api package.
 *
 * Contributors:
 *   Created by Casper S. Hornstrup <chorns@users.sourceforge.net>
 *
 * THIS SOFTWARE IS NOT COPYRIGHTED
 *
 * This source code is offered for use in the public domain. You may
 * use, modify or distribute it freely.
 *
 * This code is distributed in the hope that it will be useful but
 * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
 * DISCLAIMED. This includes but is not limited to warranties of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 */

#ifndef _NTDDCDRM_
#define _NTDDCDRM_

#include "ntddstor.h"

#ifdef __cplusplus
extern "C" {
#endif

#define IOCTL_CDROM_BASE                  FILE_DEVICE_CD_ROM

#define IOCTL_CDROM_CHECK_VERIFY \
  CTL_CODE(IOCTL_CDROM_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_FIND_NEW_DEVICES \
  CTL_CODE(IOCTL_CDROM_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_GET_CONFIGURATION \
  CTL_CODE(IOCTL_CDROM_BASE, 0x0016, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_GET_CONTROL \
  CTL_CODE(IOCTL_CDROM_BASE, 0x000D, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_GET_DRIVE_GEOMETRY \
  CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX \
  CTL_CODE(IOCTL_CDROM_BASE, 0x0014, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_GET_LAST_SESSION \
  CTL_CODE(IOCTL_CDROM_BASE, 0x000E, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_GET_VOLUME \
  CTL_CODE(IOCTL_CDROM_BASE, 0x0005, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_PAUSE_AUDIO \
  CTL_CODE(IOCTL_CDROM_BASE, 0x0003, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_PLAY_AUDIO_MSF \
  CTL_CODE(IOCTL_CDROM_BASE, 0x0006, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_RAW_READ \
  CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT,  FILE_READ_ACCESS)

#define IOCTL_CDROM_DISK_TYPE \
  CTL_CODE(IOCTL_CDROM_BASE, 0x0010, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_CDROM_READ_Q_CHANNEL \
  CTL_CODE(IOCTL_CDROM_BASE, 0x000B, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_READ_TOC \
  CTL_CODE(IOCTL_CDROM_BASE, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_READ_TOC_EX \
  CTL_CODE(IOCTL_CDROM_BASE, 0x0015, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_RESUME_AUDIO \
  CTL_CODE(IOCTL_CDROM_BASE, 0x0004, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_SEEK_AUDIO_MSF \
  CTL_CODE(IOCTL_CDROM_BASE, 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_SET_VOLUME \
  CTL_CODE(IOCTL_CDROM_BASE, 0x000A, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_SIMBAD \
  CTL_CODE(IOCTL_CDROM_BASE, 0x1003, METHOD_BUFFERED, FILE_READ_ACCESS)

#define IOCTL_CDROM_STOP_AUDIO \
  CTL_CODE(IOCTL_CDROM_BASE, 0x0002, METHOD_BUFFERED, FILE_READ_ACCESS)

#define MAXIMUM_NUMBER_TRACKS             100
#define MAXIMUM_CDROM_SIZE                804
#define MINIMUM_CDROM_READ_TOC_EX_SIZE    2

typedef struct _TRACK_DATA {
  UCHAR  Reserved;
  UCHAR  Control : 4;
  UCHAR  Adr : 4;
  UCHAR  TrackNumber;
  UCHAR  Reserved1;
  UCHAR  Address[4];
} TRACK_DATA, *PTRACK_DATA;

/* CDROM_DISK_DATA.DiskData flags */
#define CDROM_DISK_AUDIO_TRACK            0x00000001
#define CDROM_DISK_DATA_TRACK             0x00000002

typedef struct _CDROM_DISK_DATA {
  ULONG  DiskData;
} CDROM_DISK_DATA, *PCDROM_DISK_DATA;

typedef struct _CDROM_PLAY_AUDIO_MSF {
  UCHAR  StartingM;
  UCHAR  StartingS;
  UCHAR  StartingF;
  UCHAR  EndingM;
  UCHAR  EndingS;
  UCHAR  EndingF;
} CDROM_PLAY_AUDIO_MSF, *PCDROM_PLAY_AUDIO_MSF;

/* CDROM_READ_TOC_EX.Format constants */
#define CDROM_READ_TOC_EX_FORMAT_TOC      0x00
#define CDROM_READ_TOC_EX_FORMAT_SESSION  0x01
#define CDROM_READ_TOC_EX_FORMAT_FULL_TOC 0x02
#define CDROM_READ_TOC_EX_FORMAT_PMA      0x03
#define CDROM_READ_TOC_EX_FORMAT_ATIP     0x04
#define CDROM_READ_TOC_EX_FORMAT_CDTEXT   0x05

typedef struct _CDROM_READ_TOC_EX {
  UCHAR  Format : 4;
  UCHAR  Reserved1 : 3;
  UCHAR  Msf : 1;
  UCHAR  SessionTrack;
  UCHAR  Reserved2;
  UCHAR  Reserved3;
} CDROM_READ_TOC_EX, *PCDROM_READ_TOC_EX;

typedef struct _CDROM_SEEK_AUDIO_MSF {
  UCHAR  M;
  UCHAR  S;
  UCHAR  F;
} CDROM_SEEK_AUDIO_MSF, *PCDROM_SEEK_AUDIO_MSF;

/* CDROM_SUB_Q_DATA_FORMAT.Format constants */
#define IOCTL_CDROM_SUB_Q_CHANNEL         0x00
#define IOCTL_CDROM_CURRENT_POSITION      0x01
#define IOCTL_CDROM_MEDIA_CATALOG         0x02
#define IOCTL_CDROM_TRACK_ISRC            0x03

typedef struct _CDROM_SUB_Q_DATA_FORMAT {
  UCHAR Format;
  UCHAR Track;
} CDROM_SUB_Q_DATA_FORMAT, *PCDROM_SUB_Q_DATA_FORMAT;

typedef struct _CDROM_TOC {
  UCHAR  Length[2];
  UCHAR  FirstTrack;
  UCHAR  LastTrack;
  TRACK_DATA  TrackData[MAXIMUM_NUMBER_TRACKS];
} CDROM_TOC, *PCDROM_TOC;

#define CDROM_TOC_SIZE sizeof(CDROM_TOC)

typedef struct _CDROM_TOC_SESSION_DATA {
  UCHAR Length[2];
  UCHAR FirstCompleteSession;
  UCHAR LastCompleteSession;
  TRACK_DATA TrackData[1];
} CDROM_TOC_SESSION_DATA, *PCDROM_TOC_SESSION_DATA;

typedef struct _CDROM_TOC_ATIP_DATA_BLOCK {
  UCHAR  CdrwReferenceSpeed : 3;
  UCHAR  Reserved3 : 1;
  UCHAR  WritePower : 3;
  UCHAR  True1 : 1;
  UCHAR  Reserved4 : 6;
  UCHAR  UnrestrictedUse : 1;
  UCHAR  Reserved5 : 1;
  UCHAR  A3Valid : 1;
  UCHAR  A2Valid : 1;
  UCHAR  A1Valid : 1;
  UCHAR  Reserved6 : 3;
  UCHAR  IsCdrw : 1;
  UCHAR  True2 : 1;
  UCHAR  Reserved7;
  UCHAR  LeadInMsf[3];
  UCHAR  Reserved8;
  UCHAR  LeadOutMsf[3];
  UCHAR  Reserved9;
  UCHAR  A1Values[3];
  UCHAR  Reserved10;
  UCHAR  A2Values[3];
  UCHAR  Reserved11;
  UCHAR  A3Values[3];
  UCHAR  Reserved12;
} CDROM_TOC_ATIP_DATA_BLOCK, *PCDROM_TOC_ATIP_DATA_BLOCK;

typedef struct _CDROM_TOC_ATIP_DATA {
  UCHAR  Length[2];
  UCHAR  Reserved1;
  UCHAR  Reserved2;
  CDROM_TOC_ATIP_DATA_BLOCK  Descriptors[0];
} CDROM_TOC_ATIP_DATA, *PCDROM_TOC_ATIP_DATA;

/* CDROM_TOC_CD_TEXT_DATA_BLOCK.PackType constants */
#define CDROM_CD_TEXT_PACK_ALBUM_NAME 0x80
#define CDROM_CD_TEXT_PACK_PERFORMER  0x81
#define CDROM_CD_TEXT_PACK_SONGWRITER 0x82
#define CDROM_CD_TEXT_PACK_COMPOSER   0x83
#define CDROM_CD_TEXT_PACK_ARRANGER   0x84
#define CDROM_CD_TEXT_PACK_MESSAGES   0x85
#define CDROM_CD_TEXT_PACK_DISC_ID    0x86
#define CDROM_CD_TEXT_PACK_GENRE      0x87
#define CDROM_CD_TEXT_PACK_TOC_INFO   0x88
#define CDROM_CD_TEXT_PACK_TOC_INFO2  0x89
#define CDROM_CD_TEXT_PACK_UPC_EAN    0x8e
#define CDROM_CD_TEXT_PACK_SIZE_INFO  0x8f

typedef struct _CDROM_TOC_CD_TEXT_DATA_BLOCK {
  UCHAR  PackType;
  UCHAR  TrackNumber : 7;
  UCHAR  ExtensionFlag : 1;
  UCHAR  SequenceNumber;
  UCHAR  CharacterPosition : 4;
  UCHAR  BlockNumber : 3;
  UCHAR  Unicode : 1;
  _ANONYMOUS_UNION union {
    UCHAR  Text[12];
    WCHAR  WText[6];
  } DUMMYUNIONNAME;
  UCHAR  CRC[2];
} CDROM_TOC_CD_TEXT_DATA_BLOCK, *PCDROM_TOC_CD_TEXT_DATA_BLOCK;

typedef struct _CDROM_TOC_CD_TEXT_DATA {
  UCHAR  Length[2];
  UCHAR  Reserved1;
  UCHAR  Reserved2;
  CDROM_TOC_CD_TEXT_DATA_BLOCK  Descriptors[0];
} CDROM_TOC_CD_TEXT_DATA, *PCDROM_TOC_CD_TEXT_DATA;

/* CDROM_TOC_FULL_TOC_DATA_BLOCK.Adr constants */
#define ADR_NO_MODE_INFORMATION           0x0
#define ADR_ENCODES_CURRENT_POSITION      0x1
#define ADR_ENCODES_MEDIA_CATALOG         0x2
#define ADR_ENCODES_ISRC                  0x3

typedef struct _CDROM_TOC_FULL_TOC_DATA_BLOCK {
  UCHAR  SessionNumber;
  UCHAR  Control : 4;
  UCHAR  Adr : 4;
  UCHAR  Reserved1;
  UCHAR  Point;
  UCHAR  MsfExtra[3];
  UCHAR  Zero;
  UCHAR  Msf[3];
} CDROM_TOC_FULL_TOC_DATA_BLOCK, *PCDROM_TOC_FULL_TOC_DATA_BLOCK;

typedef struct _CDROM_TOC_FULL_TOC_DATA {
  UCHAR  Length[2];
  UCHAR  FirstCompleteSession;
  UCHAR  LastCompleteSession;
  CDROM_TOC_FULL_TOC_DATA_BLOCK  Descriptors[0];
} CDROM_TOC_FULL_TOC_DATA, *PCDROM_TOC_FULL_TOC_DATA;

typedef struct _CDROM_TOC_PMA_DATA {
  UCHAR  Length[2];
  UCHAR  Reserved1;
  UCHAR  Reserved2;
  CDROM_TOC_FULL_TOC_DATA_BLOCK  Descriptors[0];
} CDROM_TOC_PMA_DATA, *PCDROM_TOC_PMA_DATA;

/* SUB_Q_HEADER.AudioStatus constants */
#define AUDIO_STATUS_NOT_SUPPORTED  0x00
#define AUDIO_STATUS_IN_PROGRESS    0x11
#define AUDIO_STATUS_PAUSED         0x12
#define AUDIO_STATUS_PLAY_COMPLETE  0x13
#define AUDIO_STATUS_PLAY_ERROR     0x14
#define AUDIO_STATUS_NO_STATUS      0x15

typedef struct _SUB_Q_HEADER {
  UCHAR  Reserved;
  UCHAR  AudioStatus;
  UCHAR  DataLength[2];
} SUB_Q_HEADER, *PSUB_Q_HEADER;

typedef struct _SUB_Q_MEDIA_CATALOG_NUMBER {
  SUB_Q_HEADER  Header;
  UCHAR  FormatCode;
  UCHAR  Reserved[3];
  UCHAR  Reserved1 : 7;
  UCHAR  Mcval :1;
  UCHAR  MediaCatalog[15];
} SUB_Q_MEDIA_CATALOG_NUMBER, *PSUB_Q_MEDIA_CATALOG_NUMBER;

typedef struct _SUB_Q_TRACK_ISRC {
  SUB_Q_HEADER  Header;
  UCHAR  FormatCode;
  UCHAR  Reserved0;
  UCHAR  Track;
  UCHAR  Reserved1;
  UCHAR  Reserved2 : 7;
  UCHAR  Tcval : 1;
  UCHAR  TrackIsrc[15];
} SUB_Q_TRACK_ISRC, *PSUB_Q_TRACK_ISRC;

typedef struct _SUB_Q_CURRENT_POSITION {
  SUB_Q_HEADER  Header;
  UCHAR  FormatCode;
  UCHAR  Control : 4;
  UCHAR  ADR : 4;
  UCHAR  TrackNumber;
  UCHAR  IndexNumber;
  UCHAR  AbsoluteAddress[4];
  UCHAR  TrackRelativeAddress[4];
} SUB_Q_CURRENT_POSITION, *PSUB_Q_CURRENT_POSITION;

typedef union _SUB_Q_CHANNEL_DATA {
  SUB_Q_CURRENT_POSITION  CurrentPosition;
  SUB_Q_MEDIA_CATALOG_NUMBER  MediaCatalog;
  SUB_Q_TRACK_ISRC  TrackIsrc;
} SUB_Q_CHANNEL_DATA, *PSUB_Q_CHANNEL_DATA;

/* CDROM_AUDIO_CONTROL.LbaFormat constants */
#define AUDIO_WITH_PREEMPHASIS            0x1
#define DIGITAL_COPY_PERMITTED            0x2
#define AUDIO_DATA_TRACK                  0x4
#define TWO_FOUR_CHANNEL_AUDIO            0x8

typedef struct _CDROM_AUDIO_CONTROL {
	UCHAR  LbaFormat;
	USHORT  LogicalBlocksPerSecond;
} CDROM_AUDIO_CONTROL, *PCDROM_AUDIO_CONTROL;

typedef struct _VOLUME_CONTROL {
  UCHAR  PortVolume[4];
} VOLUME_CONTROL, *PVOLUME_CONTROL;

typedef enum _TRACK_MODE_TYPE {
	YellowMode2,
	XAForm2,
	CDDA
} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE;

typedef struct __RAW_READ_INFO {
	LARGE_INTEGER  DiskOffset;
	ULONG  SectorCount;
	TRACK_MODE_TYPE  TrackMode;
} RAW_READ_INFO, *PRAW_READ_INFO;

#ifdef __cplusplus
}
#endif

#endif /* _NTDDCDRM_ */


<?php
/*---------------------------------------------------------------------------
 * @Project: Alto CMS
 * @Project URI: http://altocms.com
 * @Description: Advanced Community Engine
 * @Copyright: Alto CMS Team
 * @License: GNU GPL v2 & MIT
 *----------------------------------------------------------------------------
 * Based on
 *   LiveStreet Engine Social Networking by Mzhelskiy Maxim
 *   Site: www.livestreet.ru
 *   E-mail: rus.engine@gmail.com
 *----------------------------------------------------------------------------
 */

/**
 * Валидатор для кастомных методов объектов
 * Валидация происходит через метод внешнего объекта
 *
 * @package engine.modules.validate
 * @since   1.0
 */
class ModuleValidate_EntityValidatorInline extends ModuleValidate_EntityValidator {
    /**
     * Метод объекта для валидации, в него передаются параметры: $sValue и $aParam
     *
     * @var string
     */
    public $method;
    /**
     * Объект у которого будет вызван метод валидации, дляя сущности - это сам объект сущности
     *
     * @var LsObject object
     */
    public $object;
    /**
     * Список параметров для передачи в метод валидации
     *
     * @var array
     */
    public $params;

    /**
     * Запуск валидации
     *
     * @param mixed $sValue    Данные для валидации
     *
     * @return bool|string
     */
    public function validate($sValue) {

        $sMethod = $this->method;
        return $this->object->$sMethod($sValue, $this->params);
    }
}

// EOF