Merge 'DBIx-Class-current' into 'replication'
Matt S Trout [Sat, 20 Jan 2007 21:16:53 +0000 (21:16 +0000)]
r26914@cain (orig r2789):  blblack | 2006-09-15 15:39:24 +0000
the beginnings of a real storage stress test
r26917@cain (orig r2792):  matthewt | 2006-09-15 21:42:04 +0000
 r26908@cain (orig r2783):  dwc | 2006-09-14 21:26:45 +0000
 Prepping 0.07002 for release
 r26915@cain (orig r2790):  castaway | 2006-09-15 21:17:43 +0000
 Fixup limit syntax finding for DB2

 r26916@cain (orig r2791):  ash | 2006-09-15 21:35:37 +0000
 Fixed incorect class name in sqlt examples

r26951@cain (orig r2793):  castaway | 2006-09-15 22:04:43 +0000
create insert_bulk using execute_array, and make populate use it in void context

r28194@cain (orig r2798):  dwc | 2006-09-23 18:26:22 +0000
 r11778@fortuna (orig r2794):  dwc | 2006-09-16 12:56:02 -0400
 Rework quote tests to not rely on SQLite, instead using debugcb to get generated SQL

r28200@cain (orig r2801):  claco | 2006-09-28 22:53:36 +0000
Added failing tests for pre/post populate->insert_bulk changes

r28201@cain (orig r2802):  claco | 2006-09-28 23:27:43 +0000
Updated 100populate.t tests to include calls in list context vs void context

r28713@cain (orig r2804):  castaway | 2006-10-03 19:01:12 +0000
Fixed to actually insert using column names, thanks claco!

r28714@cain (orig r2805):  blblack | 2006-10-03 20:25:03 +0000
make insert_bulk use the sth method in the newer style of things
r28715@cain (orig r2806):  blblack | 2006-10-03 22:57:09 +0000
add connect_info option to disable statement caching
r28718@cain (orig r2809):  blblack | 2006-10-06 01:55:56 +0000
 r12918@evoc8 (orig r2807):  dsully | 2006-10-04 13:19:37 -0500
 Make UTF-8 columns work under Perl <= 5.8.0
 r12919@evoc8 (orig r2808):  dsully | 2006-10-04 13:32:37 -0500
 Update changes

r28719@cain (orig r2810):  blblack | 2006-10-06 02:02:53 +0000
updated Changes for 0.07999_01 release
r32520@cain (orig r2818):  blblack | 2006-10-12 03:28:43 +0000
 r10869@moloko (orig r2815):  matthewt | 2006-10-06 19:49:06 -0500
 fixup to work round an aliasing bug
 r10870@moloko (orig r2816):  dwc | 2006-10-08 12:41:15 -0500
 Add tests for alias fix in [2815]

r32546@cain (orig r2844):  blblack | 2006-10-17 15:28:41 +0000
 r7941@positron (orig r2836):  castaway | 2006-10-14 12:33:13 -0500
 Minor consistency, layout and grammar updates

 r7942@positron (orig r2837):  castaway | 2006-10-14 14:24:15 -0500
 Added examples for ResultSetColumn

 r7943@positron (orig r2838):  castaway | 2006-10-14 14:41:07 -0500
 Add func example for resultsetcolumn

 r7944@positron (orig r2839):  castaway | 2006-10-14 14:43:52 -0500
 Added resultsetcolumn question to FAQ

 r7945@positron (orig r2840):  castaway | 2006-10-14 14:46:26 -0500
 Fix typo

 r7946@positron (orig r2841):  castaway | 2006-10-14 15:11:40 -0500
 Funky hashref inflating example

 r7947@positron (orig r2842):  castaway | 2006-10-14 15:21:26 -0500
 Add find_or_new / in_storage example

 r9870@positron (orig r2843):  dwc | 2006-10-17 02:40:56 -0500
 Add (currently failing) tests for single relationship accessors with objects and for PK mutation

r33014@cain (orig r2851):  matthewt | 2006-10-25 05:20:32 +0000
 r32855@cain (orig r2845):  willert | 2006-10-18 20:33:43 +0000
 Add myself to the contributors list
 r32856@cain (orig r2846):  willert | 2006-10-18 20:37:23 +0000
 Changed DBIC::Schema->load_classes to be taint-safe even when Module::Find is used to fetch the classes to import.
 Added a testfile for this behavior and any further taint related issues.

 r32857@cain (orig r2847):  willert | 2006-10-18 20:40:15 +0000
 Cosmetics: Changed DBIx::Class to fit into the global 2-space-indent convention
 r32858@cain (orig r2848):  konobi | 2006-10-18 22:07:55 +0000
 Hide documentation for deprecated modules from PAUSE.
 r32859@cain (orig r2849):  matthewt | 2006-10-21 03:16:47 +0000
 I hate you all.
 r33013@cain (orig r2850):  matthewt | 2006-10-25 05:19:21 +0000
 because this actually works

r33271@cain (orig r2857):  matthewt | 2006-11-03 04:26:25 +0000
 r33016@cain (orig r2852):  matthewt | 2006-10-25 07:11:15 +0000
 fix it properly, fix Changes
 r33253@cain (orig r2853):  castaway | 2006-10-30 14:21:53 +0000
 Fixed typos in HashRefInflator example

 r33254@cain (orig r2854):  ash | 2006-10-30 14:49:27 +0000
 Fixed type in hasrref iter - thanks abraxxa

 r33255@cain (orig r2855):  ash | 2006-10-31 11:24:43 +0000
 Deploy fix that will hopefully sort out problems with HTML::Widget::DBIxClass

 r33256@cain (orig r2856):  ash | 2006-11-01 02:11:22 +0000
 reverted previous deploy change(r8255) - sorry matt, i wont break it again

r33594@cain (orig r2873):  ash | 2006-11-12 16:52:21 +0000
Moved from M::B to M::I
Added myself to CONTRIBUTORS

r33595@cain (orig r2874):  ash | 2006-11-12 16:59:23 +0000
use inc::Module::Install 0.64 (no version previouly)

r33608@cain (orig r2876):  matthewt | 2006-11-13 08:35:04 +0000
 r33574@cain (orig r2868):  marcus | 2006-11-09 12:27:52 +0000
 remove obsolete example.
 r33576@cain (orig r2870):  matthewt | 2006-11-10 13:38:40 +0000
 inflate_result can return an array now. somebody write me tests please
 r33577@cain (orig r2871):  castaway | 2006-11-10 18:17:36 +0000
 Documentation updates:
   add_columns column_info keys
   resultset_class example

 r33593@cain (orig r2872):  castaway | 2006-11-10 22:22:22 +0000
 Minor documentation update

 r33596@cain (orig r2875):  matthewt | 2006-11-13 03:30:19 +0000
 make multi-return actually work

r33840@cain (orig r2899):  bricas | 2006-11-16 15:47:06 +0000
 r14845@Brian (orig r2878):  ash | 2006-11-13 15:48:13 -0400
 Seperated out quote tests so that matt can use them for S::A at some point (old
 test t/19quotes.t) Also includes two failing tests (quoted order by and
 { select => ['me.*']} attrs).

 r14870@Brian (orig r2882):  blblack | 2006-11-15 10:13:44 -0400
 fix for rt.cpan.org #22740 (use $^X instead of hardcoded "perl")
 r14875@Brian (orig r2887):  castaway | 2006-11-15 10:26:47 -0400
 Fix foreign/self example

 r14885@Brian (orig r2897):  blblack | 2006-11-15 16:16:14 -0400

 Don't blow up if columns_info_for returns useless results

 r14893@Brian (orig r2898):  bricas | 2006-11-16 11:42:33 -0400
 moving it to -current branch

r33841@cain (orig r2900):  bricas | 2006-11-16 15:48:02 +0000
moved from trunk
r33850@cain (orig r2909):  ash | 2006-11-18 01:13:36 +0000
Removed Class::Data::Accessor and DBIx::Class::AccessorGrouped and
replaced with Class::Accessor::Grouped.

component_class type accessors now just inherited and so no longer
automatcally require classes when set (noted in changes)

Added auto_install to Makefile.PL

r33996@cain (orig r2911):  matthewt | 2006-11-20 19:11:15 +0000
 r33842@cain (orig r2901):  bricas | 2006-11-16 15:54:41 +0000
 bumped ver. added some stuff to Changes i know were missing.
 r33845@cain (orig r2904):  blblack | 2006-11-16 16:43:42 +0000
 added changes entry for rt#22740
 r33846@cain (orig r2905):  castaway | 2006-11-16 16:45:29 +0000
 Added patch from Ted Carnahan to rel docs

r34019@cain (orig r2917):  matthewt | 2006-11-22 05:22:32 +0000
moved tests to compose_namespace instead of compose_connection, marked compose_connection as deprecated, undocumented DB.pm
r34020@cain (orig r2918):  matthewt | 2006-11-22 05:30:06 +0000
class reg test
r34029@cain (orig r2921):  claco | 2006-11-22 17:38:43 +0000
Updated version requirement for Class::Accessor::Grouped to 0.03
r34035@cain (orig r2925):  ningu | 2006-11-22 22:10:30 +0000
 r18925@haferschleim (orig r2919):  ningu | 2006-11-21 22:44:26 -0800
 - slight optimization to ident_condition in PK.pm
 - get ident_cond in update() before applying arguments, so a column's pk can be updated
 r18926@haferschleim (orig r2920):  ningu | 2006-11-21 22:54:10 -0800
 revert update() change
 r18953@haferschleim (orig r2922):  ningu | 2006-11-22 12:12:43 -0800
 re-commit minimal pk-mutation in update(), with test
 r18956@haferschleim (orig r2924):  ningu | 2006-11-22 14:09:07 -0800
 add shallow copy of $attrs in ResultSet->new

r34039@cain (orig r2929):  ningu | 2006-11-23 00:02:14 +0000
trivial test cleanup
r34041@cain (orig r2931):  matthewt | 2006-11-23 20:05:52 +0000
 r28722@cain (orig r2813):  castaway | 2006-10-06 19:45:42 +0000
 Versioning! With tests! Woo!

r34042@cain (orig r2932):  matthewt | 2006-11-23 20:05:58 +0000
 r28723@cain (orig r2814):  castaway | 2006-10-06 19:52:38 +0000
 s/Path::Class/File::Spec/

r34043@cain (orig r2933):  matthewt | 2006-11-23 20:06:02 +0000

r34044@cain (orig r2934):  matthewt | 2006-11-23 20:06:06 +0000

r34045@cain (orig r2935):  matthewt | 2006-11-23 20:06:09 +0000
 r34031@cain (orig r2923):  castaway | 2006-11-22 20:44:36 +0000
 Fix tests, remove some random rints

r34046@cain (orig r2936):  matthewt | 2006-11-23 20:06:14 +0000

r34142@cain (orig r2940):  ningu | 2006-11-23 21:39:33 +0000
- nuke old _resultset caching stuff
- teeny cleanup to ResultSetColumn code
r34143@cain (orig r2941):  castaway | 2006-11-23 23:33:42 +0000
Add backup_directory, make tests cleanup

r34148@cain (orig r2946):  matthewt | 2006-11-26 16:21:17 +0000
 r34145@cain (orig r2943):  nigel | 2006-11-26 13:24:39 +0000
 Added a test to check that the result from a 2 level has_many prefetch
 is the same as that got by expanding the relationships one thing at a
 time.

r34189@cain (orig r2948):  ash | 2006-11-27 19:34:28 +0000
- $schema->deploy now accepts a list of source (name)s to deploy
- Also fixed creating of FK constraints to use is_foreign_key attr explicitly
  even if no back rel
r34191@cain (orig r2950):  ash | 2006-11-27 21:39:23 +0000
Typo fix in error message
r34192@cain (orig r2951):  ash | 2006-11-27 21:52:10 +0000
Fixed ningu's typo from rev 2929, and added test to catch error better
r34194@cain (orig r2953):  castaway | 2006-11-28 12:44:42 +0000
Add blessed checking to deflate

r34625@cain (orig r2955):  ningu | 2006-12-02 06:06:15 +0000
inline relationship and inflate code for new, update, get_column, set_column, etc.
r34626@cain (orig r2956):  ningu | 2006-12-02 06:16:31 +0000
tiny cosmetic fixes
r35150@cain (orig r2959):  blblack | 2006-12-07 02:38:17 +0000
 r12195@localhost (orig r2957):  ash | 2006-12-06 15:48:49 -0600
 More descriptive error messages courtesy of Marc Espie
 r12196@localhost (orig r2958):  ash | 2006-12-06 17:05:30 -0600
 Join condition patch from Bernhard Graf

r35222@cain (orig r2967):  blblack | 2006-12-11 14:24:48 +0000
 r12251@localhost (orig r2961):  ningu | 2006-12-09 14:39:02 -0600
 - die in Storage::DBI::Pg when it can't find the autoinc sequence
 r12253@localhost (orig r2963):  ningu | 2006-12-10 10:25:22 -0600
 add test for has_many prefetch with adjacent rows with no rel objects
 r12254@localhost (orig r2964):  ningu | 2006-12-10 10:26:59 -0600
 whoops
 r12255@localhost (orig r2965):  blblack | 2006-12-10 19:00:22 -0600
 allow pk mutation via column accessor + update
 r12316@localhost (orig r2966):  blblack | 2006-12-11 08:24:23 -0600
 better fix for pk mutation based on mst irc conversation

r35458@cain (orig r2974):  matthewt | 2006-12-28 00:34:58 +0000
 r35424@cain (orig r2969):  dwc | 2006-12-19 06:22:09 +0000
 fix find_related-based queries to correctly grep the unique key
 r35455@cain (orig r2971):  ash | 2006-12-21 21:04:33 +0000
 Made many_to_many throw an exception if its not provided with a $f_rel

r35466@cain (orig r2976):  matthewt | 2006-12-28 19:21:52 +0000
 r34017@cain (orig r2915):  ash | 2006-11-21 09:46:41 +0000
 Changed row and rs objects to not have direct handle to a source, instead a
 (schema,source_name) tuple of type ResultSourceHandle.

r35467@cain (orig r2977):  matthewt | 2006-12-28 19:21:57 +0000
 r34018@cain (orig r2916):  ash | 2006-11-21 20:58:19 +0000
 Missed a reference to {result_source}

r35468@cain (orig r2978):  matthewt | 2006-12-28 19:22:01 +0000
 r34036@cain (orig r2926):  ningu | 2006-11-22 22:23:59 +0000
 change monkier => moniker

r35469@cain (orig r2979):  matthewt | 2006-12-28 19:22:05 +0000
 r34037@cain (orig r2927):  ningu | 2006-11-22 22:34:23 +0000
 fix typo

r35470@cain (orig r2980):  matthewt | 2006-12-28 19:22:08 +0000
 r34038@cain (orig r2928):  ningu | 2006-11-22 22:44:22 +0000
 fix typo fix

r35471@cain (orig r2981):  matthewt | 2006-12-28 19:22:11 +0000

r35472@cain (orig r2982):  matthewt | 2006-12-28 19:23:55 +0000
 r34147@cain (orig r2945):  ash | 2006-11-26 16:18:42 +0000
 Made source_name read-only on source instances, r/w on classes

r35473@cain (orig r2983):  matthewt | 2006-12-28 19:24:00 +0000

r35474@cain (orig r2984):  matthewt | 2006-12-28 19:24:34 +0000
 r35456@cain (orig r2972):  ash | 2006-12-27 22:48:49 +0000
 Removed CDBI subclassing bugs. constrain_columns to work out now

r35475@cain (orig r2985):  matthewt | 2006-12-28 19:24:38 +0000
 r35457@cain (orig r2973):  ash | 2006-12-28 00:15:24 +0000
 Fixed problem with cdbi-t/13constrain.t

r35476@cain (orig r2986):  matthewt | 2006-12-28 19:24:41 +0000

r35676@cain (orig r2993):  matthewt | 2007-01-01 20:05:37 +0000
 r35675@cain (orig r2992):  castaway | 2007-01-01 19:59:21 +0000
 Inflate/Deflate on all refs but scalars, with tests and all!

r35678@cain (orig r2995):  matthewt | 2007-01-01 23:07:38 +0000
 r35677@cain (orig r2994):  castaway | 2007-01-01 22:39:12 +0000
 Fixup update/new ignoring with scalarrefs
 Add tests for same, plus discard_changes test

r35686@cain (orig r3003):  matthewt | 2007-01-02 20:36:29 +0000
multi-col group support for Ordered, from Neil de Carteret
r35815@cain (orig r3006):  ash | 2007-01-05 14:59:01 +0000
Added abraxa's HashRefInflator (no docs as yet)
r35825@cain (orig r3016):  ash | 2007-01-13 01:52:30 +0000
Added some simple docs to HashRefInflator and updated cookbook to match
r35845@cain (orig r3017):  ash | 2007-01-14 15:24:03 +0000
Make not of introduction of ResultSourceHandle
r35853@cain (orig r3020):  matthewt | 2007-01-17 01:24:13 +0000
 r33849@cain (orig r2908):  jnapiorkowski | 2006-11-18 00:48:30 +0000

r35854@cain (orig r3021):  matthewt | 2007-01-17 01:25:24 +0000
 r33995@cain (orig r2910):  jnapiorkowski | 2006-11-20 05:01:56 +0000
 changed storage->insert|update|delete to accept the source object directly and to get the attributes for the columns in storage::DBI and not elsewhere.  Cleaned up the tests.  Still getting attribute info from the table schemas

r35855@cain (orig r3022):  matthewt | 2007-01-17 01:25:37 +0000
 r34195@cain (orig r2954):  jnapiorkowski | 2006-12-01 04:35:26 +0000
 moved bind attributes to DBI.pm/DBI/Pg.pm

r35856@cain (orig r3023):  matthewt | 2007-01-17 01:25:42 +0000
 r35326@cain (orig r2968):  jnapiorkowski | 2006-12-13 01:04:55 +0000
 updated bulk insert to handle bind_param_array, created some basic tests

r35857@cain (orig r3024):  matthewt | 2007-01-17 01:25:47 +0000

r35858@cain (orig r3025):  matthewt | 2007-01-17 01:26:29 +0000
 r35669@cain (orig r2989):  matthewt | 2006-12-30 20:18:22 +0000
 fixup external bind params

r35859@cain (orig r3026):  matthewt | 2007-01-17 01:26:43 +0000
 r35821@cain (orig r3012):  jnapiorkowski | 2007-01-10 21:08:36 +0000
 Merge from current and fixed issue when a column has multiple bind values.

r35860@cain (orig r3027):  matthewt | 2007-01-17 01:26:47 +0000
 r35822@cain (orig r3013):  jnapiorkowski | 2007-01-10 21:09:07 +0000
 documentation updates

r35861@cain (orig r3028):  matthewt | 2007-01-17 01:26:49 +0000
 r35823@cain (orig r3014):  jnapiorkowski | 2007-01-10 21:43:19 +0000
 some refactoring to reduce cut and paste work

r35862@cain (orig r3029):  matthewt | 2007-01-17 01:26:52 +0000
 r35824@cain (orig r3015):  jnapiorkowski | 2007-01-10 22:11:21 +0000
 additional refactoring to better handle source objects

r35863@cain (orig r3030):  matthewt | 2007-01-17 01:35:23 +0000
arguably slightly less broken
r35867@cain (orig r3034):  matthewt | 2007-01-17 01:42:25 +0000
Changes note for param_bind since the authors forgot
r35873@cain (orig r3036):  victori | 2007-01-19 03:04:48 +0000
committing first version of filecolumn
r35874@cain (orig r3037):  victori | 2007-01-20 19:46:33 +0000
minor update to FileColumn. I added a callback method which can be used by FileColumn::Thumbnail

96 files changed:
Build.PL
Changes
MANIFEST.SKIP
Makefile.PL
lib/DBIx/Class.pm
lib/DBIx/Class/AccessorGroup.pm [deleted file]
lib/DBIx/Class/Core.pm
lib/DBIx/Class/DB.pm
lib/DBIx/Class/FileColumn.pm [new file with mode: 0644]
lib/DBIx/Class/InflateColumn.pm
lib/DBIx/Class/InflateColumn/DateTime.pm
lib/DBIx/Class/Manual/Cookbook.pod
lib/DBIx/Class/Manual/FAQ.pod
lib/DBIx/Class/Ordered.pm
lib/DBIx/Class/PK.pm
lib/DBIx/Class/PK/Auto/DB2.pm
lib/DBIx/Class/PK/Auto/MSSQL.pm
lib/DBIx/Class/PK/Auto/MySQL.pm
lib/DBIx/Class/PK/Auto/Oracle.pm
lib/DBIx/Class/PK/Auto/Pg.pm
lib/DBIx/Class/PK/Auto/SQLite.pm
lib/DBIx/Class/Relationship.pm
lib/DBIx/Class/Relationship/HasMany.pm
lib/DBIx/Class/Relationship/HasOne.pm
lib/DBIx/Class/Relationship/ManyToMany.pm
lib/DBIx/Class/ResultClass/HashRefInflator.pm [new file with mode: 0644]
lib/DBIx/Class/ResultSet.pm
lib/DBIx/Class/ResultSetColumn.pm
lib/DBIx/Class/ResultSetManager.pm
lib/DBIx/Class/ResultSource.pm
lib/DBIx/Class/ResultSourceHandle.pm [new file with mode: 0644]
lib/DBIx/Class/ResultSourceProxy.pm
lib/DBIx/Class/ResultSourceProxy/Table.pm
lib/DBIx/Class/Row.pm
lib/DBIx/Class/Schema.pm
lib/DBIx/Class/Schema/Versioned.pm [new file with mode: 0644]
lib/DBIx/Class/Serialize/Storable.pm [deleted file]
lib/DBIx/Class/Storage.pm
lib/DBIx/Class/Storage/DBI.pm
lib/DBIx/Class/Storage/DBI/NoBindVars.pm
lib/DBIx/Class/Storage/DBI/Pg.pm
lib/DBIx/Class/Storage/DBI/SQLite.pm
lib/DBIx/Class/Storage/Statistics.pm
lib/DBIx/Class/UTF8Columns.pm
lib/SQL/Translator/Parser/DBIx/Class.pm
t/100populate.t [new file with mode: 0644]
t/19quotes.t
t/19quotes_newstyle.t
t/31stats.t
t/34exception_action.t
t/35disable_sth_caching.t [new file with mode: 0644]
t/40resultsetmanager.t
t/54taint.t [new file with mode: 0644]
t/55storage_stress.t [new file with mode: 0644]
t/60core.t
t/63register_class.t [new file with mode: 0644]
t/65multipk.t
t/68inflate.t
t/68inflate_resultclass_hashrefinflator.t [new file with mode: 0644]
t/68inflate_serialize.t
t/69update.t
t/71mysql.t
t/72pg.t
t/73oracle.t
t/745db2.t
t/746db2_400.t
t/74mssql.t
t/76joins.t
t/79aliasing.t
t/80unique.t
t/85utf8.t
t/86sqlt.t
t/87ordered.t
t/89dbicadmin.t
t/93nobindvars.t
t/93single_accessor_object.t [new file with mode: 0644]
t/94pk_mutation.t [new file with mode: 0644]
t/94versioning.t [new file with mode: 0644]
t/95sql_maker_quote.t [new file with mode: 0644]
t/96file_column.pm [new file with mode: 0644]
t/bindtype_columns.t [new file with mode: 0644]
t/cdbi-sweet-t/08pager.t
t/lib/DBICTest.pm
t/lib/DBICTest/Schema.pm
t/lib/DBICTest/Schema/Artist.pm
t/lib/DBICTest/Schema/ArtistSourceName.pm
t/lib/DBICTest/Schema/Employee.pm
t/lib/DBICTest/Schema/FileColumn.pm [new file with mode: 0644]
t/lib/DBICTest/Schema/FourKeys.pm
t/lib/DBICTest/Schema/LinerNotes.pm
t/lib/DBICTest/Schema/NoPrimaryKey.pm
t/lib/DBICTest/Schema/OneKey.pm
t/lib/DBICTest/Schema/Serialized.pm
t/lib/DBICVersionNew.pm [new file with mode: 0644]
t/lib/DBICVersionOrig.pm [new file with mode: 0644]
t/lib/sqlite.sql

index 2ba9d22..a919ccc 100644 (file)
--- a/Build.PL
+++ b/Build.PL
@@ -1,32 +1,3 @@
-use strict;
-use Module::Build;
-
-my %arguments = (
-    create_makefile_pl => 'passthrough',
-    license            => 'perl',
-    module_name        => 'DBIx::Class',
-    requires           => {
-        'Cwd'                       => 3.19,
-        'Data::Page'                => 2.00,
-        'Scalar::Util'              => 0,
-        'SQL::Abstract'             => 1.20,
-        'SQL::Abstract::Limit'      => 0.101,
-        'Class::C3'                 => 0.13,
-        'Storable'                  => 0,
-        'Class::Data::Accessor'     => 0.01,
-       'Carp::Clan'                => 0,
-        'DBI'                       => 1.40,
-        'Module::Find'              => 0,
-        'Class::Inspector'          => 0,
-    },
-    build_requires      => {
-        'DBD::SQLite'               => 1.11,
-    },
-    create_makefile_pl => 'passthrough',
-    create_readme      => 1,
-    test_files         => [ glob('t/*.t'), glob('t/*/*.t') ],
-    script_files       => [ glob('script/*') ],
-);
-
-Module::Build->new(%arguments)->create_build_script;
-
+# Dear Distribution Packager. This use of require is intentional.
+# Module::Install detects Build.PL usage and acts accordingly.
+require 'Makefile.PL';
diff --git a/Changes b/Changes
index cebe02a..92826fd 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,16 @@
 Revision history for DBIx::Class
 
+        - add support for binding BYTEA and similar parameters (w/Pg impl)
+        - add support to Ordered for multiple ordering columns
+        - mark DB.pm and compose_connection as deprecated
+        - switch tests to compose_namespace
+        - ResltClass::HashRefInflator added
+        - Changed row and rs objects to not have direct handle to a source,
+          instead a (schema,source_name) tuple of type ResultSourceHandle
+
+0.07999_01 2006-10-05 21:00:00
+        - add connect_info option "disable_statement_caching"
+        - create insert_bulk using execute_array, populate uses it
         - added DBIx::Class::Schema::load_namespaces, alternative to
           load_classes
         - added source_info method for source-level metadata (kinda like
@@ -13,12 +24,38 @@ Revision history for DBIx::Class
         - columns_info_for is deprecated, and no longer runs automatically.
           You can make it work like before via
           __PACKAGE__->column_info_from_storage(1) for now
-
-0.07002
+        - Replaced DBIx::Class::AccessorGroup and Class::Data::Accessor with
+          Class::Accessor::Grouped. Only user noticible change is to 
+          table_class on ResultSourceProxy::Table (i.e. table objects in 
+          schemas) and, resultset_class and result_class in ResultSource. 
+          These accessors no longer automatically require the classes when
+          set.
+
+0.07004
+        - fix find_related-based queries to correctly grep the unique key
+
+0.07003 2006-11-16 11:52:00
+        - fix for rt.cpan.org #22740 (use $^X instead of hardcoded "perl")
+        - Tweaks to resultset to allow inflate_result to return an array
+        - Fix UTF8Columns to work under Perl <= 5.8.0
+        - Fix up new_result in ResultSet to avoid alias-related bugs
+        - Made new/update/find handle 'single' rel accessor correctly
+        - Fix NoBindVars to be safer and handle non-true bind values
+        - Don't blow up if columns_info_for returns useless results
+        - Documentation updates
+
+0.07002 2006-09-14 21:17:32
+        - fix quote tests for recent versions of SQLite
+        - added reference implementation of Manual::Example
+        - backported column_info_from_storage accessor from -current, but
         - fixed inflate_datetime.t tests/stringify under older Test::More
+        - minor fixes for many-to-many relationship helpers
         - cleared up Relationship docs, and fixed some typos
         - use ref instead of eval to check limit syntax (to avoid issues with
           Devel::StackTrace)
+        - update ResultSet::_cond_for_update_delete to handle more complicated
+          queries
+        - bugfix to Oracle columns_info_for
         - remove_columns now deletes columns from _columns
 
 0.07001 2006-08-18 19:55:00
index 10c77a4..9184f2a 100644 (file)
@@ -25,6 +25,7 @@
 \.tmp$
 \.old$
 \.bak$
+\..*?\.sw[po]$
 \#$
 \b\.#
 
@@ -39,3 +40,6 @@
 
 # Skip maint stuff
 ^maint/
+
+# Dont use Module::Build anymore
+# Build.PL
index 192903a..b9eeb22 100644 (file)
@@ -1,31 +1,31 @@
-# Note: this file was auto-generated by Module::Build::Compat version 0.03
-    
-    unless (eval "use Module::Build::Compat 0.02; 1" ) {
-      print "This module requires Module::Build to install itself.\n";
-      
-      require ExtUtils::MakeMaker;
-      my $yn = ExtUtils::MakeMaker::prompt
-       ('  Install Module::Build now from CPAN?', 'y');
-      
-      unless ($yn =~ /^y/i) {
-       die " *** Cannot install without Module::Build.  Exiting ...\n";
-      }
-      
-      require Cwd;
-      require File::Spec;
-      require CPAN;
-      
-      # Save this 'cause CPAN will chdir all over the place.
-      my $cwd = Cwd::cwd();
-      
-      CPAN::Shell->install('Module::Build::Compat');
-      CPAN::Shell->expand("Module", "Module::Build::Compat")->uptodate
-       or die "Couldn't install Module::Build, giving up.\n";
-      
-      chdir $cwd or die "Cannot chdir() back to $cwd: $!";
-    }
-    eval "use Module::Build::Compat 0.02; 1" or die $@;
-    
-    Module::Build::Compat->run_build_pl(args => \@ARGV);
-    require Module::Build;
-    Module::Build::Compat->write_makefile(build_class => 'Module::Build');
+use inc::Module::Install 0.64;
+
+name     'DBIx-Class';
+all_from 'lib/DBIx/Class.pm';
+perl_version '5.006001';
+
+requires 'Cwd'                       => 3.19; 
+requires 'Data::Page'                => 2.00;
+requires 'Scalar::Util'              => 0;
+requires 'SQL::Abstract'             => 1.20;
+requires 'SQL::Abstract::Limit'      => 0.101;
+requires 'Class::C3'                 => 0.13;
+requires 'Storable'                  => 0;
+requires 'Carp::Clan'                => 0;
+requires 'DBI'                       => 1.40;
+requires 'Module::Find'              => 0;
+requires 'Class::Inspector'          => 0;
+requires 'Class::Accessor::Grouped'  => 0.03;
+
+# Perl 5.8.0 doesn't have utf8::is_utf8()
+requires 'Encode'                    => 0 if ($] <= 5.008000);  
+
+build_requires 'DBD::SQLite'         => 1.11;
+
+install_script 'script/dbicadmin';
+
+tests "t/*.t t/*/*.t";
+
+auto_install;
+
+WriteAll;
index 6ff6e3e..6ce93c5 100644 (file)
@@ -4,9 +4,14 @@ use strict;
 use warnings;
 
 use vars qw($VERSION);
-use base qw/DBIx::Class::Componentised Class::Data::Accessor/;
+use base qw/DBIx::Class::Componentised Class::Accessor::Grouped/;
+
+sub mk_classdata { 
+    my $self = shift;
+    $self->mk_group_accessors('inherited', $_[0]); 
+    $self->set_inherited(@_) if @_ > 1;
+}
 
-sub mk_classdata { shift->mk_classaccessor(@_); }
 sub component_base_class { 'DBIx::Class' }
 
 # Always remember to do all digits for the version even if they're 0
@@ -16,18 +21,18 @@ sub component_base_class { 'DBIx::Class' }
 $VERSION = '0.07999_01';
 
 sub MODIFY_CODE_ATTRIBUTES {
-    my ($class,$code,@attrs) = @_;
-    $class->mk_classdata('__attr_cache' => {})
-      unless $class->can('__attr_cache');
-    $class->__attr_cache->{$code} = [@attrs];
-    return ();
+  my ($class,$code,@attrs) = @_;
+  $class->mk_classdata('__attr_cache' => {})
+    unless $class->can('__attr_cache');
+  $class->__attr_cache->{$code} = [@attrs];
+  return ();
 }
 
 sub _attr_cache {
-    my $self = shift;
-    my $cache = $self->can('__attr_cache') ? $self->__attr_cache : {};
-    my $rest = eval { $self->next::method };
-    return $@ ? $cache : { %$cache, %$rest };
+  my $self = shift;
+  my $cache = $self->can('__attr_cache') ? $self->__attr_cache : {};
+  my $rest = eval { $self->next::method };
+  return $@ ? $cache : { %$cache, %$rest };
 }
 
 1;
@@ -180,6 +185,8 @@ andyg: Andy Grundman <andy@hybridized.org>
 
 ank: Andres Kievsky
 
+ash: Ash Berlin <ash@cpan.org>
+
 bert: Norbert Csongradi <bert@cpan.org>
 
 blblack: Brandon L. Black <blblack@gmail.com>
@@ -212,6 +219,8 @@ konobi: Scott McWhirter
 
 LTJake: Brian Cassidy <bricas@cpan.org>
 
+ned: Neil de Carteret
+
 nigel: Nigel Metheringham <nigelm@cpan.org>
 
 ningu: David Kamholz <dkamholz@cpan.org>
@@ -236,8 +245,12 @@ Todd Lipcon
 
 typester: Daisuke Murase <typester@cpan.org>
 
+victori: Victor Igumnov <victori@cpan.org>
+
 wdh: Will Hawes
 
+willert: Sebastian Willert <willert@cpan.org>
+
 zamolxes: Bogdan Lucaciu <bogdan@wiz.ro>
 
 =head1 LICENSE
diff --git a/lib/DBIx/Class/AccessorGroup.pm b/lib/DBIx/Class/AccessorGroup.pm
deleted file mode 100644 (file)
index 56bcf1b..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-package DBIx::Class::AccessorGroup;
-
-use strict;
-use warnings;
-
-use Carp::Clan qw/^DBIx::Class/;
-
-=head1 NAME
-
-DBIx::Class::AccessorGroup -  Lets you build groups of accessors
-
-=head1 SYNOPSIS
-
-=head1 DESCRIPTION
-
-This class lets you build groups of accessors that will call different
-getters and setters.
-
-=head1 METHODS
-
-=head2 mk_group_accessors
-
-=over 4
-
-=item Arguments: $group, @fieldspec
-
-Returns: none
-
-=back
-
-Creates a set of accessors in a given group.
-
-$group is the name of the accessor group for the generated accessors; they
-will call get_$group($field) on get and set_$group($field, $value) on set.
-
-@fieldspec is a list of field/accessor names; if a fieldspec is a scalar
-this is used as both field and accessor name, if a listref it is expected to
-be of the form [ $accessor, $field ].
-
-=cut
-
-sub mk_group_accessors {
-  my ($self, $group, @fields) = @_;
-
-  $self->_mk_group_accessors('make_group_accessor', $group, @fields);
-  return;
-}
-
-
-{
-    no strict 'refs';
-    no warnings 'redefine';
-
-    sub _mk_group_accessors {
-        my($self, $maker, $group, @fields) = @_;
-        my $class = ref $self || $self;
-
-        # So we don't have to do lots of lookups inside the loop.
-        $maker = $self->can($maker) unless ref $maker;
-
-        foreach my $field (@fields) {
-            if( $field eq 'DESTROY' ) {
-                carp("Having a data accessor named DESTROY  in ".
-                             "'$class' is unwise.");
-            }
-
-            my $name = $field;
-
-            ($name, $field) = @$field if ref $field;
-
-            my $accessor = $self->$maker($group, $field);
-            my $alias = "_${name}_accessor";
-
-            #warn "$class $group $field $alias";
-
-            *{$class."\:\:$name"}  = $accessor;
-              #unless defined &{$class."\:\:$field"}
-
-            *{$class."\:\:$alias"}  = $accessor;
-              #unless defined &{$class."\:\:$alias"}
-        }
-    }
-}
-
-=head2 mk_group_ro_accessors
-
-=over 4
-
-=item Arguments: $group, @fieldspec
-
-Returns: none
-
-=back
-
-Creates a set of read only accessors in a given group. Identical to
-<L:/mk_group_accessors> but accessors will throw an error if passed a value
-rather than setting the value.
-
-=cut
-
-sub mk_group_ro_accessors {
-    my($self, $group, @fields) = @_;
-
-    $self->_mk_group_accessors('make_group_ro_accessor', $group, @fields);
-}
-
-=head2 mk_group_wo_accessors
-
-=over 4
-
-=item Arguments: $group, @fieldspec
-
-Returns: none
-
-=back
-
-Creates a set of write only accessors in a given group. Identical to
-<L:/mk_group_accessors> but accessors will throw an error if not passed a
-value rather than getting the value.
-
-=cut
-
-sub mk_group_wo_accessors {
-    my($self, $group, @fields) = @_;
-
-    $self->_mk_group_accessors('make_group_wo_accessor', $group, @fields);
-}
-
-=head2 make_group_accessor
-
-=over 4
-
-=item Arguments: $group, $field
-
-Returns: $sub (\CODE)
-
-=back
-
-Returns a single accessor in a given group; called by mk_group_accessors
-for each entry in @fieldspec.
-
-=cut
-
-sub make_group_accessor {
-    my ($class, $group, $field) = @_;
-
-    my $set = "set_$group";
-    my $get = "get_$group";
-
-    # Build a closure around $field.
-    return sub {
-        my $self = shift;
-
-        if(@_) {
-            return $self->$set($field, @_);
-        }
-        else {
-            return $self->$get($field);
-        }
-    };
-}
-
-=head2 make_group_ro_accessor
-
-=over 4
-
-=item Arguments: $group, $field
-
-Returns: $sub (\CODE)
-
-=back
-
-Returns a single read-only accessor in a given group; called by
-mk_group_ro_accessors for each entry in @fieldspec.
-
-=cut
-
-sub make_group_ro_accessor {
-    my($class, $group, $field) = @_;
-
-    my $get = "get_$group";
-
-    return sub {
-        my $self = shift;
-
-        if(@_) {
-            my $caller = caller;
-            croak("'$caller' cannot alter the value of '$field' on ".
-                        "objects of class '$class'");
-        }
-        else {
-            return $self->$get($field);
-        }
-    };
-}
-
-=head2 make_group_wo_accessor
-
-=over 4
-
-=item Arguments: $group, $field
-
-Returns: $sub (\CODE)
-
-=back
-
-Returns a single write-only accessor in a given group; called by
-mk_group_wo_accessors for each entry in @fieldspec.
-
-=cut
-
-sub make_group_wo_accessor {
-    my($class, $group, $field) = @_;
-
-    my $set = "set_$group";
-
-    return sub {
-        my $self = shift;
-
-        unless (@_) {
-            my $caller = caller;
-            croak("'$caller' cannot access the value of '$field' on ".
-                        "objects of class '$class'");
-        }
-        else {
-            return $self->$set($field, @_);
-        }
-    };
-}
-
-=head2 get_simple
-
-=over 4
-
-=item Arguments: $field
-
-Returns: $value
-
-=back
-
-Simple getter for hash-based objects which returns the value for the field
-name passed as an argument.
-
-=cut
-
-sub get_simple {
-  my ($self, $get) = @_;
-  return $self->{$get};
-}
-
-=head2 set_simple
-
-=over 4
-
-=item Arguments: $field, $new_value
-
-Returns: $new_value
-
-=back
-
-Simple setter for hash-based objects which sets and then returns the value
-for the field name passed as an argument.
-
-=cut
-
-sub set_simple {
-  my ($self, $set, $val) = @_;
-  return $self->{$set} = $val;
-}
-
-=head2 get_component_class
-
-=over 4
-
-=item Arguments: $name
-
-Returns: $component_class
-
-=back
-
-Returns the class name for a component; returns an object key if called on
-an object, or attempts to return classdata referenced by _$name if called
-on a class.
-
-=cut
-
-sub get_component_class {
-  my ($self, $get) = @_;
-  if (ref $self) {
-      return $self->{$get};
-  } else {
-      $get = "_$get";
-      return $self->can($get) ? $self->$get : undef;
-  }
-}
-
-=head2 set_component_class
-
-=over 4
-
-=item Arguments: $name, $new_component_class
-
-Returns: $new_component_class
-
-=back
-
-Sets a component class name; attempts to require the class before setting
-but does not error if unable to do so. Sets an object key of the given name
-if called or an object or classdata called _$name if called on a class.
-
-=cut
-
-sub set_component_class {
-  my ($self, $set, $val) = @_;
-  eval "require $val";
-  if ($@) {
-      my $val_path = $val;
-      $val_path =~ s{::}{/}g;
-      carp $@ unless $@ =~ /^Can't locate $val_path\.pm/;
-  }
-  if (ref $self) {
-      return $self->{$set} = $val;
-  } else {
-      $set = "_$set";
-      return $self->can($set) ?
-        $self->$set($val) :
-        $self->mk_classdata($set => $val);
-  }
-}
-
-1;
-
-=head1 AUTHORS
-
-Matt S. Trout <mst@shadowcatsystems.co.uk>
-
-=head1 LICENSE
-
-You may distribute this code under the same terms as Perl itself.
-
-=cut
-
index 4f9a59c..92dd74c 100644 (file)
@@ -7,14 +7,12 @@ no warnings 'qw';
 use base qw/DBIx::Class/;
 
 __PACKAGE__->load_components(qw/
-  Serialize::Storable
-  InflateColumn
   Relationship
+  InflateColumn
   PK::Auto
   PK
   Row
-  ResultSourceProxy::Table
-  AccessorGroup/);
+  ResultSourceProxy::Table/);
 
 1;
 
@@ -50,8 +48,6 @@ The core modules currently are:
 
 =item L<DBIx::Class::ResultSourceProxy::Table>
 
-=item L<DBIx::Class::AccessorGroup>
-
 =back
 
 =head1 AUTHORS
index 007c82a..9d80916 100644 (file)
@@ -8,6 +8,11 @@ use DBIx::Class::Schema;
 use DBIx::Class::Storage::DBI;
 use DBIx::Class::ClassResolver::PassThrough;
 use DBI;
+use Scalar::Util;
+
+unless ($INC{"DBIx/Class/CDBICompat.pm"}) {
+  warn "IMPORTANT: DBIx::Class::DB is DEPRECATED AND *WILL* BE REMOVED. DO NOT USE.\n";
+}
 
 __PACKAGE__->load_components(qw/ResultSetProxy/);
 
@@ -23,29 +28,15 @@ sub storage { shift->schema_instance(@_)->storage; }
 
 DBIx::Class::DB - (DEPRECATED) classdata schema component
 
-=head1 SYNOPSIS
-
-  package MyDB;
-
-  use base qw/DBIx::Class/;
-  __PACKAGE__->load_components('DB');
-
-  __PACKAGE__->connection('dbi:...', 'user', 'pass', \%attrs);
-
-  package MyDB::MyTable;
-
-  use base qw/MyDB/;
-  __PACKAGE__->load_components('Core'); # just load this in MyDB if it will
-                                        # always be there
-
-  ...
-
 =head1 DESCRIPTION
 
 This class is designed to support the Class::DBI connection-as-classdata style
 for DBIx::Class. You are *strongly* recommended to use a DBIx::Class::Schema
 instead; DBIx::Class::DB will not undergo new development and will be moved
-to being a CDBICompat-only component before 1.0.
+to being a CDBICompat-only component before 1.0. In order to discourage further
+use, documentation has been removed as of 0.08000
+
+=begin HIDE_BECAUSE_THIS_CLASS_IS_DEPRECATED
 
 =head1 METHODS
 
@@ -150,13 +141,43 @@ native L<DBIx::Class::ResultSet> system.
 =cut
 
 sub resultset_instance {
-  my $class = ref $_[0] || $_[0];
-  my $source = $class->result_source_instance;
+  $_[0]->result_source_instance->resultset
+}
+
+sub result_source_instance {
+  my $class = shift;
+  $class = ref $class || $class;
+  __PACKAGE__->mk_classdata(qw/_result_source_instance/)
+    unless __PACKAGE__->can('_result_source_instance');
+
+  
+  return $class->_result_source_instance(@_) if @_;
+
+  my $source = $class->_result_source_instance;
+  return {} unless Scalar::Util::blessed($source);
+
   if ($source->result_class ne $class) {
-    $source = $source->new($source);
-    $source->result_class($class);
+    # Remove old source instance so we dont get deep recursion
+    #$DB::single = 1;
+    # Need to set it to a non-undef value so that it doesn't just fallback to
+    # a parent class's _result_source_instance
+    #$class->_result_source_instance({});
+    #$class->table($class);
+    #$source = $class->_result_source_instance;
+
+    $DB::single = 1;
+    $source = $source->new({ 
+        %$source, 
+        source_name  => $class,
+        result_class => $class
+    } );
+    $class->_result_source_instance($source);
+    if (my $coderef = $class->can('schema_instance')) {
+        $coderef->($class)->register_class($class, $class);
+    }
   }
-  return $source->resultset;
+  return $source;
 }
 
 =head2 resolve_class
@@ -177,6 +198,8 @@ Alias for L<txn_commit>
 
 Alias for L<txn_rollback>
 
+=end HIDE_BECAUSE_THIS_CLASS_IS_DEPRECATED
+
 =head1 AUTHORS
 
 Matt S. Trout <mst@shadowcatsystems.co.uk>
diff --git a/lib/DBIx/Class/FileColumn.pm b/lib/DBIx/Class/FileColumn.pm
new file mode 100644 (file)
index 0000000..757d75a
--- /dev/null
@@ -0,0 +1,208 @@
+package DBIx::Class::FileColumn;
+
+use strict;
+use warnings;
+use base 'DBIx::Class';
+use File::Path;
+use File::Copy;
+use IO::File;
+
+sub inflate_result {
+    my $self = shift;
+    my $ret = $self->next::method(@_);
+    
+    $self->_inflate_file_column($ret);
+    return $ret;
+}
+
+sub insert {
+    my ( $self, @rest ) = @_;
+
+    my ( $file, @column_names ) = $self->_load_file_column_information;
+    my $ret = $self->next::method(@rest);
+    $self->_save_file_column( $file, $ret, @column_names );
+    return $ret;
+}
+
+sub update {
+    my ($self, @rest ) = @_;
+    
+    my ( $file, @column_names ) = $self->_load_file_column_information;
+    my $ret = $self->next::method(@rest);
+    $self->_save_file_column( $file, $ret, @column_names );
+    return $ret;  
+}
+
+sub delete {
+    my ( $self, @rest ) = @_;
+
+    my @column_names = $self->columns;
+    for (@column_names) {
+        if ( $self->column_info($_)->{is_file_column} ) {
+            my $path =
+              File::Spec->catdir( $self->column_info($_)->{file_column_path},
+                $self->id );
+            rmtree( [$path], 0, 0 );
+        }
+    }
+
+    my $ret = $self->next::method(@rest);
+
+    return $ret;
+}
+
+sub _inflate_file_column {
+    my $self = shift;
+    my $ret  = shift;
+
+    my @column_names = $self->columns;
+    for(@column_names) {
+        if ( $ret->column_info($_)->{is_file_column} ) {
+            # make sure everything checks out
+            unless (defined $ret->$_) {
+                # if something is wrong set it to undef
+                $ret->$_(undef);
+                next;
+            }
+            my $fs_file =
+              File::Spec->catfile( $ret->column_info($_)->{file_column_path}, 
+                $ret->id, $ret->$_ );
+            $ret->$_({handle => new IO::File($fs_file, "r"), filename => $ret->$_});
+        }
+    }
+}
+
+sub _load_file_column_information {
+    my $self = shift;
+
+    my $file;
+    my @column_names;
+
+    @column_names = $self->columns;
+    for (@column_names) {
+        if ( $self->column_info($_)->{is_file_column} ) {
+            # make sure everything checks out
+            unless ((defined $self->$_) ||
+             (defined $self->$_->{filename} && defined $self->$_->{handle})) {
+                # if something is wrong set it to undef
+                $self->$_(undef);
+                next;
+            }
+            $file->{$_} = $self->$_;
+            $self->$_( $self->$_->{filename} );
+        }
+    }
+
+    return ( $file, @column_names );
+}
+
+sub _save_file_column {
+    my ( $self, $file, $ret, @column_names ) = @_;
+
+    for (@column_names) {
+        if ( $ret->column_info($_)->{is_file_column} ) {
+            next unless (defined $ret->$_);
+            my $file_path =
+              File::Spec->catdir( $ret->column_info($_)->{file_column_path},
+                $ret->id );
+            mkpath [$file_path];
+            
+            my $outfile =
+              File::Spec->catfile( $file_path, $file->{$_}->{filename} );
+            File::Copy::copy( $file->{$_}->{handle}, $outfile );
+        
+            $self->_file_column_callback($file->{$_},$ret,$_);
+        }
+    }
+}
+
+=head1 METHODS
+
+=cut
+
+
+=head2 _file_column_callback ($file,$ret,$target)
+
+method made to be overridden for callback purposes.
+
+=cut
+
+sub _file_column_callback {
+    my ($self,$file,$ret,$target) = @_;
+}
+
+=head1 NAME
+
+DBIx::Class::FileColumn - FileColumn map files from the Database to the filesystem.
+
+=head1 DESCRIPTION
+
+FileColumn
+
+=head1 SYNOPSIS
+
+In your L<DBIx::Class> table class:
+
+    __PACKAGE__->load_components( "PK::Auto", "FileColumn", "Core" );
+    
+    # define your columns
+    __PACKAGE__->add_columns(
+        "id",
+        {
+            data_type         => "integer",
+            is_auto_increment => 1,
+            is_nullable       => 0,
+            size              => 4,
+        },
+        "filename",
+        {
+            data_type           => "varchar",
+            is_file_column      => 1,
+            file_column_path    =>'/tmp/uploaded_files',
+            # or for a Catalyst application 
+            # file_column_path  => MyApp->path_to('root','static','files'),
+            default_value       => undef,
+            is_nullable         => 1,
+            size                => 255,
+        },
+    );
+    
+
+In your L<Catalyst::Controller> class:
+
+FileColumn requires a hash that contains L<IO::File> as handle and the file's name as name.
+
+    my $entry = $c->model('MyAppDB::Articles')->create({ 
+        subject => 'blah',
+        filename => { 
+            handle => $c->req->upload('myupload')->fh, 
+            filename => $c->req->upload('myupload')->basename 
+        },
+        body => '....'
+    });
+    $c->stash->{entry}=$entry;
+    
+
+And Place the following in your TT template
+    
+    Article Subject: [% entry.subject %]
+    Uploaded File: 
+    <a href="/static/files/[% entry.id %]/[% entry.filename.filename %]">File</a>
+    Body: [% entry.body %]
+    
+The file will be stored on the filesystem for later retrieval.
+Calling delete on your resultset will delete the file from the filesystem.
+Retrevial of the record automatically inflates the column back to the set hash with the IO::File handle and filename.
+
+=head1 AUTHOR
+
+Victor Igumnov
+
+=head1 LICENSE
+
+This library is free software, you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
+
+1;
index de68b23..721894f 100644 (file)
@@ -8,7 +8,7 @@ use base qw/DBIx::Class::Row/;
 
 =head1 NAME
 
-DBIx::Class::InflateColumn - Automatically create objects from column data
+DBIx::Class::InflateColumn - Automatically create references from column data
 
 =head1 SYNOPSIS
 
@@ -20,13 +20,18 @@ DBIx::Class::InflateColumn - Automatically create objects from column data
 
 =head1 DESCRIPTION
 
-This component translates column data into objects, i.e. "inflating"
-the column data. It also "deflates" objects into an appropriate format
+This component translates column data into references, i.e. "inflating"
+the column data. It also "deflates" references into an appropriate format
 for the database.
 
 It can be used, for example, to automatically convert to and from
 L<DateTime> objects for your date and time fields.
 
+It will accept arrayrefs, hashrefs and blessed references (objects),
+but not scalarrefs. Scalar references are passed through to the
+database to deal with, to allow such settings as C< \'year + 1'> and
+C< \'DEFAULT' > to work.
+
 =head1 METHODS
 
 =head2 inflate_column
@@ -85,7 +90,9 @@ sub _inflated_column {
 
 sub _deflated_column {
   my ($self, $col, $value) = @_;
-  return $value unless ref $value; # If it's not an object, don't touch it
+#  return $value unless ref $value && blessed($value); # If it's not an object, don't touch it
+  ## Leave scalar refs (ala SQL::Abstract literal SQL), untouched, deflate all other refs
+  return $value unless (ref $value && ref($value) ne 'SCALAR');
   my $info = $self->column_info($col) or
     $self->throw_exception("No column info for $col");
   return $value unless exists $info->{_inflate_info};
@@ -125,14 +132,15 @@ analogous to L<DBIx::Class::Row/set_column>.
 =cut
 
 sub set_inflated_column {
-  my ($self, $col, $obj) = @_;
-  $self->set_column($col, $self->_deflated_column($col, $obj));
-  if (blessed $obj) {
-    $self->{_inflated_column}{$col} = $obj; 
+  my ($self, $col, $inflated) = @_;
+  $self->set_column($col, $self->_deflated_column($col, $inflated));
+#  if (blessed $inflated) {
+  if (ref $inflated && ref($inflated) ne 'SCALAR') {
+    $self->{_inflated_column}{$col} = $inflated; 
   } else {
     delete $self->{_inflated_column}{$col};      
   }
-  return $obj;
+  return $inflated;
 }
 
 =head2 store_inflated_column
@@ -145,100 +153,15 @@ as dirty. This is directly analogous to L<DBIx::Class::Row/store_column>.
 =cut
 
 sub store_inflated_column {
-  my ($self, $col, $obj) = @_;
-  unless (blessed $obj) {
+  my ($self, $col, $inflated) = @_;
+#  unless (blessed $inflated) {
+  unless (ref $inflated && ref($inflated) ne 'SCALAR') {
       delete $self->{_inflated_column}{$col};
-      $self->store_column($col => $obj);
-      return $obj;
+      $self->store_column($col => $inflated);
+      return $inflated;
   }
   delete $self->{_column_data}{$col};
-  return $self->{_inflated_column}{$col} = $obj;
-}
-
-=head2 get_column
-
-Gets a column value in the same way as L<DBIx::Class::Row/get_column>. If there
-is an inflated value stored that has not yet been deflated, it is deflated
-when the method is invoked.
-
-=cut
-
-sub get_column {
-  my ($self, $col) = @_;
-  if (exists $self->{_inflated_column}{$col}
-        && !exists $self->{_column_data}{$col}) {
-    $self->store_column($col, $self->_deflated_column($col, $self->{_inflated_column}{$col})); 
-  }
-  return $self->next::method($col);
-}
-
-=head2 get_columns 
-
-Returns the get_column info for all columns as a hash,
-just like L<DBIx::Class::Row/get_columns>.  Handles inflation just
-like L</get_column>.
-
-=cut
-
-sub get_columns {
-  my $self = shift;
-  if (exists $self->{_inflated_column}) {
-    foreach my $col (keys %{$self->{_inflated_column}}) {
-      $self->store_column($col, $self->_deflated_column($col, $self->{_inflated_column}{$col}))
-       unless exists $self->{_column_data}{$col};
-    }
-  }
-  return $self->next::method;
-}
-
-=head2 has_column_loaded
-
-Like L<DBIx::Class::Row/has_column_loaded>, but also returns true if there
-is an inflated value stored.
-
-=cut
-
-sub has_column_loaded {
-  my ($self, $col) = @_;
-  return 1 if exists $self->{_inflated_column}{$col};
-  return $self->next::method($col);
-}
-
-=head2 update
-
-Updates a row in the same way as L<DBIx::Class::Row/update>, handling
-inflation and deflation of columns appropriately.
-
-=cut
-
-sub update {
-  my ($class, $attrs, @rest) = @_;
-  foreach my $key (keys %{$attrs||{}}) {
-    if (ref $attrs->{$key}
-          && exists $class->column_info($key)->{_inflate_info}) {
-      $class->set_inflated_column($key, delete $attrs->{$key});
-    }
-  }
-  return $class->next::method($attrs, @rest);
-}
-
-=head2 new
-
-Creates a row in the same way as L<DBIx::Class::Row/new>, handling
-inflation and deflation of columns appropriately.
-
-=cut
-
-sub new {
-  my ($class, $attrs, @rest) = @_;
-  my $inflated;
-  foreach my $key (keys %{$attrs||{}}) {
-    $inflated->{$key} = delete $attrs->{$key} 
-      if ref $attrs->{$key} && exists $class->column_info($key)->{_inflate_info};
-  }
-  my $obj = $class->next::method($attrs, @rest);
-  $obj->{_inflated_column} = $inflated if $inflated;
-  return $obj;
+  return $self->{_inflated_column}{$col} = $inflated;
 }
 
 =head1 SEE ALSO
@@ -259,6 +182,8 @@ Matt S. Trout <mst@shadowcatsystems.co.uk>
 
 Daniel Westermann-Clark <danieltwc@cpan.org> (documentation)
 
+Jess Robinson <cpan@desert-island.demon.co.uk>
+
 =head1 LICENSE
 
 You may distribute this code under the same terms as Perl itself.
index f05523c..27ceaeb 100644 (file)
@@ -33,6 +33,8 @@ one your code should continue to work without modification (though note
 that this feature is new as of 0.07, so it may not be perfect yet - bug
 reports to the list very much welcome).
 
+For more help with components, see L<DBIx::Class::Manual::Component>.
+
 =cut
 
 __PACKAGE__->load_components(qw/InflateColumn/);
index e46d388..6c45d9b 100644 (file)
@@ -72,8 +72,10 @@ L<SQL::Abstract/WHERE CLAUSES>.
 
 =head3 Using specific columns
 
-When you only want selected columns from a table, you can use C<cols> to
-specify which ones you need:
+When you only want specific columns from a table, you can use
+C<columns> to specify which ones you need. This is useful to avoid
+loading columns with large amounts of data that you aren't about to
+use anyway:
 
   my $rs = $schema->resultset('Artist')->search(
     undef,
@@ -85,6 +87,9 @@ specify which ones you need:
   # Equivalent SQL:
   # SELECT artist.name FROM artist
 
+This is a shortcut for C<select> and C<as>, see below. C<columns>
+cannot be used together with C<select> and C<as>.
+
 =head3 Using database functions or stored procedures
 
 The combination of C<select> and C<as> can be used to return the result of a
@@ -94,7 +99,7 @@ stored procedure name). You then use C<as> to set the column name you will use
 to access the returned value:
 
   my $rs = $schema->resultset('Artist')->search(
-    undef,
+    {},
     {
       select => [ 'name', { LENGTH => 'name' } ],
       as     => [qw/ name name_length /],
@@ -105,15 +110,15 @@ to access the returned value:
   # SELECT name name, LENGTH( name ) name_length
   # FROM artist
 
-If your alias exists as a column in your base class (i.e. it was added with
-C<add_columns>), you just access it as normal. Our C<Artist> class has a C<name>
-column, so we just use the C<name> accessor:
+If your alias exists as a column in your base class (i.e. it was added
+with C<add_columns>), you just access it as normal. Our C<Artist>
+class has a C<name> column, so we just use the C<name> accessor:
 
   my $artist = $rs->first();
   my $name = $artist->name();
 
 If on the other hand the alias does not correspond to an existing column, you
-can get the value using the C<get_column> accessor:
+have to fetch the value using the C<get_column> accessor:
 
   my $name_length = $artist->get_column('name_length');
 
@@ -129,7 +134,7 @@ any of your aliases using either of these:
 =head3 SELECT DISTINCT with multiple columns
 
   my $rs = $schema->resultset('Foo')->search(
-    undef,
+    {},
     {
       select => [
         { distinct => [ $source->columns ] }
@@ -143,7 +148,7 @@ any of your aliases using either of these:
 =head3 SELECT COUNT(DISTINCT colname)
 
   my $rs = $schema->resultset('Foo')->search(
-    undef,
+    {},
     {
       select => [
         { count => { distinct => 'colname' } }
@@ -157,7 +162,7 @@ any of your aliases using either of these:
 L<DBIx::Class> supports C<GROUP BY> as follows:
 
   my $rs = $schema->resultset('Artist')->search(
-    undef,
+    {},
     {
       join     => [qw/ cds /],
       select   => [ 'name', { count => 'cds.cdid' } ],
@@ -173,7 +178,7 @@ L<DBIx::Class> supports C<GROUP BY> as follows:
 
 =head3 Predefined searches
 
-You can write your own DBIx::Class::ResultSet class by inheriting from it
+You can write your own L<DBIx::Class::ResultSet> class by inheriting from it
 and define often used searches as methods:
 
   package My::DBIC::ResultSet::CD;
@@ -382,7 +387,7 @@ From 0.04999_05 onwards, C<prefetch> can be nested more than one relationship
 deep using the same syntax as a multi-step join:
 
   my $rs = $schema->resultset('Tag')->search(
-    undef,
+    {},
     {
       prefetch => {
         cd => 'artist'
@@ -401,6 +406,55 @@ SQL statements:
   my $tag = $rs->first;
   print $tag->cd->artist->name;
 
+=head2 Columns of data
+
+If you want to find the sum of a particular column there are several
+ways, the obvious one is to use search:
+
+  my $rs = $schema->resultset('Items')->search(
+    {},
+    { 
+       select => [ { sum => 'Cost' } ],
+       as     => [ 'total_cost' ],
+    }
+  );
+  my $tc = $rs->first->get_column('total_cost');
+
+Or, you can use the L<DBIx::Class::ResultSetColumn>, which gets
+returned when you ask the C<ResultSet> for a column using
+C<get_column>:
+
+  my $cost = $schema->resultset('Items')->get_column('Cost');
+  my $tc = $cost->sum;
+
+With this you can also do:
+
+  my $minvalue = $cost->min;
+  my $maxvalue = $cost->max;
+
+Or just iterate through the values of this column only:
+
+  while ( my $c = $cost->next ) {
+    print $c;
+  }
+
+  foreach my $c ($cost->all) {
+    print $c;
+  }
+
+C<ResultSetColumn> only has a limited number of built-in functions, if
+you need one that it doesn't have, then you can use the C<func> method
+instead:
+
+  my $avg = $cost->func('AVERAGE');
+
+This will cause the following SQL statement to be run:
+
+  SELECT AVERAGE(Cost) FROM Items me
+
+Which will of course only work if your database supports this function.
+See L<DBIx::Class::ResultSetColumn> for more documentation.
+
 =head2 Using relationships
 
 =head3 Create a new row in a related table
@@ -539,7 +593,7 @@ For more complex stringification, you can use an anonymous subroutine:
   use overload '""' => sub { $_[0]->name . ", " .
                              $_[0]->address }, fallback => 1;
 
-=head3 Stringifcation Example
+=head3 Stringification Example
 
 Suppose we have two tables: C<Product> and C<Category>. The table
 specifications are:
@@ -588,7 +642,9 @@ To create a DBIx::Class schema from an existing database:
 To create a MySQL database from an existing L<DBIx::Class> schema, convert the
 schema to MySQL's dialect of SQL:
 
-  sqlt --from DBIx::Class --to MySQL --DBIx::Class "MySchema.pm" > Schema1.sql
+  sqlt --from SQL::Translator::Parser::DBIx::Class 
+       --to MySQL 
+       --DBIx::Class "MySchema.pm" > Schema1.sql
   
 And import using the mysql client:
 
@@ -671,14 +727,14 @@ described under C<Schema import/export>.
 Use C<sqlt> to transform your schema into an SQL script suitable for your
 customer's database. E.g. for MySQL:
 
-  sqlt --from DBIx::Class
+  sqlt --from SQL::Translator::Parser::DBIx::Class
        --to MySQL
        --DBIx::Class "MySchema.pm" > Schema1.mysql.sql
 
 If you need to target databases from multiple vendors, just generate an SQL
 script suitable for each. To support PostgreSQL too:
 
-  sqlt --from DBIx::Class
+  sqlt --from SQL::Translator::DBIx::Class
        --to PostgreSQL
        --DBIx::Class "MySchema.pm" > Schema1.pgsql.sql
 
@@ -706,7 +762,7 @@ As your application evolves, it may be necessary to modify your schema to
 change functionality. Once the changes are made to your schema in DBIx::Class,
 export the modified schema as before, taking care not to overwrite the original:
 
-  sqlt --from DBIx::Class
+  sqlt --from SQL::Translator::DBIx::Class
        --to MySQL
        --DBIx::Class "Anything.pm" > Schema2.mysql.sql
 
@@ -721,33 +777,35 @@ The schema update can be deployed to customers using the same method as before.
 
 =head2 Setting limit dialect for SQL::Abstract::Limit
 
-In some cases, SQL::Abstract::Limit cannot determine the dialect of the remote
-SQL-server by looking at the database-handle. This is a common problem when
-using the DBD::JDBC, since the DBD-driver only know that in has a Java-driver
-available, not which JDBC-driver the Java component has loaded.
-This specifically sets the limit_dialect to Microsoft SQL-server (Se more names
-in SQL::Abstract::Limit -documentation.
+In some cases, SQL::Abstract::Limit cannot determine the dialect of
+the remote SQL server by looking at the database handle. This is a
+common problem when using the DBD::JDBC, since the DBD-driver only
+know that in has a Java-driver available, not which JDBC driver the
+Java component has loaded.  This specifically sets the limit_dialect
+to Microsoft SQL-server (See more names in SQL::Abstract::Limit
+-documentation.
 
   __PACKAGE__->storage->sql_maker->limit_dialect('mssql');
 
-The JDBC-bridge is one way of getting access to a MSSQL-server from a platform
+The JDBC bridge is one way of getting access to a MSSQL server from a platform
 that Microsoft doesn't deliver native client libraries for. (e.g. Linux)
 
-=head2 Setting quotes for the generated SQL. 
+=head2 Setting quoting for the generated SQL. 
 
-If the database contains columnames with spaces and/or reserved words, the
-SQL-query needs to be quoted. This is done using:
+If the database contains column names with spaces and/or reserved words, they
+need to be quoted in the SQL queries. This is done using:
 
   __PACKAGE__->storage->sql_maker->quote_char([ qw/[ ]/] );
   __PACKAGE__->storage->sql_maker->name_sep('.');
 
-The first sets the quotesymbols. If the quote i "symmetric" as " or '
+The first sets the quote characters. Either a pair of matching
+brackets, or a C<"> or C<'>:
   
   __PACKAGE__->storage->sql_maker->quote_char('"');
 
-is enough. If the left quote differs form the right quote, the first 
-notation should be used. name_sep needs to be set to allow the 
-SQL generator to put the quotes the correct place. 
+Check the documentation of your database for the correct quote
+characters to use. C<name_sep> needs to be set to allow the SQL
+generator to put the quotes the correct place.
 
 =head2 Overloading methods
 
@@ -772,11 +830,11 @@ You can accomplish this by overriding C<store_column>:
   }
 
 Note that the hard work is done by the call to C<next::method>, which
-redispatches your call to store_column to the superclass(es).
+redispatches your call to store_column in the superclass(es).
 
 =head3 Automatically creating related objects
 
-You might have a class C<Artist> which has many C<CD>s.  Further, you
+You might have a class C<Artist> which has many C<CD>s.  Further, if you
 want to create a C<CD> object every time you insert an C<Artist> object.
 You can accomplish this by overriding C<insert> on your objects:
 
@@ -836,11 +894,11 @@ L<Data::Dumper/EXAMPLES> for more information.
 
 =head2 Retrieving a row object's Schema
 
-It is possible to get a Schema object from a row object like so,
+It is possible to get a Schema object from a row object like so:
 
   my $schema = $cd->result_source->schema;
-  my $artist_rs = $schema->resultset('Artist');
-           # for example
+  # use the schema as normal:
+  my $artist_rs = $schema->resultset('Artist'); 
 
 This can be useful when you don't want to pass around a Schema object to every
 method.
@@ -921,19 +979,22 @@ not work, but then you already know the value of the last primary key anyway.
 =head2 Dynamic Sub-classing DBIx::Class proxy classes 
 (AKA multi-class object inflation from one table) 
  
-L<DBIx::Class> classes are proxy classes, therefore some different techniques 
-need to be employed for more than basic subclassing.  In this example we have  
-a single user table that carries a boolean bit for admin.  We would like  
-like to give the admin users objects(L<DBIx::Class::Row>) the same methods as  
-a regular user but also special admin only methods.  It doesn't make sense to  
-create two seperate proxy-class files for this.  We would be copying all the  
-user methods into the Admin class.  There is a cleaner way to accomplish this. 
-
-Overriding the C<inflate_results()> method within the User proxy-class gives 
-us the effect we want.  This method is called by L<DBIx::Class::ResultSet> when  
-inflating a result from storage.  So we grab the object being returned, inspect 
-the values we are looking for, bless it if it's an admin object, and then  
-return it.  Running the test file below will confirm this works. 
+L<DBIx::Class> classes are proxy classes, therefore some different
+techniques need to be employed for more than basic subclassing.  In
+this example we have a single user table that carries a boolean bit
+for admin.  We would like like to give the admin users
+objects(L<DBIx::Class::Row>) the same methods as a regular user but
+also special admin only methods.  It doesn't make sense to create two
+seperate proxy-class files for this.  We would be copying all the user
+methods into the Admin class.  There is a cleaner way to accomplish
+this.
+
+Overriding the C<inflate_result> method within the User proxy-class
+gives us the effect we want.  This method is called by
+L<DBIx::Class::ResultSet> when inflating a result from storage.  So we
+grab the object being returned, inspect the values we are looking for,
+bless it if it's an admin object, and then return it.  See the example
+below:
  
 B<Schema Definition> 
  
@@ -955,7 +1016,7 @@ B<Proxy-Class definitions>
     ### Defined what our admin class is for ensure_class_loaded 
     my $admin_class = __PACKAGE__ . '::Admin'; 
      
-    __PACKAGE__->load_components(qw/PK::Auto Core/); 
+    __PACKAGE__->load_components(qw/Core/); 
      
     __PACKAGE__->table('users'); 
      
@@ -1035,4 +1096,30 @@ B<Test File> test.pl
     ### The statement below will print 
     print "I can do admin stuff\n" if $admin->can('do_admin_stuff'); 
 
+=head2 Skip object creation for faster results
+
+DBIx::Class is not built for speed, it's built for convenience and
+ease of use, but sometimes you just need to get the data, and skip the
+fancy objects.
+  
+To do this simply use L<DBIx::Class::ResultClass::HashRefInflator>.
+  
+ my $rs = $schema->resultset('CD');
+ $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
+ my $hash_ref = $rs->find(1);
+  
+Wasn't that easy?
+  
+=head2 Want to know if find_or_create found or created a row?
+
+Just use C<find_or_new> instead, then check C<in_storage>:
+
+  my $obj = $rs->find_or_new({ blah => 'blarg' });
+  unless ($obj->in_storage) {
+    $obj->insert;
+    # do whatever else you wanted if it was a new row
+  }
+
 =cut
index 20983ce..928808c 100644 (file)
@@ -245,10 +245,16 @@ documentation.
 
 =over 4
 
-=item .. fetch as much data as possible in as few select calls as possible? (prefetch)
+=item .. fetch as much data as possible in as few select calls as possible?
 
 See the prefetch examples in the L<Cookbook|DBIx::Class::Manual::Cookbook>.
 
+=item .. fetch a whole column of data instead of a row?
+
+Call C<get_column> on a L<DBIx::Class::ResultSet>, this returns a
+L<DBIx::Class::ResultSetColumn>, see it's documentation and the
+L<Cookbook|DBIx::Class::Manual::Cookbook> for details.
+
 =back
 
 =head2 Inserting and updating data
index 8e2c74d..d5a7a00 100644 (file)
@@ -17,7 +17,26 @@ Create a table for your ordered data.
     name TEXT NOT NULL,
     position INTEGER NOT NULL
   );
-  # Optional: group_id INTEGER NOT NULL
+
+Optionally, add one or more columns to specify groupings, allowing you 
+to maintain independent ordered lists within one table:
+
+  CREATE TABLE items (
+    item_id INTEGER PRIMARY KEY AUTOINCREMENT,
+    name TEXT NOT NULL,
+    position INTEGER NOT NULL,
+    group_id INTEGER NOT NULL
+  );
+
+Or even
+
+  CREATE TABLE items (
+    item_id INTEGER PRIMARY KEY AUTOINCREMENT,
+    name TEXT NOT NULL,
+    position INTEGER NOT NULL,
+    group_id INTEGER NOT NULL,
+    other_group_id INTEGER NOT NULL
+  );
 
 In your Schema or DB class add Ordered to the top 
 of the component list.
@@ -29,7 +48,14 @@ each row.
 
   package My::Item;
   __PACKAGE__->position_column('position');
-  __PACKAGE__->grouping_column('group_id'); # optional
+
+If you are using one grouping column, specify it as follows:
+
+  __PACKAGE__->grouping_column('group_id');
+
+Or if you have multiple grouping columns:
+
+  __PACKAGE__->grouping_column(['group_id', 'other_group_id']);
 
 Thats it, now you can change the position of your objects.
 
@@ -54,6 +80,10 @@ Thats it, now you can change the position of your objects.
   $item->move_first();
   $item->move_last();
   $item->move_to( $position );
+  $item->move_to_group( 'groupname' );
+  $item->move_to_group( 'groupname', $position );
+  $item->move_to_group( {group_id=>'groupname', 'other_group_id=>'othergroupname'} );
+  $item->move_to_group( {group_id=>'groupname', 'other_group_id=>'othergroupname'}, $position );
 
 =head1 DESCRIPTION
 
@@ -127,6 +157,7 @@ is this sibliing.
 sub first_sibling {
     my( $self ) = @_;
     return 0 if ($self->get_column($self->position_column())==1);
+
     return ($self->result_source->resultset->search(
         {
             $self->position_column => 1,
@@ -289,11 +320,72 @@ sub move_to {
         $self->_grouping_clause(),
     });
     my $op = ($from_position>$to_position) ? '+' : '-';
-    $rs->update({ $position_column => \"$position_column $op 1" });
+    $rs->update({ $position_column => \"$position_column $op 1" });  #" Sorry, GEdit bug
+    $self->{_ORDERED_INTERNAL_UPDATE} = 1;
     $self->update({ $position_column => $to_position });
     return 1;
 }
 
+
+
+=head2 move_to_group
+
+  $item->move_to_group( $group, $position );
+
+Moves the object to the specified position of the specified
+group, or to the end of the group if $position is undef.
+1 is returned on success, and 0 is returned if the object is
+already at the specified position of the specified group.
+
+$group may be specified as a single scalar if only one 
+grouping column is in use, or as a hashref of column => value pairs
+if multiple grouping columns are in use.
+
+=cut
+
+sub move_to_group {
+    my( $self, $to_group, $to_position ) = @_;
+
+    # if we're given a string, turn it into a hashref
+    unless (ref $to_group eq 'HASH') {
+        $to_group = {($self->_grouping_columns)[0] => $to_group};
+    }
+
+    my $position_column = $self->position_column;
+    #my @grouping_columns = $self->_grouping_columns;
+
+    return 0 if ( ! defined($to_group) );
+    return 0 if ( defined($to_position) and $to_position < 1 );
+    return 0 if ( $self->_is_in_group($to_group) 
+                    and ((not defined($to_position)) 
+                            or (defined($to_position) and $self->$position_column==$to_position)
+                        )
+                    );
+
+    # Move to end of current group and adjust siblings
+    $self->move_last;
+
+    $self->set_columns($to_group);
+    my $new_group_count = $self->result_source->resultset->search({$self->_grouping_clause()})->count();
+    if (!defined($to_position) or $to_position > $new_group_count) {
+        $self->{_ORDERED_INTERNAL_UPDATE} = 1;
+        $self->update({ $position_column => $new_group_count + 1 });
+    }
+    else {
+        my @between = ($to_position, $new_group_count);
+
+        my $rs = $self->result_source->resultset->search({
+            $position_column => { -between => [ @between ] },
+            $self->_grouping_clause(),
+        });
+        $rs->update({ $position_column => \"$position_column + 1" }); #"
+        $self->{_ORDERED_INTERNAL_UPDATE} = 1;
+        $self->update({ $position_column => $to_position });
+    }
+
+    return 1;
+}
+
 =head2 insert
 
 Overrides the DBIC insert() method by providing a default 
@@ -310,6 +402,53 @@ sub insert {
     return $self->next::method( @_ );
 }
 
+=head2 update
+
+Overrides the DBIC update() method by checking for a change
+to the position and/or group columns.  Movement within a
+group or to another group is handled by repositioning
+the appropriate siblings.  Position defaults to the end
+of a new group if it has been changed to undef.
+
+=cut
+
+sub update {
+    my $self = shift;
+
+    if ($self->{_ORDERED_INTERNAL_UPDATE}) {
+        delete $self->{_ORDERED_INTERNAL_UPDATE};
+        return $self->next::method( @_ );
+    }
+
+    $self->set_columns($_[0]) if @_ > 0;
+    my %changes = $self->get_dirty_columns;
+    $self->discard_changes;
+
+    my $pos_col = $self->position_column;
+
+    # if any of our grouping columns have been changed
+    if (grep {$_} map {exists $changes{$_}} $self->_grouping_columns ) {
+
+        # create new_group by taking the current group and inserting changes
+        my $new_group = {$self->_grouping_clause};
+        foreach my $col (keys %$new_group) {
+            if (exists $changes{$col}) {
+                $new_group->{$col} = $changes{$col};
+                delete $changes{$col}; # don't want to pass this on to next::method
+            }
+        }
+
+        $self->move_to_group(
+            $new_group,
+            exists($changes{$pos_col}) ? delete($changes{$pos_col}) : $self->$pos_col
+        );
+    }
+    elsif (exists $changes{$pos_col}) {
+        $self->move_to(delete $changes{$pos_col});
+    }
+    return $self->next::method( \%changes );
+}
+
 =head2 delete
 
 Overrides the DBIC delete() method by first moving the object 
@@ -331,21 +470,57 @@ need to use them.
 
 =head2 _grouping_clause
 
-This method returns a name=>value pare for limiting a search 
-by the collection column.  If the collection column is not 
+This method returns one or more name=>value pairs for limiting a search 
+by the grouping column(s).  If the grouping column is not 
 defined then this will return an empty list.
 
 =cut
-
 sub _grouping_clause {
     my( $self ) = @_;
+    return map {  $_ => $self->get_column($_)  } $self->_grouping_columns();
+}
+
+
+
+=head2 _get_grouping_columns
+
+Returns a list of the column names used for grouping, regardless of whether
+they were specified as an arrayref or a single string, and returns ()
+if there is no grouping.
+
+=cut
+sub _grouping_columns {
+    my( $self ) = @_;
     my $col = $self->grouping_column();
-    if ($col) {
-        return ( $col => $self->get_column($col) );
+    if (ref $col eq 'ARRAY') {
+        return @$col;
+    } elsif ($col) {
+        return ( $col );
+    } else {
+        return ();
     }
-    return ();
 }
 
+
+
+=head2 _is_in_group($other)
+
+    $item->_is_in_group( {user => 'fred', list => 'work'} )
+
+Returns true if the object is in the group represented by hashref $other
+=cut
+sub _is_in_group {
+    my ($self, $other) = @_;
+    my $current = {$self->_grouping_clause};
+    return 0 unless (ref $other eq 'HASH') and (keys %$current == keys %$other);
+    for my $key (keys %$current) {
+        return 0 unless exists $other->{$key};
+        return 0 if $current->{$key} ne $other->{$key};
+    }
+    return 1;
+}
+
+
 1;
 __END__
 
index ea22a21..9b9f8a4 100644 (file)
@@ -99,8 +99,8 @@ Produces a condition hash to locate a row based on the primary key(s).
 sub ident_condition {
   my ($self, $alias) = @_;
   my %cond;
-  $cond{(defined $alias ? "${alias}.$_" : $_)} = $self->get_column($_)
-    for $self->primary_columns;
+  my $prefix = defined $alias ? $alias.'.' : '';
+  $cond{$prefix.$_} = $self->get_column($_) for $self->primary_columns;
   return \%cond;
 }
 
index 8c12ab2..b30a9ff 100644 (file)
@@ -1,4 +1,5 @@
-package DBIx::Class::PK::Auto::DB2;
+package # hide package from pause
+  DBIx::Class::PK::Auto::DB2;
 
 use strict;
 use warnings;
index 637cb32..f87a3cf 100644 (file)
@@ -1,4 +1,5 @@
-package DBIx::Class::PK::Auto::MSSQL;
+package # hide package from pause
+  DBIx::Class::PK::Auto::MSSQL;
 
 use strict;
 use warnings;
index 3107819..8dd5c09 100644 (file)
@@ -1,4 +1,5 @@
-package DBIx::Class::PK::Auto::MySQL;
+package # hide package from pause
+  DBIx::Class::PK::Auto::MySQL;
 
 use strict;
 use warnings;
index 4d39f5e..e23e243 100644 (file)
@@ -1,4 +1,5 @@
-package DBIx::Class::PK::Auto::Oracle;
+package # hide package from pause
+  DBIx::Class::PK::Auto::Oracle;
 
 use strict;
 use warnings;
index 1a850b4..0a6bd27 100644 (file)
@@ -1,4 +1,5 @@
-package DBIx::Class::PK::Auto::Pg;
+package # hide package from pause
+  DBIx::Class::PK::Auto::Pg;
 
 use strict;
 use warnings;
index 80bdc7c..6fb9495 100644 (file)
@@ -1,4 +1,5 @@
-package DBIx::Class::PK::Auto::SQLite;
+package # hide package from pause
+  DBIx::Class::PK::Auto::SQLite;
 
 use strict;
 use warnings;
index 6a5a046..c987bb5 100644 (file)
@@ -125,7 +125,7 @@ The above belongs_to relationship could also have been specified as,
 
   My::DBIC::Schema::Book->belongs_to( author,
                                       'My::DBIC::Schema::Author',
-                                      { 'self.author' => 'foreign.author' } );
+                                      { 'foreign.author' => 'self.author' } );
 
 Creates a relationship where the calling class stores the foreign class's
 primary key in one (or more) of its columns. This relationship defaults to
@@ -308,9 +308,11 @@ And, for the reverse relationship, from Role to Actor:
 
   My::DBIC::Schema::Role->many_to_many( actors => 'actor_roles', 'actor' );
 
-Creates accessors bridging two relationships; not strictly a relationship in
-its own right, although the accessor will return a resultset or collection of
-objects just as a has_many would.
+Many_to_many is not strictly a relationship in its own right. Instead, it is
+a bridge between two resultsets which provide the same kind of convenience
+accessors as true relationships provide. Although the accessor will return a 
+resultset or collection of objects just like has_many does, you cannot call 
+C<$related_resultset> and similar methods which operate on true relationships.
 
 In the above example, ActorRoles is the link table class, and Role is the
 foreign class. The C<$link_rel_name> parameter is the name of the accessor for
index 2c9a3bb..6bdefd4 100644 (file)
@@ -16,6 +16,11 @@ sub has_many {
       "${class} has more"
     ) if $too_many;
 
+    $class->throw_exception(
+      "has_many needs a primary key to infer a join; ".
+      "${class} has none"
+    ) if !defined $pri && (!defined $cond || !length $cond);
+
     my ($f_key,$guess);
     if (defined $cond && length $cond) {
       $f_key = $cond;
index 568078c..543649b 100644 (file)
@@ -17,10 +17,17 @@ sub _has_one {
   unless (ref $cond) {
     $class->ensure_class_loaded($f_class);
     my ($pri, $too_many) = $class->primary_columns;
+
     $class->throw_exception(
       "might_have/has_one can only infer join for a single primary key; ".
       "${class} has more"
     ) if $too_many;
+
+    $class->throw_exception(
+      "might_have/has_one needs a primary key  to infer a join; ".
+      "${class} has none"
+    ) if !defined $pri && (!defined $cond || !length $cond);
+
     my $f_class_loaded = eval { $f_class->columns };
     my ($f_key,$guess);
     if (defined $cond && length $cond) {
index e294a8c..d8d50de 100644 (file)
@@ -6,6 +6,15 @@ use warnings;
 
 sub many_to_many {
   my ($class, $meth, $rel, $f_rel, $rel_attrs) = @_;
+
+  $class->throw_exception(
+    "missing relation in many-to-many"
+  ) unless $rel;
+
+  $class->throw_exception(
+    "missing foreign relation in many-to-many"
+  ) unless $f_rel;
+
   {
     no strict 'refs';
     no warnings 'redefine';
diff --git a/lib/DBIx/Class/ResultClass/HashRefInflator.pm b/lib/DBIx/Class/ResultClass/HashRefInflator.pm
new file mode 100644 (file)
index 0000000..ca6741e
--- /dev/null
@@ -0,0 +1,76 @@
+package DBIx::Class::ResultClass::HashRefInflator;
+
+=head1 NAME
+
+DBIx::Class::ResultClass::HashRefInflator
+
+=head1 SYNOPSIS
+
+ my $rs = $schema->resultset('CD');
+
+ $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
+
+=head1 DESCRIPTION
+
+DBIx::Class is not built for speed: it's built for convenience and
+ease of use. But sometimes you just need to get the data, and skip the
+fancy objects. That is what this class provides.
+
+There are two ways of using this class.
+
+=over
+
+=item *
+
+Specify C<< $rs->result_class >> on a specific resultset to affect only that
+resultser (and any chained off of it); or
+
+=item *
+
+Specify C<< __PACKAGE__->result_class >> on your source object to force all
+uses of that result source to be inflated to hash-refs - this approach is not
+recomended
+
+=back
+
+=head1 METHODS
+
+=head2 inflate_result
+
+Inflates the result and prefetched data into a hash-ref using L<mk_hash>.
+
+=cut
+
+sub inflate_result {
+    my ($self, $source, $me, $prefetch) = @_;
+
+    return mk_hash($me, $prefetch);
+}
+
+=head2 mk_hash
+
+This does all the work of inflating the (pre)fetched data.
+
+=cut
+
+sub mk_hash {
+    my ($me, $rest) = @_;
+
+    # $me is the hashref of cols/data from the immediate resultsource
+    # $rest is a deep hashref of all the data from the prefetched
+    # related sources.
+
+    # to avoid emtpy has_many rels contain one empty hashref
+    return if (not keys %$me);
+
+    return { %$me,
+        map {
+          ( $_ =>
+             ref($rest->{$_}[0]) eq 'ARRAY' ? [ map { mk_hash(@$_) } @{$rest->{$_}} ]
+                                            : mk_hash( @{$rest->{$_}} )
+          )
+        } keys %$rest
+    };
+}
+
+1;
index 63b9006..d51c4b9 100644 (file)
@@ -10,10 +10,10 @@ use Carp::Clan qw/^DBIx::Class/;
 use Data::Page;
 use Storable;
 use DBIx::Class::ResultSetColumn;
+use DBIx::Class::ResultSourceHandle;
 use base qw/DBIx::Class/;
 
-__PACKAGE__->load_components(qw/AccessorGroup/);
-__PACKAGE__->mk_group_accessors('simple' => qw/result_source result_class/);
+__PACKAGE__->mk_group_accessors('simple' => qw/result_class _source_handle/);
 
 =head1 NAME
 
@@ -85,7 +85,9 @@ sub new {
   return $class->new_result(@_) if ref $class;
 
   my ($source, $attrs) = @_;
-  #weaken $source;
+  $source = $source->handle 
+    unless $source->isa('DBIx::Class::ResultSourceHandle');
+  $attrs = { %{$attrs||{}} };
 
   if ($attrs->{page}) {
     $attrs->{rows} ||= 10;
@@ -96,8 +98,8 @@ sub new {
   $attrs->{alias} ||= 'me';
 
   my $self = {
-    result_source => $source,
-    result_class => $attrs->{result_class} || $source->result_class,
+    _source_handle => $source,
+    result_class => $attrs->{result_class} || $source->resolve->result_class,
     cond => $attrs->{where},
     count => undef,
     pager => undef,
@@ -238,7 +240,7 @@ sub search_rs {
         : $having);
   }
 
-  my $rs = (ref $self)->new($self->result_source, $new_attrs);
+  my $rs = (ref $self)->new($self->_source_handle, $new_attrs);
   if ($rows) {
     $rs->set_cache($rows);
   }
@@ -343,6 +345,22 @@ sub find {
     $input_query = {@_};
   }
 
+  my (%related, $info);
+
+  foreach my $key (keys %$input_query) {
+    if (ref($input_query->{$key})
+        && ($info = $self->result_source->relationship_info($key))) {
+      my $rel_q = $self->result_source->resolve_condition(
+                    $info->{cond}, delete $input_query->{$key}, $key
+                  );
+      die "Can't handle OR join condition in find" if ref($rel_q) eq 'ARRAY';
+      @related{keys %$rel_q} = values %$rel_q;
+    }
+  }
+  if (my @keys = keys %related) {
+    @{$input_query}{@keys} = values %related;
+  }
+
   my @unique_queries = $self->_unique_queries($input_query, $attrs);
 
   # Build the final query: Default to the disjunction of the unique queries,
@@ -392,21 +410,23 @@ sub _unique_queries {
     ? ($attrs->{key})
     : $self->result_source->unique_constraint_names;
 
+  my $where = $self->_collapse_cond($self->{attrs}{where} || {});
+  my $num_where = scalar keys %$where;
+
   my @unique_queries;
   foreach my $name (@constraint_names) {
     my @unique_cols = $self->result_source->unique_constraint_columns($name);
     my $unique_query = $self->_build_unique_query($query, \@unique_cols);
 
+    my $num_cols = scalar @unique_cols;
     my $num_query = scalar keys %$unique_query;
-    next unless $num_query;
 
-    # XXX: Assuming quite a bit about $self->{attrs}{where}
-    my $num_cols = scalar @unique_cols;
-    my $num_where = exists $self->{attrs}{where}
-      ? scalar keys %{ $self->{attrs}{where} }
-      : 0;
-    push @unique_queries, $unique_query
-      if $num_query + $num_where == $num_cols;
+    my $total = $num_query + $num_where;
+    if ($num_query && ($num_query == $num_cols || $total == $num_cols)) {
+      # The query is either unique on its own or is unique in combination with
+      # the existing where clause
+      push @unique_queries, $unique_query;
+    }
   }
 
   return @unique_queries;
@@ -520,7 +540,7 @@ sub single {
     $attrs->{where}, $attrs
   );
 
-  return (@data ? $self->_construct_object(@data) : ());
+  return (@data ? ($self->_construct_object(@data))[0] : ());
 }
 
 # _is_unique_query
@@ -705,22 +725,29 @@ sub next {
     $self->{all_cache_position} = 1;
     return ($self->all)[0];
   }
+  if ($self->{stashed_objects}) {
+    my $obj = shift(@{$self->{stashed_objects}});
+    delete $self->{stashed_objects} unless @{$self->{stashed_objects}};
+    return $obj;
+  }
   my @row = (
     exists $self->{stashed_row}
       ? @{delete $self->{stashed_row}}
       : $self->cursor->next
   );
   return unless (@row);
-  return $self->_construct_object(@row);
+  my ($row, @more) = $self->_construct_object(@row);
+  $self->{stashed_objects} = \@more if @more;
+  return $row;
 }
 
 sub _construct_object {
   my ($self, @row) = @_;
   my $info = $self->_collapse_result($self->{_attrs}{as}, \@row);
-  my $new = $self->result_class->inflate_result($self->result_source, @$info);
-  $new = $self->{_attrs}{record_filter}->($new)
+  my @new = $self->result_class->inflate_result($self->_source_handle, @$info);
+  @new = $self->{_attrs}{record_filter}->(@new)
     if exists $self->{_attrs}{record_filter};
-  return $new;
+  return @new;
 }
 
 sub _collapse_result {
@@ -893,7 +920,7 @@ sub _count { # Separated out so pager can get the full count
   # offset, order by and page are not needed to count. record_filter is cdbi
   delete $attrs->{$_} for qw/rows offset order_by page pager record_filter/;
 
-  my $tmp_rs = (ref $self)->new($self->result_source, $attrs);
+  my $tmp_rs = (ref $self)->new($self->_source_handle, $attrs);
   my ($count) = $tmp_rs->cursor->next;
   return $count;
 }
@@ -1084,9 +1111,9 @@ sub update {
     unless ref $values eq 'HASH';
 
   my $cond = $self->_cond_for_update_delete;
-
+   
   return $self->result_source->storage->update(
-    $self->result_source->from, $values, $cond
+    $self->result_source, $values, $cond
   );
 }
 
@@ -1136,7 +1163,7 @@ sub delete {
 
   my $cond = $self->_cond_for_update_delete;
 
-  $self->result_source->storage->delete($self->result_source->from, $cond);
+  $self->result_source->storage->delete($self->result_source, $cond);
   return 1;
 }
 
@@ -1204,7 +1231,7 @@ attribute set on the resultset (10 by default).
 
 sub page {
   my ($self, $page) = @_;
-  return (ref $self)->new($self->result_source, { %{$self->{attrs}}, page => $page });
+  return (ref $self)->new($self->_source_handle, { %{$self->{attrs}}, page => $page });
 }
 
 =head2 new_result
@@ -1236,9 +1263,7 @@ sub new_result {
     %{ $self->_remove_alias($collapsed_cond, $alias) },
   );
 
-  my $obj = $self->result_class->new(\%new);
-  $obj->result_source($self->result_source) if $obj->can('result_source');
-  return $obj;
+  return $self->result_class->new(\%new,$self->_source_handle);
 }
 
 # _collapse_cond
@@ -1284,9 +1309,15 @@ sub _collapse_cond {
 sub _remove_alias {
   my ($self, $query, $alias) = @_;
 
-  my %unaliased = %{ $query || {} };
-  foreach my $key (keys %unaliased) {
-    $unaliased{$1} = delete $unaliased{$key}
+  my %orig = %{ $query || {} };
+  my %unaliased;
+
+  foreach my $key (keys %orig) {
+    if ($key !~ /\./) {
+      $unaliased{$key} = $orig{$key};
+      next;
+    }
+    $unaliased{$1} = $orig{$key}
       if $key =~ m/^(?:\Q$alias\E\.)?([^.]+)$/;
   }
 
@@ -1526,7 +1557,7 @@ sub related_resultset {
     my $rel_obj = $self->result_source->relationship_info($rel);
 
     $self->throw_exception(
-      "search_related: result source '" . $self->result_source->name .
+      "search_related: result source '" . $self->_source_handle->source_moniker .
         "' has no such relationship $rel")
       unless $rel_obj;
     
@@ -1535,7 +1566,7 @@ sub related_resultset {
     my $join_count = $seen->{$rel};
     my $alias = ($join_count > 1 ? join('_', $rel, $join_count) : $rel);
 
-    $self->result_source->schema->resultset($rel_obj->{class})->search_rs(
+    $self->_source_handle->schema->resultset($rel_obj->{class})->search_rs(
       undef, {
         %{$self->{attrs}||{}},
         join => undef,
@@ -1576,7 +1607,7 @@ sub _resolved_attrs {
   return $self->{_attrs} if $self->{_attrs};
 
   my $attrs = { %{$self->{attrs}||{}} };
-  my $source = $self->{result_source};
+  my $source = $self->result_source;
   my $alias = $attrs->{alias};
 
   $attrs->{columns} ||= delete $attrs->{cols} if exists $attrs->{cols};
@@ -1708,6 +1739,16 @@ sub _merge_attr {
   }
 }
 
+sub result_source {
+    my $self = shift;
+
+    if (@_) {
+        $self->_source_handle($_[0]->handle);
+    } else {
+        $self->_source_handle->resolve;
+    }
+}
+
 =head2 throw_exception
 
 See L<DBIx::Class::Schema/throw_exception> for details.
@@ -1716,7 +1757,7 @@ See L<DBIx::Class::Schema/throw_exception> for details.
 
 sub throw_exception {
   my $self=shift;
-  $self->result_source->schema->throw_exception(@_);
+  $self->_source_handle->schema->throw_exception(@_);
 }
 
 # XXX: FIXME: Attributes docs need clearing up
index 49b8456..876a3c1 100644 (file)
@@ -35,12 +35,8 @@ passed as params. Used internally by L<DBIx::Class::ResultSet/get_column>.
 sub new {
   my ($class, $rs, $column) = @_;
   $class = ref $class if ref $class;
-
-  my $object_ref = { _column => $column,
-                    _parent_resultset => $rs };
-  
-  my $new = bless $object_ref, $class;
-  $new->throw_exception("column must be supplied") unless ($column);
+  my $new = bless { _column => $column, _parent_resultset => $rs }, $class;
+  $new->throw_exception("column must be supplied") unless $column;
   return $new;
 }
 
@@ -64,7 +60,6 @@ one value.
 
 sub next {
   my $self = shift;
-    
   $self->{_resultset} = $self->{_parent_resultset}->search(undef, {select => [$self->{_column}], as => [$self->{_column}]}) unless ($self->{_resultset});
   my ($row) = $self->{_resultset}->cursor->next;
   return $row;
@@ -111,8 +106,7 @@ resultset (or C<undef> if there are none).
 =cut
 
 sub min {
-  my $self = shift;
-  return $self->func('MIN');
+  return shift->func('MIN');
 }
 
 =head2 max
@@ -133,8 +127,7 @@ resultset (or C<undef> if there are none).
 =cut
 
 sub max {
-  my $self = shift;
-  return $self->func('MAX');
+  return shift->func('MAX');
 }
 
 =head2 sum
@@ -155,8 +148,7 @@ the resultset. Use on varchar-like columns at your own risk.
 =cut
 
 sub sum {
-  my $self = shift;
-  return $self->func('SUM');
+  return shift->func('SUM');
 }
 
 =head2 func
@@ -180,9 +172,7 @@ value. Produces the following SQL:
 =cut
 
 sub func {
-  my $self = shift;
-  my $function = shift;
-
+  my ($self,$function) = @_;
   my ($row) = $self->{_parent_resultset}->search(undef, {select => {$function => $self->{_column}}, as => [$self->{_column}]})->cursor->next;
   return $row;
 }
index 46aa406..78461c9 100644 (file)
@@ -13,7 +13,6 @@ classes (EXPERIMENTAL)
 
   # in a table class
   __PACKAGE__->load_components(qw/ResultSetManager Core/); # note order!
-  __PACKAGE__->load_resultset_components(qw/AlwaysRS/);
 
   # will be removed from the table class and inserted into a
   # table-specific resultset class
@@ -68,10 +67,6 @@ sub table {
 
 =head2 load_resultset_components
 
-  # in a table class
-  __PACKAGE__->load_components(qw/ResultSetManager Core/); # note order!
-  __PACKAGE__->load_resultset_components(qw/AlwaysRS/);
-
 C<load_resultset_components> loads components in addition to
 C<DBIx::Class::ResultSet> (or whatever you set as
 C<base_resultset_class>).
index 14bc4f8..e3c2b80 100644 (file)
@@ -4,20 +4,21 @@ use strict;
 use warnings;
 
 use DBIx::Class::ResultSet;
+use DBIx::Class::ResultSourceHandle;
 use Carp::Clan qw/^DBIx::Class/;
 use Storable;
 
 use base qw/DBIx::Class/;
-__PACKAGE__->load_components(qw/AccessorGroup/);
 
 __PACKAGE__->mk_group_accessors('simple' => qw/_ordered_columns
   _columns _primaries _unique_constraints name resultset_attributes
-  schema from _relationships column_info_from_storage source_name
-  source_info/);
+  schema from _relationships column_info_from_storage source_info/);
 
-__PACKAGE__->mk_group_accessors('component_class' => qw/resultset_class
+__PACKAGE__->mk_group_accessors('inherited' => qw/resultset_class
   result_class/);
 
+__PACKAGE__->mk_group_ro_accessors('simple' => qw/source_name/);
+
 =head1 NAME
 
 DBIx::Class::ResultSource - Result source object
@@ -47,9 +48,7 @@ sub new {
   my ($class, $attrs) = @_;
   $class = ref $class if ref $class;
 
-  my $new = { %{$attrs || {}}, _resultset => undef };
-  bless $new, $class;
-
+  my $new = bless { %{$attrs || {}} }, $class;
   $new->{resultset_class} ||= 'DBIx::Class::ResultSet';
   $new->{resultset_attributes} = { %{$new->{resultset_attributes} || {}} };
   $new->{_ordered_columns} = [ @{$new->{_ordered_columns}||[]}];
@@ -108,29 +107,31 @@ whatever your database supports.
 =item size
 
 The length of your column, if it is a column type that can have a size
-restriction. This is currently not used by DBIx::Class.
+restriction. This is currently only used by L<DBIx::Class::Schema/deploy>.
 
 =item is_nullable
 
 Set this to a true value for a columns that is allowed to contain
-NULL values. This is currently not used by DBIx::Class.
+NULL values. This is currently only used by L<DBIx::Class::Schema/deploy>.
 
 =item is_auto_increment
 
 Set this to a true value for a column whose value is somehow
 automatically set. This is used to determine which columns to empty
-when cloning objects using C<copy>.
+when cloning objects using C<copy>. It is also used by
+L<DBIx::Class::Schema/deploy>.
 
 =item is_foreign_key
 
 Set this to a true value for a column that contains a key from a
-foreign table. This is currently not used by DBIx::Class.
+foreign table. This is currently only used by
+L<DBIx::Class::Schema/deploy>.
 
 =item default_value
 
 Set this to the default value which will be inserted into a column
 by the database. Can contain either a value or a function. This is
-currently not used by DBIx::Class.
+currently only used by L<DBIx::Class::Schema/deploy>.
 
 =item sequence
 
@@ -139,6 +140,14 @@ generate a new key value. If not specified, L<DBIx::Class::PK::Auto>
 will attempt to retrieve the name of the sequence from the database
 automatically.
 
+=item extras
+
+This is used by L<DBIx::Class::Schema/deploy> and L<SQL::Translator>
+to add extra non-generic data to the column. For example: C<< extras
+=> { unsigned => 1} >> is used by the MySQL producer to set an integer
+column to unsigned. For more details, see
+L<SQL::Translator::Producer::MySQL>.
+
 =back
 
 =head2 add_column
@@ -201,8 +210,8 @@ sub column_info {
        and $self->schema and $self->storage )
   {
     $self->{_columns_info_loaded}++;
-    my $info;
-    my $lc_info;
+    my $info = {};
+    my $lc_info = {};
     # eval for the case of storage without table
     eval { $info = $self->storage->columns_info_for( $self->from ) };
     unless ($@) {
@@ -210,7 +219,10 @@ sub column_info {
         $lc_info->{lc $realcol} = $info->{$realcol};
       }
       foreach my $col ( keys %{$self->_columns} ) {
-        $self->_columns->{$col} = { %{ $self->_columns->{$col}}, %{$info->{$col} || $lc_info->{lc $col}} };
+        $self->_columns->{$col} = {
+          %{ $self->_columns->{$col} },
+          %{ $info->{$col} || $lc_info->{lc $col} || {} }
+        };
       }
     }
   }
@@ -931,12 +943,20 @@ but is cached from then on unless resultset_class changes.
 
 =head2 resultset_class
 
+` package My::ResultSetClass;
+  use base 'DBIx::Class::ResultSet';
+  ...
+
+  $source->resultset_class('My::ResultSet::Class');
+
 Set the class of the resultset, this is useful if you want to create your
 own resultset methods. Create your own class derived from
-L<DBIx::Class::ResultSet>, and set it here.
+L<DBIx::Class::ResultSet>, and set it here. 
 
 =head2 resultset_attributes
 
+  $source->resultset_attributes({ order_by => [ 'id' ] });
+
 Specify here any attributes you wish to pass to your specialised resultset.
 
 =cut
@@ -948,12 +968,6 @@ sub resultset {
     'call it on the schema instead.'
   ) if scalar @_;
 
-  # disabled until we can figure out a way to do it without consistency issues
-  #
-  #return $self->{_resultset}
-  #  if ref $self->{_resultset} eq $self->resultset_class;
-  #return $self->{_resultset} =
-
   return $self->resultset_class->new(
     $self, $self->{resultset_attributes}
   );
@@ -979,6 +993,20 @@ its class name.
   # from your schema...
   $schema->resultset('Books')->find(1);
 
+=head2 handle
+
+Obtain a new handle to this source. Returns an instance of a 
+L<DBIx::Class::ResultSourceHandle>.
+
+=cut
+
+sub handle {
+    return new DBIx::Class::ResultSourceHandle({
+        schema         => $_[0]->schema,
+        source_moniker => $_[0]->source_name
+    });
+}
+
 =head2 throw_exception
 
 See L<DBIx::Class::Schema/"throw_exception">.
diff --git a/lib/DBIx/Class/ResultSourceHandle.pm b/lib/DBIx/Class/ResultSourceHandle.pm
new file mode 100644 (file)
index 0000000..60118b8
--- /dev/null
@@ -0,0 +1,76 @@
+package DBIx::Class::ResultSourceHandle;
+
+use strict;
+use warnings;
+use Storable;
+
+use base qw/DBIx::Class/;
+
+use overload
+    q/""/ => sub { __PACKAGE__ . ":" . shift->source_moniker; },
+    fallback => 1;
+
+__PACKAGE__->mk_group_accessors('simple' => qw/schema source_moniker/);
+
+=head1 NAME
+
+DBIx::Class::ResultSourceHandle
+
+=head1 DESCRIPTION
+
+This module removes fixed link between Rows/ResultSets and the actual source
+objects, which gets round the following problems
+
+=over 4
+
+=item *
+
+Needing to keep C<$schema> in scope, since any objects/result_sets
+will have a C<$schema> object through their source handle
+
+=item *
+
+Large output when using Data::Dump(er) since this class can be set to
+stringify to almost nothing
+
+=item *
+
+Closer to being aboe to do a Serialize::Storable that doesn't require class-based connections
+
+=back
+
+=head1 METHODS
+
+=head2 new
+
+=cut
+
+sub new {
+    my ($class, $data) = @_;
+
+    $class = ref $class if ref $class;
+
+    bless $data, $class;
+}
+
+=head2 resolve
+
+Resolve the moniker into the actual ResultSource object
+
+=cut
+
+sub resolve { return $_[0]->schema->source($_[0]->source_moniker) }
+
+sub STORABLE_freeze {
+    my ($self, $cloning) = @_;
+    my $to_serialize = { %$self };
+    delete $to_serialize->{schema};
+    return (Storable::freeze($to_serialize));
+}
+
+sub STORABLE_thaw {
+    my ($self, $cloning,$ice) = @_;
+    %$self = %{ Storable::thaw($ice) };
+}
+
+1;
index b596e5c..696c9a5 100644 (file)
@@ -5,13 +5,29 @@ use strict;
 use warnings;
 
 use base qw/DBIx::Class/;
+use Scalar::Util qw/blessed/;
+use Carp::Clan qw/^DBIx::Class/;
 
 sub iterator_class  { shift->result_source_instance->resultset_class(@_) }
 sub resultset_class { shift->result_source_instance->resultset_class(@_) }
 sub result_class { shift->result_source_instance->result_class(@_) }
-sub source_name { shift->result_source_instance->source_name(@_) }
 sub source_info { shift->result_source_instance->source_info(@_) }
 
+sub set_inherited_ro_instance {
+    my $self = shift;
+
+    croak "Cannot set @{[shift]} on an instance" if blessed $self;
+
+    return $self->set_inherited(@_);
+}
+
+sub get_inherited_ro_instance {
+    return shift->get_inherited(@_);
+}
+
+__PACKAGE__->mk_group_accessors('inherited_ro_instance' => 'source_name');
+
+
 sub resultset_attributes {
   shift->result_source_instance->resultset_attributes(@_);
 }
index f70f2bc..ce78cb8 100644 (file)
@@ -4,10 +4,10 @@ use strict;
 use warnings;
 
 use base qw/DBIx::Class::ResultSourceProxy/;
-__PACKAGE__->load_components(qw/AccessorGroup/);
 
-__PACKAGE__->mk_group_accessors('component_class' => 'table_class');
-__PACKAGE__->table_class('DBIx::Class::ResultSource::Table');
+use DBIx::Class::ResultSource::Table;
+
+__PACKAGE__->mk_classdata(table_class => 'DBIx::Class::ResultSource::Table');
 
 __PACKAGE__->mk_classdata('table_alias'); # FIXME: Doesn't actually do
                                           # anything yet!
@@ -53,7 +53,12 @@ sub table {
         source_name => undef,
     });
   }
-  $class->mk_classdata('result_source_instance' => $table);
+
+  $class->mk_classdata('result_source_instance')
+    unless $class->can('result_source_instance');
+
+  $class->result_source_instance($table);
+
   if ($class->can('schema_instance')) {
     $class =~ m/([^:]+)$/;
     $class->schema_instance->register_class($class, $class);
index 60250b6..d66beb1 100644 (file)
@@ -6,9 +6,7 @@ use warnings;
 use base qw/DBIx::Class/;
 use Carp::Clan qw/^DBIx::Class/;
 
-__PACKAGE__->load_components(qw/AccessorGroup/);
-
-__PACKAGE__->mk_group_accessors('simple' => 'result_source');
+__PACKAGE__->mk_group_accessors('simple' => qw/_source_handle/);
 
 =head1 NAME
 
@@ -32,20 +30,46 @@ Creates a new row object from column => value mappings passed as a hash ref
 =cut
 
 sub new {
-  my ($class, $attrs) = @_;
+  my ($class, $attrs, $source) = @_;
   $class = ref $class if ref $class;
 
   my $new = { _column_data => {} };
   bless $new, $class;
 
+  $new->_source_handle($source) if $source;
+
   if ($attrs) {
     $new->throw_exception("attrs must be a hashref")
       unless ref($attrs) eq 'HASH';
-    foreach my $k (keys %$attrs) {
-      $new->throw_exception("No such column $k on $class")
-        unless $class->has_column($k);
-      $new->store_column($k => $attrs->{$k});
+    
+    my ($related,$inflated);
+    foreach my $key (keys %$attrs) {
+      if (ref $attrs->{$key}) {
+        my $info = $class->relationship_info($key);
+        if ($info && $info->{attrs}{accessor}
+          && $info->{attrs}{accessor} eq 'single')
+        {
+          $new->set_from_related($key, $attrs->{$key});        
+          $related->{$key} = $attrs->{$key};
+          next;
+        }
+        elsif ($class->has_column($key)
+          && exists $class->column_info($key)->{_inflate_info})
+        {
+          $inflated->{$key} = $attrs->{$key};
+          next;
+        }
+      }
+      $new->throw_exception("No such column $key on $class")
+        unless $class->has_column($key);
+      $new->store_column($key => $attrs->{$key});          
     }
+    if (my $source = delete $attrs->{-result_source}) {
+      $new->result_source($source);
+    }
+
+    $new->{_relationship_data} = $related if $related;
+    $new->{_inflated_column} = $inflated if $inflated;
   }
 
   return $new;
@@ -66,16 +90,17 @@ L<DBIx::Class::ResultSet/create>).
 sub insert {
   my ($self) = @_;
   return $self if $self->in_storage;
-  $self->{result_source} ||= $self->result_source_instance
+  my $source = $self->result_source;
+  $source ||=  $self->result_source($self->result_source_instance)
     if $self->can('result_source_instance');
-  my $source = $self->{result_source};
   $self->throw_exception("No result_source set on this object; can't insert")
     unless $source;
-  #use Data::Dumper; warn Dumper($self);
-  $source->storage->insert($source->from, { $self->get_columns });
+
+  $source->storage->insert($source, { $self->get_columns });
   $self->in_storage(1);
   $self->{_dirty_columns} = {};
   $self->{related_resultsets} = {};
+  undef $self->{_orig_ident};
   return $self;
 }
 
@@ -107,14 +132,36 @@ required.
 sub update {
   my ($self, $upd) = @_;
   $self->throw_exception( "Not in database" ) unless $self->in_storage;
-  $self->set_columns($upd) if $upd;
-  my %to_update = $self->get_dirty_columns;
-  return $self unless keys %to_update;
   my $ident_cond = $self->ident_condition;
   $self->throw_exception("Cannot safely update a row in a PK-less table")
     if ! keys %$ident_cond;
+
+  if ($upd) {
+    foreach my $key (keys %$upd) {
+      if (ref $upd->{$key}) {
+        my $info = $self->relationship_info($key);
+        if ($info && $info->{attrs}{accessor}
+          && $info->{attrs}{accessor} eq 'single')
+        {
+          my $rel = delete $upd->{$key};
+          $self->set_from_related($key => $rel);
+          $self->{_relationship_data}{$key} = $rel;          
+        } 
+        elsif ($self->has_column($key)
+          && exists $self->column_info($key)->{_inflate_info})
+        {
+          $self->set_inflated_column($key, delete $upd->{$key});          
+        }
+      }
+    }
+    $self->set_columns($upd);    
+  }
+  my %to_update = $self->get_dirty_columns;
+  return $self unless keys %to_update;
   my $rows = $self->result_source->storage->update(
-               $self->result_source->from, \%to_update, $ident_cond);
+               $self->result_source, \%to_update,
+               $self->{_orig_ident} || $ident_cond
+             );
   if ($rows == 0) {
     $self->throw_exception( "Can't update ${self}: row not found" );
   } elsif ($rows > 1) {
@@ -122,6 +169,7 @@ sub update {
   }
   $self->{_dirty_columns} = {};
   $self->{related_resultsets} = {};
+  undef $self->{_orig_ident};
   return $self;
 }
 
@@ -130,8 +178,8 @@ sub update {
   $obj->delete
 
 Deletes the object from the database. The object is still perfectly
-usable, but C<-E<gt>in_storage()> will now return 0 and the object must
-reinserted using C<-E<gt>insert()> before C<-E(<gt>update()> can be used
+usable, but C<< ->in_storage() >> will now return 0 and the object must
+reinserted using C<< ->insert() >> before C<< ->update() >> can be used
 on it. If you delete an object in a class with a C<has_many>
 relationship, all the related objects will be deleted as well. To turn
 this behavior off, pass C<cascade_delete => 0> in the C<$attr>
@@ -152,7 +200,7 @@ sub delete {
               unless exists $self->{_column_data}{$column};
     }
     $self->result_source->storage->delete(
-      $self->result_source->from, $ident_cond);
+      $self->result_source, $ident_cond);
     $self->in_storage(undef);
   } else {
     $self->throw_exception("Can't do class delete without a ResultSource instance")
@@ -168,9 +216,10 @@ sub delete {
 
   my $val = $obj->get_column($col);
 
-Gets a column value from a row object. Currently, does not do
-any queries; the column must have already been fetched from
-the database and stored in the object.
+Gets a column value from a row object. Does not do any queries; the column 
+must have already been fetched from the database and stored in the object. If 
+there is an inflated value stored that has not yet been deflated, it is deflated
+when the method is invoked.
 
 =cut
 
@@ -178,6 +227,10 @@ sub get_column {
   my ($self, $column) = @_;
   $self->throw_exception( "Can't fetch data as class method" ) unless ref $self;
   return $self->{_column_data}{$column} if exists $self->{_column_data}{$column};
+  if (exists $self->{_inflated_column}{$column}) {
+    return $self->store_column($column,
+      $self->_deflated_column($column, $self->{_inflated_column}{$column}));   
+  }
   $self->throw_exception( "No such column '${column}'" ) unless $self->has_column($column);
   return undef;
 }
@@ -196,6 +249,7 @@ database (or set locally).
 sub has_column_loaded {
   my ($self, $column) = @_;
   $self->throw_exception( "Can't call has_column data as class method" ) unless ref $self;
+  return 1 if exists $self->{_inflated_column}{$column};
   return exists $self->{_column_data}{$column};
 }
 
@@ -209,6 +263,12 @@ Does C<get_column>, for all column values at once.
 
 sub get_columns {
   my $self = shift;
+  if (exists $self->{_inflated_column}) {
+    foreach my $col (keys %{$self->{_inflated_column}}) {
+      $self->store_column($col, $self->_deflated_column($col, $self->{_inflated_column}{$col}))
+        unless exists $self->{_column_data}{$col};
+    }
+  }
   return %{$self->{_column_data}};
 }
 
@@ -238,6 +298,7 @@ the column is marked as dirty for when you next call $obj->update.
 sub set_column {
   my $self = shift;
   my ($column) = @_;
+  $self->{_orig_ident} ||= $self->ident_condition;
   my $old = $self->get_column($column);
   my $ret = $self->store_column(@_);
   $self->{_dirty_columns}{$column} = 1
@@ -324,9 +385,17 @@ Called by ResultSet to inflate a result from storage
 
 sub inflate_result {
   my ($class, $source, $me, $prefetch) = @_;
-  #use Data::Dumper; print Dumper(@_);
+
+  my ($source_handle) = $source;
+
+  if ($source->isa('DBIx::Class::ResultSourceHandle')) {
+      $source = $source_handle->resolve
+  } else {
+      $source_handle = $source->handle
+  }
+
   my $new = {
-    result_source => $source,
+    _source_handle => $source_handle,
     _column_data => $me,
     _in_storage => 1
   };
@@ -426,6 +495,18 @@ sub is_column_changed {
 
 Accessor to the ResultSource this object was created from
 
+=cut
+
+sub result_source {
+    my $self = shift;
+
+    if (@_) {
+        $self->_source_handle($_[0]->handle);
+    } else {
+        $self->_source_handle->resolve;
+    }
+}
+
 =head2 register_column
 
   $column_info = { .... };
index ff30b53..4478d6f 100644 (file)
@@ -5,6 +5,7 @@ use warnings;
 
 use Carp::Clan qw/^DBIx::Class/;
 use Scalar::Util qw/weaken/;
+use File::Spec;
 require Module::Find;
 
 use base qw/DBIx::Class/;
@@ -93,10 +94,15 @@ moniker.
 
 sub register_source {
   my ($self, $moniker, $source) = @_;
+
+  %$source = %{ $source->new( { %$source, source_name => $moniker }) };
+
   my %reg = %{$self->source_registrations};
   $reg{$moniker} = $source;
   $self->source_registrations(\%reg);
+
   $source->schema($self);
+
   weaken($source->{schema}) if ref($self);
   if ($source->result_class) {
     my %map = %{$self->class_mappings};
@@ -105,6 +111,19 @@ sub register_source {
   }
 }
 
+sub _unregister_source {
+    my ($self, $moniker) = @_;
+    my %reg = %{$self->source_registrations}; 
+
+    my $source = delete $reg{$moniker};
+    $self->source_registrations(\%reg);
+    if ($source->result_class) {
+        my %map = %{$self->class_mappings};
+        delete $map{$source->result_class};
+        $self->class_mappings(\%map);
+    }
+}
+
 =head2 class
 
 =over 4
@@ -267,10 +286,18 @@ sub load_classes {
     foreach my $prefix (keys %comps_for) {
       foreach my $comp (@{$comps_for{$prefix}||[]}) {
         my $comp_class = "${prefix}::${comp}";
+        { # try to untaint module name. mods where this fails
+          # are left alone so we don't have to change the old behavior
+          no locale; # localized \w doesn't untaint expression
+          if ( $comp_class =~ m/^( (?:\w+::)* \w+ )$/x ) {
+            $comp_class = $1;
+          }
+        }
         $class->ensure_class_loaded($comp_class);
-        $comp_class->source_name($comp) unless $comp_class->source_name;
 
-        push(@to_register, [ $comp_class->source_name, $comp_class ]);
+        $comp = $comp_class->source_name || $comp;
+#  $DB::single = 1;
+        push(@to_register, [ $comp, $comp_class ]);
       }
     }
   }
@@ -440,7 +467,7 @@ sub load_namespaces {
   return;
 }
 
-=head2 compose_connection
+=head2 compose_connection (DEPRECATED)
 
 =over 4
 
@@ -450,6 +477,12 @@ sub load_namespaces {
 
 =back
 
+DEPRECATED. You probably wanted compose_namespace.
+
+Actually, you probably just wanted to call connect.
+
+=for hidden due to deprecation
+
 Calls L<DBIx::Class::Schema/"compose_namespace"> to the target namespace,
 calls L<DBIx::Class::Schema/connection> with @db_info on the new schema,
 then injects the L<DBix::Class::ResultSetProxy> component and a
@@ -464,43 +497,50 @@ more information.
 
 =cut
 
-sub compose_connection {
-  my ($self, $target, @info) = @_;
-  my $base = 'DBIx::Class::ResultSetProxy';
-  eval "require ${base};";
-  $self->throw_exception
-    ("No arguments to load_classes and couldn't load ${base} ($@)")
-      if $@;
-
-  if ($self eq $target) {
-    # Pathological case, largely caused by the docs on early C::M::DBIC::Plain
-    foreach my $moniker ($self->sources) {
-      my $source = $self->source($moniker);
+{
+  my $warn;
+
+  sub compose_connection {
+    my ($self, $target, @info) = @_;
+
+    warn "compose_connection deprecated as of 0.08000" unless $warn++;
+
+    my $base = 'DBIx::Class::ResultSetProxy';
+    eval "require ${base};";
+    $self->throw_exception
+      ("No arguments to load_classes and couldn't load ${base} ($@)")
+        if $@;
+  
+    if ($self eq $target) {
+      # Pathological case, largely caused by the docs on early C::M::DBIC::Plain
+      foreach my $moniker ($self->sources) {
+        my $source = $self->source($moniker);
+        my $class = $source->result_class;
+        $self->inject_base($class, $base);
+        $class->mk_classdata(resultset_instance => $source->resultset);
+        $class->mk_classdata(class_resolver => $self);
+      }
+      $self->connection(@info);
+      return $self;
+    }
+  
+    my $schema = $self->compose_namespace($target, $base);
+    {
+      no strict 'refs';
+      *{"${target}::schema"} = sub { $schema };
+    }
+  
+    $schema->connection(@info);
+    foreach my $moniker ($schema->sources) {
+      my $source = $schema->source($moniker);
       my $class = $source->result_class;
-      $self->inject_base($class, $base);
+      #warn "$moniker $class $source ".$source->storage;
+      $class->mk_classdata(result_source_instance => $source);
       $class->mk_classdata(resultset_instance => $source->resultset);
-      $class->mk_classdata(class_resolver => $self);
+      $class->mk_classdata(class_resolver => $schema);
     }
-    $self->connection(@info);
-    return $self;
-  }
-
-  my $schema = $self->compose_namespace($target, $base);
-  {
-    no strict 'refs';
-    *{"${target}::schema"} = sub { $schema };
-  }
-
-  $schema->connection(@info);
-  foreach my $moniker ($schema->sources) {
-    my $source = $schema->source($moniker);
-    my $class = $source->result_class;
-    #warn "$moniker $class $source ".$source->storage;
-    $class->mk_classdata(result_source_instance => $source);
-    $class->mk_classdata(resultset_instance => $source->resultset);
-    $class->mk_classdata(class_resolver => $schema);
+    return $schema;
   }
-  return $schema;
 }
 
 =head2 compose_namespace
@@ -639,6 +679,7 @@ sub connection {
   my $storage = $storage_class->new($self);
   $storage->connect_info(\@info);
   $self->storage($storage);
+  $self->on_connect() if($self->can('on_connect'));
   return $self;
 }
 
@@ -778,7 +819,12 @@ Pass this method a resultsource name, and an arrayref of
 arrayrefs. The arrayrefs should contain a list of column names,
 followed by one or many sets of matching data for the given columns. 
 
-Each set of data is inserted into the database using
+In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
+to insert the data, as this is a fast method. However, insert_bulk currently
+assumes that your datasets all contain the same type of values, using scalar
+references in a column in one row, and not in another will probably not work.
+
+Otherwise, each set of data is inserted into the database using
 L<DBIx::Class::ResultSet/create>, and a arrayref of the resulting row
 objects is returned.
 
@@ -797,13 +843,16 @@ sub populate {
   my ($self, $name, $data) = @_;
   my $rs = $self->resultset($name);
   my @names = @{shift(@$data)};
-  my @created;
-  foreach my $item (@$data) {
-    my %create;
-    @create{@names} = @$item;
-    push(@created, $rs->create(\%create));
+  if(defined wantarray) {
+    my @created;
+    foreach my $item (@$data) {
+      my %create;
+      @create{@names} = @$item;
+      push(@created, $rs->create(\%create));
+    }
+    return @created;
   }
-  return @created;
+  $self->storage->insert_bulk($self->source($name), \@names, $data);
 }
 
 =head2 exception_action
@@ -868,12 +917,17 @@ sub throw_exception {
 Attempts to deploy the schema to the current storage using L<SQL::Translator>.
 
 Note that this feature is currently EXPERIMENTAL and may not work correctly
-across all databases, or fully handle complex relationships.
+across all databases, or fully handle complex relationships. Saying that, it
+has been used successfully by many people, including the core dev team.
 
 See L<SQL::Translator/METHODS> for a list of values for C<$sqlt_args>. The most
 common value for this would be C<< { add_drop_table => 1, } >> to have the SQL
 produced include a DROP TABLE statement for each table created.
 
+Additionally, the DBIx::Class parser accepts a C<sources> parameter as a hash 
+ref or an array ref, containing a list of source to deploy. If present, then 
+only the sources listed will get deployed.
+
 =cut
 
 sub deploy {
@@ -886,16 +940,41 @@ sub deploy {
 
 =over 4
 
-=item Arguments: \@databases, $version, $directory, $sqlt_args
+=item Arguments: \@databases, $version, $directory, $preversion, $sqlt_args
 
 =back
 
 Creates an SQL file based on the Schema, for each of the specified
-database types, in the given directory.
+database types, in the given directory. Given a previous version number,
+this will also create a file containing the ALTER TABLE statements to
+transform the previous schema into the current one. Note that these
+statements may contain DROP TABLE or DROP COLUMN statements that can
+potentially destroy data.
+
+The file names are created using the C<ddl_filename> method below, please
+override this method in your schema if you would like a different file
+name format. For the ALTER file, the same format is used, replacing
+$version in the name with "$preversion-$version".
+
+If no arguments are passed, then the following default values are used:
+
+=over 4
+
+=item databases  - ['MySQL', 'SQLite', 'PostgreSQL']
+
+=item version    - $schema->VERSION
+
+=item directory  - './'
+
+=item preversion - <none>
+
+=back
 
 Note that this feature is currently EXPERIMENTAL and may not work correctly
 across all databases, or fully handle complex relationships.
 
+WARNING: Please check all SQL files created, before applying them.
+
 =cut
 
 sub create_ddl_dir {
@@ -907,19 +986,30 @@ sub create_ddl_dir {
 
 =head2 ddl_filename (EXPERIMENTAL)
 
-  my $filename = $table->ddl_filename($type, $dir, $version)
+=over 4
+
+=item Arguments: $directory, $database-type, $version, $preversion
+
+=back
+
+  my $filename = $table->ddl_filename($type, $dir, $version, $preversion)
+
+This method is called by C<create_ddl_dir> to compose a file name out of
+the supplied directory, database type and version number. The default file
+name format is: C<$dir$schema-$version-$type.sql>.
 
-Creates a filename for a SQL file based on the table class name.  Not
-intended for direct end user use.
+You may override this method in your schema if you wish to use a different
+format.
 
 =cut
 
 sub ddl_filename {
-    my ($self, $type, $dir, $version) = @_;
+    my ($self, $type, $dir, $version, $pversion) = @_;
 
     my $filename = ref($self);
     $filename =~ s/::/-/;
-    $filename = "$dir$filename-$version-$type.sql";
+    $filename = File::Spec->catfile($dir, "$filename-$version-$type.sql");
+    $filename =~ s/$version/$pversion-$version/ if($pversion);
 
     return $filename;
 }
diff --git a/lib/DBIx/Class/Schema/Versioned.pm b/lib/DBIx/Class/Schema/Versioned.pm
new file mode 100644 (file)
index 0000000..91e78aa
--- /dev/null
@@ -0,0 +1,303 @@
+package DBIx::Class::Version::Table;
+use base 'DBIx::Class';
+use strict;
+use warnings;
+
+__PACKAGE__->load_components(qw/ Core/);
+__PACKAGE__->table('SchemaVersions');
+
+__PACKAGE__->add_columns
+    ( 'Version' => {
+        'data_type' => 'VARCHAR',
+        'is_auto_increment' => 0,
+        'default_value' => undef,
+        'is_foreign_key' => 0,
+        'name' => 'Version',
+        'is_nullable' => 0,
+        'size' => '10'
+        },
+      'Installed' => {
+          'data_type' => 'VARCHAR',
+          'is_auto_increment' => 0,
+          'default_value' => undef,
+          'is_foreign_key' => 0,
+          'name' => 'Installed',
+          'is_nullable' => 0,
+          'size' => '20'
+          },
+      );
+__PACKAGE__->set_primary_key('Version');
+
+package DBIx::Class::Version;
+use base 'DBIx::Class::Schema';
+use strict;
+use warnings;
+
+__PACKAGE__->register_class('Table', 'DBIx::Class::Version::Table');
+
+
+# ---------------------------------------------------------------------------
+package DBIx::Class::Schema::Versioned;
+
+use strict;
+use warnings;
+use base 'DBIx::Class';
+use POSIX 'strftime';
+use Data::Dumper;
+
+__PACKAGE__->mk_classdata('_filedata');
+__PACKAGE__->mk_classdata('upgrade_directory');
+__PACKAGE__->mk_classdata('backup_directory');
+
+sub on_connect
+{
+    my ($self) = @_;
+    my $vschema = DBIx::Class::Version->connect(@{$self->storage->connect_info()});
+    my $vtable = $vschema->resultset('Table');
+    my $pversion;
+
+    if(!$self->exists($vtable))
+    {
+#        $vschema->storage->debug(1);
+        $vschema->storage->ensure_connected();
+        $vschema->deploy();
+        $pversion = 0;
+    }
+    else
+    {
+        my $psearch = $vtable->search(undef, 
+                                      { select => [
+                                                   { 'max' => 'Installed' },
+                                                   ],
+                                            as => ['maxinstall'],
+                                        })->first;
+        $pversion = $vtable->search({ Installed => $psearch->get_column('maxinstall'),
+                                  })->first;
+        $pversion = $pversion->Version if($pversion);
+    }
+#    warn("Previous version: $pversion\n");
+    if($pversion eq $self->VERSION)
+    {
+        warn "This version is already installed\n";
+        return 1;
+    }
+
+## use IC::DT?    
+
+    if(!$pversion)
+    {
+        $vtable->create({ Version => $self->VERSION,
+                          Installed => strftime("%Y-%m-%d %H:%M:%S", gmtime())
+                          });
+        ## If we let the user do this, where does the Version table get updated?
+        warn "No previous version found, calling deploy to install this version.\n";
+        $self->deploy();
+        return 1;
+    }
+
+    my $file = $self->ddl_filename(
+                                   $self->storage->sqlt_type,
+                                   $self->upgrade_directory,
+                                   $self->VERSION
+                                   );
+    if(!$file)
+    {
+        # No upgrade path between these two versions
+        return 1;
+    }
+
+     $file = $self->ddl_filename(
+                                 $self->storage->sqlt_type,
+                                 $self->upgrade_directory,
+                                 $self->VERSION,
+                                 $pversion,
+                                 );
+#    $file =~ s/@{[ $self->VERSION ]}/"${pversion}-" . $self->VERSION/e;
+    if(!-f $file)
+    {
+        warn "Upgrade not possible, no upgrade file found ($file)\n";
+        return;
+    }
+
+    my $fh;
+    open $fh, "<$file" or warn("Can't open upgrade file, $file ($!)");
+    my @data = split(/;\n/, join('', <$fh>));
+    close($fh);
+    @data = grep { $_ && $_ !~ /^-- / } @data;
+    @data = grep { $_ !~ /^(BEGIN TRANACTION|COMMIT)/m } @data;
+
+    $self->_filedata(\@data);
+
+    ## Don't do this yet, do only on command?
+    ## If we do this later, where does the Version table get updated??
+    warn "Versions out of sync. This is " . $self->VERSION . 
+        ", your database contains version $pversion, please call upgrade on your Schema.\n";
+#    $self->upgrade($pversion, $self->VERSION);
+}
+
+sub exists
+{
+    my ($self, $rs) = @_;
+
+    my $c = eval {
+        $rs->search({ 1, 0 })->count;
+    };
+    return 0 if $@ || !defined $c;
+
+    return 1;
+}
+
+sub backup
+{
+    my ($self) = @_;
+    ## Make each ::DBI::Foo do this
+    $self->storage->backup($self->backup_directory());
+}
+
+sub upgrade
+{
+    my ($self) = @_;
+
+    ## overridable sub, per default just run all the commands.
+
+    $self->backup();
+
+    $self->run_upgrade(qr/create/i);
+    $self->run_upgrade(qr/alter table .*? add/i);
+    $self->run_upgrade(qr/alter table .*? (?!drop)/i);
+    $self->run_upgrade(qr/alter table .*? drop/i);
+    $self->run_upgrade(qr/drop/i);
+#    $self->run_upgrade(qr//i);
+
+    my $vschema = DBIx::Class::Version->connect(@{$self->storage->connect_info()});
+    my $vtable = $vschema->resultset('Table');
+    $vtable->create({ Version => $self->VERSION,
+                      Installed => strftime("%Y-%m-%d %H:%M:%S", gmtime())
+                      });
+}
+
+
+sub run_upgrade
+{
+    my ($self, $stm) = @_;
+#    print "Reg: $stm\n";
+    my @statements = grep { $_ =~ $stm } @{$self->_filedata};
+#    print "Statements: ", join("\n", @statements), "\n";
+    $self->_filedata([ grep { $_ !~ /$stm/i } @{$self->_filedata} ]);
+
+    for (@statements)
+    {
+        $self->storage->debugfh->print("$_\n") if $self->storage->debug;
+#        print "Running \n>>$_<<\n";
+        $self->storage->dbh->do($_) or warn "SQL was:\n $_";
+    }
+
+    return 1;
+}
+
+1;
+
+=head1 NAME
+
+DBIx::Class::Versioning - DBIx::Class::Schema plugin for Schema upgrades
+
+=head1 SYNOPSIS
+
+  package Library::Schema;
+  use base qw/DBIx::Class::Schema/;   
+  # load Library::Schema::CD, Library::Schema::Book, Library::Schema::DVD
+  __PACKAGE__->load_classes(qw/CD Book DVD/);
+
+  __PACKAGE__->load_components(qw/+DBIx::Class::Schema::Versioned/);
+  __PACKAGE__->upgrade_directory('/path/to/upgrades/');
+  __PACKAGE__->backup_directory('/path/to/backups/');
+
+  sub backup
+  {
+    my ($self) = @_;
+    # my special backup process
+  }
+
+  sub upgrade
+  {
+    my ($self) = @_;
+
+    ## overridable sub, per default just runs all the commands.
+
+    $self->run_upgrade(qr/create/i);
+    $self->run_upgrade(qr/alter table .*? add/i);
+    $self->run_upgrade(qr/alter table .*? (?!drop)/i);
+    $self->run_upgrade(qr/alter table .*? drop/i);
+    $self->run_upgrade(qr/drop/i);
+    $self->run_upgrade(qr//i);   
+  }
+
+=head1 DESCRIPTION
+
+This module is a component designed to extend L<DBIx::Class::Schema>
+classes, to enable them to upgrade to newer schema layouts. To use this
+module, you need to have called C<create_ddl_dir> on your Schema to
+create your upgrade files to include with your delivery.
+
+A table called I<SchemaVersions> is created and maintained by the
+module. This contains two fields, 'Version' and 'Installed', which
+contain each VERSION of your Schema, and the date+time it was installed.
+
+If you would like to influence which levels of version change need
+upgrades in your Schema, you can override the method C<ddl_filename>
+in L<DBIx::Class::Schema>. Return a false value if there is no upgrade
+path between the two versions supplied. By default, every change in
+your VERSION is regarded as needing an upgrade.
+
+The actual upgrade is called manually by calling C<upgrade> on your
+schema object. Code is run at connect time to determine whether an
+upgrade is needed, if so, a warning "Versions out of sync" is
+produced.
+
+NB: At the moment, SQLite upgrading is rather spotty, as SQL::Translator::Diff
+returns SQL statements that SQLite does not support.
+
+
+=head1 METHODS
+
+=head2 backup
+
+This is an overwritable method which is called just before the upgrade, to
+allow you to make a backup of the database. Per default this method attempts
+to call C<< $self->storage->backup >>, to run the standard backup on each
+database type. 
+
+This method should return the name of the backup file, if appropriate.
+
+C<backup> is called from C<upgrade>, make sure you call it, if you write your
+own <upgrade> method.
+
+=head2 upgrade
+
+This is an overwritable method used to run your upgrade. The freeform method
+allows you to run your upgrade any way you please, you can call C<run_upgrade>
+any number of times to run the actual SQL commands, and in between you can
+sandwich your data upgrading. For example, first run all the B<CREATE>
+commands, then migrate your data from old to new tables/formats, then 
+issue the DROP commands when you are finished.
+
+=head2 run_upgrade
+
+ $self->run_upgrade(qr/create/i);
+
+Runs a set of SQL statements matching a passed in regular expression. The
+idea is that this method can be called any number of times from your
+C<upgrade> method, running whichever commands you specify via the
+regex in the parameter.
+
+=head2 upgrade_directory
+
+Use this to set the directory your upgrade files are stored in.
+
+=head2 backup_directory
+
+Use this to set the directory you want your backups stored in.
+
+=head1 AUTHOR
+
+Jess Robinson <castaway@desert-island.demon.co.uk>
diff --git a/lib/DBIx/Class/Serialize/Storable.pm b/lib/DBIx/Class/Serialize/Storable.pm
deleted file mode 100644 (file)
index 7ccd2b0..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-package DBIx::Class::Serialize::Storable;
-use strict;
-use warnings;
-use Storable;
-
-sub STORABLE_freeze {
-    my ($self,$cloning) = @_;
-    my $to_serialize = { %$self };
-    delete $to_serialize->{result_source};
-    return (Storable::freeze($to_serialize));
-}
-
-sub STORABLE_thaw {
-    my ($self,$cloning,$serialized) = @_;
-    %$self = %{ Storable::thaw($serialized) };
-    $self->result_source($self->result_source_instance)
-      if $self->can('result_source_instance');
-}
-
-1;
-
-__END__
-
-=head1 NAME
-
-    DBIx::Class::Serialize::Storable - hooks for Storable freeze/thaw
-
-=head1 SYNOPSIS
-
-    # in a table class definition
-    __PACKAGE__->load_components(qw/Serialize::Storable/);
-
-    # meanwhile, in a nearby piece of code
-    my $cd = $schema->resultset('CD')->find(12);
-    # if the cache uses Storable, this will work automatically
-    $cache->set($cd->ID, $cd);
-
-=head1 DESCRIPTION
-
-This component adds hooks for Storable so that row objects can be
-serialized. It assumes that your row object class (C<result_class>) is
-the same as your table class, which is the normal situation.
-
-=head1 HOOKS
-
-The following hooks are defined for L<Storable> - see the
-documentation for L<Storable/Hooks> for detailed information on these
-hooks.
-
-=head2 STORABLE_freeze
-
-The serializing hook, called on the object during serialization. It
-can be inherited, or defined in the class itself, like any other
-method.
-
-=head2 STORABLE_thaw
-
-The deserializing hook called on the object during deserialization.
-
-=head1 AUTHORS
-
-David Kamholz <dkamholz@cpan.org>
-
-=head1 LICENSE
-
-You may distribute this code under the same terms as Perl itself.
-
-=cut
index f98001b..9a58b94 100644 (file)
@@ -8,7 +8,6 @@ use base qw/DBIx::Class/;
 use Scalar::Util qw/weaken/;
 use Carp::Clan qw/^DBIx::Class/;
 
-__PACKAGE__->load_components(qw/AccessorGroup/);
 __PACKAGE__->mk_group_accessors('simple' => qw/debug debugobj schema/);
 
 package # Hide from PAUSE
index ff7c9cd..04dd140 100644 (file)
@@ -10,11 +10,12 @@ use SQL::Abstract::Limit;
 use DBIx::Class::Storage::DBI::Cursor;
 use DBIx::Class::Storage::Statistics;
 use IO::File;
+use Scalar::Util 'blessed';
 
 __PACKAGE__->mk_group_accessors(
   'simple' =>
     qw/_connect_info _dbh _sql_maker _sql_maker_opts _conn_pid _conn_tid
-       cursor on_connect_do transaction_depth/
+       disable_sth_caching cursor on_connect_do transaction_depth/
 );
 
 BEGIN {
@@ -58,9 +59,10 @@ WHERE ROW_NUM BETWEEN $offset AND $last
 
 # While we're at it, this should make LIMIT queries more efficient,
 #  without digging into things too deeply
+use Scalar::Util 'blessed';
 sub _find_syntax {
   my ($self, $syntax) = @_;
-  my $dbhname = ref $syntax eq 'HASH' ? $syntax->{Driver}{Name} : '';
+  my $dbhname = blessed($syntax) ?  $syntax->{Driver}{Name} : $syntax;
   if(ref($self) && $dbhname && $dbhname eq 'DB2') {
     return 'RowNumberOver';
   }
@@ -236,9 +238,18 @@ sub _join_condition {
   if (ref $cond eq 'HASH') {
     my %j;
     for (keys %$cond) {
-      my $x = '= '.$self->_quote($cond->{$_}); $j{$_} = \$x;
+      my $v = $cond->{$_};
+      if (ref $v) {
+        # XXX no throw_exception() in this package and croak() fails with strange results
+        Carp::croak(ref($v) . qq{ reference arguments are not supported in JOINS - try using \"..." instead'})
+            if ref($v) ne 'SCALAR';
+        $j{$_} = $v;
+      }
+      else {
+        my $x = '= '.$self->_quote($v); $j{$_} = \$x;
+      }
     };
-    return $self->_recurse_where(\%j);
+    return scalar($self->_recurse_where(\%j));
   } elsif (ref $cond eq 'ARRAY') {
     return join(' OR ', map { $self->_join_condition($_) } @$cond);
   } else {
@@ -334,6 +345,11 @@ This can be set to an arrayref of literal sql statements, which will
 be executed immediately after making the connection to the database
 every time we [re-]connect.
 
+=item disable_sth_caching
+
+If set to a true value, this option will disable the caching of
+statement handles via L<DBI/prepare_cached>.
+
 =item limit_dialect 
 
 Sets the limit dialect. This is useful for JDBC-bridge among others
@@ -411,6 +427,7 @@ Examples:
           quote_char => q{`},
           name_sep => q{@},
           on_connect_do => ['SET search_path TO myschema,otherschema,public'],
+          disable_sth_caching => 1,
       },
     ]
   );
@@ -430,8 +447,10 @@ sub connect_info {
   my $info = [ @$info_arg ]; # copy because we can alter it
   my $last_info = $info->[-1];
   if(ref $last_info eq 'HASH') {
-    if(my $on_connect_do = delete $last_info->{on_connect_do}) {
-      $self->on_connect_do($on_connect_do);
+    for my $storage_opt (qw/on_connect_do disable_sth_caching/) {
+      if(my $value = delete $last_info->{$storage_opt}) {
+        $self->$storage_opt($value);
+      }
     }
     for my $sql_maker_opt (qw/limit_dialect quote_char name_sep/) {
       if(my $opt_val = delete $last_info->{$sql_maker_opt}) {
@@ -651,7 +670,7 @@ sub dbh {
 sub _sql_maker_args {
     my ($self) = @_;
     
-    return ( limit_dialect => $self->dbh, %{$self->_sql_maker_opts} );
+    return ( bindtype=>'columns', limit_dialect => $self->dbh, %{$self->_sql_maker_opts} );
 }
 
 sub sql_maker {
@@ -799,29 +818,68 @@ sub _prep_for_execute {
   my ($self, $op, $extra_bind, $ident, @args) = @_;
 
   my ($sql, @bind) = $self->sql_maker->$op($ident, @args);
-  unshift(@bind, @$extra_bind) if $extra_bind;
+  unshift(@bind,
+    map { ref $_ eq 'ARRAY' ? $_ : [ '!!dummy', $_ ] } @$extra_bind)
+      if $extra_bind;
   @bind = map { ref $_ ? ''.$_ : $_ } @bind; # stringify args
 
   return ($sql, @bind);
 }
 
 sub _execute {
-  my $self = shift;
-
-  my ($sql, @bind) = $self->_prep_for_execute(@_);
-
+  my ($self, $op, $extra_bind, $ident, $bind_attributes, @args) = @_;
+  
+  if( blessed($ident) && $ident->isa("DBIx::Class::ResultSource") )
+  {
+    $ident = $ident->from();
+  }
+  
+  my ($sql, @bind) = $self->sql_maker->$op($ident, @args);
+  unshift(@bind,
+    map { ref $_ eq 'ARRAY' ? $_ : [ '!!dummy', $_ ] } @$extra_bind)
+      if $extra_bind;
   if ($self->debug) {
-      my @debug_bind = map { defined $_ ? qq{'$_'} : q{'NULL'} } @bind;
+      my @debug_bind =
+        map { defined ($_ && $_->[1]) ? qq{'$_->[1]'} : q{'NULL'} } @bind;
       $self->debugobj->query_start($sql, @debug_bind);
   }
+  my $sth = eval { $self->sth($sql,$op) };
 
-  my $sth = $self->sth($sql);
+  if (!$sth || $@) {
+    $self->throw_exception(
+      'no sth generated via sql (' . ($@ || $self->_dbh->errstr) . "): $sql"
+    );
+  }
 
   my $rv;
   if ($sth) {
     my $time = time();
-    $rv = eval { $sth->execute(@bind) };
+       
+    $rv = eval {
+       
+      my $placeholder_index = 1; 
+
+      foreach my $bound (@bind) {
+
+        my $attributes = {};
+        my($column_name, @data) = @$bound;
+
+        if( $bind_attributes ) {
+          $attributes = $bind_attributes->{$column_name}
+          if defined $bind_attributes->{$column_name};
+        }
 
+               foreach my $data (@data)
+               {
+          $data = ref $data ? ''.$data : $data; # stringify args
+
+          $sth->bind_param($placeholder_index, $data, $attributes);
+          $placeholder_index++;                  
+               }
+      }
+      $sth->execute();
+    };
+  
     if ($@ || !$rv) {
       $self->throw_exception("Error executing '$sql': ".($@ || $sth->errstr));
     }
@@ -829,28 +887,135 @@ sub _execute {
     $self->throw_exception("'$sql' did not generate a statement.");
   }
   if ($self->debug) {
-      my @debug_bind = map { defined $_ ? qq{`$_'} : q{`NULL'} } @bind;
-      $self->debugobj->query_end($sql, @debug_bind);
+     my @debug_bind =
+       map { defined ($_ && $_->[1]) ? qq{'$_->[1]'} : q{'NULL'} } @bind; 
+     $self->debugobj->query_end($sql, @debug_bind);
   }
   return (wantarray ? ($rv, $sth, @bind) : $rv);
 }
 
 sub insert {
-  my ($self, $ident, $to_insert) = @_;
+  my ($self, $source, $to_insert) = @_;
+  
+  my $ident = $source->from; 
+  my $bind_attributes = $self->source_bind_attributes($source);
+
   $self->throw_exception(
     "Couldn't insert ".join(', ',
       map "$_ => $to_insert->{$_}", keys %$to_insert
     )." into ${ident}"
-  ) unless ($self->_execute('insert' => [], $ident, $to_insert));
+  ) unless ($self->_execute('insert' => [], $source, $bind_attributes, $to_insert));
   return $to_insert;
 }
 
+## Still not quite perfect, and EXPERIMENTAL
+## Currently it is assumed that all values passed will be "normal", i.e. not 
+## scalar refs, or at least, all the same type as the first set, the statement is
+## only prepped once.
+sub insert_bulk {
+  my ($self, $source, $cols, $data) = @_;
+  my %colvalues;
+  my $table = $source->from;
+  @colvalues{@$cols} = (0..$#$cols);
+  my ($sql, @bind) = $self->sql_maker->insert($table, \%colvalues);
+  
+  if ($self->debug) {
+      my @debug_bind = map { defined $_->[1] ? qq{$_->[1]} : q{'NULL'} } @bind;
+      $self->debugobj->query_start($sql, @debug_bind);
+  }
+  my $sth = $self->sth($sql);
+
+#  @bind = map { ref $_ ? ''.$_ : $_ } @bind; # stringify args
+
+  my $rv;
+  
+  ## This must be an arrayref, else nothing works!
+  
+  my $tuple_status = [];
+  
+  ##use Data::Dumper;
+  ##print STDERR Dumper( $data, $sql, [@bind] );
+       
+  if ($sth) {
+  
+    my $time = time();
+       
+    #$rv = eval {
+       #
+       #  $sth->execute_array({
+
+       #    ArrayTupleFetch => sub {
+
+       #      my $values = shift @$data;  
+    #      return if !$values; 
+    #      return [ @{$values}[@bind] ];
+       #    },
+         
+       #    ArrayTupleStatus => $tuple_status,
+       #  })
+    #};
+       
+       ## Get the bind_attributes, if any exist
+    my $bind_attributes = $self->source_bind_attributes($source);
+
+       ## Bind the values and execute
+       $rv = eval {
+       
+     my $placeholder_index = 1; 
+
+        foreach my $bound (@bind) {
+
+          my $attributes = {};
+          my ($column_name, $data_index) = @$bound;
+
+          if( $bind_attributes ) {
+            $attributes = $bind_attributes->{$column_name}
+            if defined $bind_attributes->{$column_name};
+          }
+                 
+                 my @data = map { $_->[$data_index] } @$data;
+
+          $sth->bind_param_array( $placeholder_index, [@data], $attributes );
+          $placeholder_index++;
+      }
+         $sth->execute_array( {ArrayTupleStatus => $tuple_status} );
+
+       };
+   
+    if ($@ || !defined $rv) {
+      my $errors = '';
+      foreach my $tuple (@$tuple_status)
+      {
+          $errors .= "\n" . $tuple->[1] if(ref $tuple);
+      }
+      $self->throw_exception("Error executing '$sql': ".($@ || $errors));
+    }
+  } else {
+    $self->throw_exception("'$sql' did not generate a statement.");
+  }
+  if ($self->debug) {
+      my @debug_bind = map { defined $_ ? qq{`$_'} : q{`NULL'} } @bind;
+      $self->debugobj->query_end($sql, @debug_bind);
+  }
+  return (wantarray ? ($rv, $sth, @bind) : $rv);
+}
+
 sub update {
-  return shift->_execute('update' => [], @_);
+  my $self = shift @_;
+  my $source = shift @_;
+  my $bind_attributes = $self->source_bind_attributes($source);
+  
+  return $self->_execute('update' => [], $source, $bind_attributes, @_);
 }
 
+
 sub delete {
-  return shift->_execute('delete' => [], @_);
+  my $self = shift @_;
+  my $source = shift @_;
+  
+  my $bind_attrs = {}; ## If ever it's needed...
+  
+  return $self->_execute('delete' => [], $source, $bind_attrs, @_);
 }
 
 sub _select {
@@ -866,7 +1031,8 @@ sub _select {
       ($order ? (order_by => $order) : ())
     };
   }
-  my @args = ('select', $attrs->{bind}, $ident, $select, $condition, $order);
+  my $bind_attrs = {}; ## Future support
+  my @args = ('select', $attrs->{bind}, $ident, $bind_attrs, $select, $condition, $order);
   if ($attrs->{software_limit} ||
       $self->sql_maker->_default_limit_syntax eq "GenericSubQ") {
         $attrs->{software_limit} = 1;
@@ -878,6 +1044,20 @@ sub _select {
   return $self->_execute(@args);
 }
 
+sub source_bind_attributes {
+  my ($self, $source) = @_;
+  
+  my $bind_attributes;
+  foreach my $column ($source->columns) {
+  
+    my $data_type = $source->column_info($column)->{data_type} || '';
+    $bind_attributes->{$column} = $self->bind_attribute_by_data_type($data_type)
+        if $data_type;
+  }
+
+  return $bind_attributes;
+}
+
 =head2 select
 
 =over 4
@@ -919,11 +1099,17 @@ Returns a L<DBI> sth (statement handle) for the supplied SQL.
 
 sub _dbh_sth {
   my ($self, $dbh, $sql) = @_;
+
   # 3 is the if_active parameter which avoids active sth re-use
-  $dbh->prepare_cached($sql, {}, 3) or
-    $self->throw_exception(
-      'no sth generated via sql (' . ($@ || $dbh->errstr) . "): $sql"
-    );
+  my $sth = $self->disable_sth_caching
+    ? $dbh->prepare($sql)
+    : $dbh->prepare_cached($sql, {}, 3);
+
+  $self->throw_exception(
+    'no sth generated via sql (' . ($@ || $dbh->errstr) . "): $sql"
+  ) if !$sth;
+
+  $sth;
 }
 
 sub sth {
@@ -1012,11 +1198,25 @@ Returns the database driver name.
 
 sub sqlt_type { shift->dbh->{Driver}->{Name} }
 
+=head2 bind_attribute_by_data_type
+
+Given a datatype from column info, returns a database specific bind attribute for
+$dbh->bind_param($val,$attribute) or nothing if we will let the database planner
+just handle it.
+
+Generally only needed for special case column types, like bytea in postgres.
+
+=cut
+
+sub bind_attribute_by_data_type {
+    return;
+}
+
 =head2 create_ddl_dir (EXPERIMENTAL)
 
 =over 4
 
-=item Arguments: $schema \@databases, $version, $directory, $sqlt_args
+=item Arguments: $schema \@databases, $version, $directory, $preversion, $sqlt_args
 
 =back
 
@@ -1030,7 +1230,7 @@ across all databases, or fully handle complex relationships.
 
 sub create_ddl_dir
 {
-  my ($self, $schema, $databases, $version, $dir, $sqltargs) = @_;
+  my ($self, $schema, $databases, $version, $dir, $preversion, $sqltargs) = @_;
 
   if(!$dir || !-d $dir)
   {
@@ -1043,14 +1243,18 @@ sub create_ddl_dir
   $sqltargs = { ( add_drop_table => 1 ), %{$sqltargs || {}} };
 
   eval "use SQL::Translator";
-  $self->throw_exception("Can't deploy without SQL::Translator: $@") if $@;
+  $self->throw_exception("Can't create a ddl file without SQL::Translator: $@") if $@;
 
-  my $sqlt = SQL::Translator->new($sqltargs);
+  my $sqlt = SQL::Translator->new({
+#      debug => 1,
+      add_drop_table => 1,
+  });
   foreach my $db (@$databases)
   {
     $sqlt->reset();
     $sqlt->parser('SQL::Translator::Parser::DBIx::Class');
 #    $sqlt->parser_args({'DBIx::Class' => $schema);
+    $sqlt = $self->configure_sqlt($sqlt, $db);
     $sqlt->data($schema);
     $sqlt->producer($db);
 
@@ -1058,24 +1262,97 @@ sub create_ddl_dir
     my $filename = $schema->ddl_filename($db, $dir, $version);
     if(-e $filename)
     {
-      $self->throw_exception("$filename already exists, skipping $db");
+      warn("$filename already exists, skipping $db");
       next;
     }
-    open($file, ">$filename") 
-      or $self->throw_exception("Can't open $filename for writing ($!)");
+
     my $output = $sqlt->translate;
-#use Data::Dumper;
-#    print join(":", keys %{$schema->source_registrations});
-#    print Dumper($sqlt->schema);
     if(!$output)
     {
-      $self->throw_exception("Failed to translate to $db. (" . $sqlt->error . ")");
+      warn("Failed to translate to $db, skipping. (" . $sqlt->error . ")");
       next;
     }
+    if(!open($file, ">$filename"))
+    {
+        $self->throw_exception("Can't open $filename for writing ($!)");
+        next;
+    }
     print $file $output;
     close($file);
+
+    if($preversion)
+    {
+      eval "use SQL::Translator::Diff";
+      if($@)
+      {
+        warn("Can't diff versions without SQL::Translator::Diff: $@");
+        next;
+      }
+
+      my $prefilename = $schema->ddl_filename($db, $dir, $preversion);
+#      print "Previous version $prefilename\n";
+      if(!-e $prefilename)
+      {
+        warn("No previous schema file found ($prefilename)");
+        next;
+      }
+      #### We need to reparse the SQLite file we just wrote, so that 
+      ##   Diff doesnt get all confoosed, and Diff is *very* confused.
+      ##   FIXME: rip Diff to pieces!
+#      my $target_schema = $sqlt->schema;
+#      unless ( $target_schema->name ) {
+#        $target_schema->name( $filename );
+#      }
+      my @input;
+      push @input, {file => $prefilename, parser => $db};
+      push @input, {file => $filename, parser => $db};
+      my ( $source_schema, $source_db, $target_schema, $target_db ) = map {
+        my $file   = $_->{'file'};
+        my $parser = $_->{'parser'};
+
+        my $t = SQL::Translator->new;
+        $t->debug( 0 );
+        $t->trace( 0 );
+        $t->parser( $parser )            or die $t->error;
+        my $out = $t->translate( $file ) or die $t->error;
+        my $schema = $t->schema;
+        unless ( $schema->name ) {
+          $schema->name( $file );
+        }
+        ($schema, $parser);
+      } @input;
+
+      my $diff = SQL::Translator::Diff::schema_diff($source_schema, $db,
+                                                    $target_schema, $db,
+                                                    {}
+                                                   );
+      my $difffile = $schema->ddl_filename($db, $dir, $version, $preversion);
+      print STDERR "Diff: $difffile: $db, $dir, $version, $preversion \n";
+      if(-e $difffile)
+      {
+        warn("$difffile already exists, skipping");
+        next;
+      }
+      if(!open $file, ">$difffile")
+      { 
+        $self->throw_exception("Can't write to $difffile ($!)");
+        next;
+      }
+      print $file $diff;
+      close($file);
+    }
   }
+}
 
+sub configure_sqlt() {
+  my $self = shift;
+  my $tr = shift;
+  my $db = shift || $self->sqlt_type;
+  if ($db eq 'PostgreSQL') {
+    $tr->quote_table_names(0);
+    $tr->quote_field_names(0);
+  }
+  return $tr;
 }
 
 =head2 deployment_statements
@@ -1108,6 +1385,17 @@ sub deployment_statements {
   $type ||= $self->sqlt_type;
   $version ||= $schema->VERSION || '1.x';
   $dir ||= './';
+  my $filename = $schema->ddl_filename($type, $dir, $version);
+  if(-f $filename)
+  {
+      my $file;
+      open($file, "<$filename") 
+        or $self->throw_exception("Can't open $filename ($!)");
+      my @rows = <$file>;
+      close($file);
+      return join('', @rows);
+  }
+
   eval "use SQL::Translator";
   if(!$@)
   {
@@ -1115,26 +1403,20 @@ sub deployment_statements {
     $self->throw_exception($@) if $@;
     eval "use SQL::Translator::Producer::${type};";
     $self->throw_exception($@) if $@;
+
+    # sources needs to be a parser arg, but for simplicty allow at top level 
+    # coming in
+    $sqltargs->{parser_args}{sources} = delete $sqltargs->{sources}
+        if exists $sqltargs->{sources};
+
     my $tr = SQL::Translator->new(%$sqltargs);
     SQL::Translator::Parser::DBIx::Class::parse( $tr, $schema );
     return "SQL::Translator::Producer::${type}"->can('produce')->($tr);
   }
 
-  my $filename = $schema->ddl_filename($type, $dir, $version);
-  if(!-f $filename)
-  {
-#      $schema->create_ddl_dir([ $type ], $version, $dir, $sqltargs);
-      $self->throw_exception("No SQL::Translator, and no Schema file found, aborting deploy");
-      return;
-  }
-  my $file;
-  open($file, "<$filename") 
-      or $self->throw_exception("Can't open $filename ($!)");
-  my @rows = <$file>;
-  close($file);
+  $self->throw_exception("No SQL::Translator, and no Schema file found, aborting deploy");
+  return;
 
-  return join('', @rows);
-  
 }
 
 sub deploy {
index 2ab0799..2877ee2 100644 (file)
@@ -17,15 +17,17 @@ well, as is the case with L<DBD::Sybase>
 
 =head1 METHODS
 
-=head2 sth
+=head2 connect_info
 
-Uses C<prepare> instead of the usual C<prepare_cached>, seeing as we can't cache very effectively without bind variables.
+We can't cache very effectively without bind variables, so force the C<disable_sth_caching> setting to be turned on when the connect info is set.
 
 =cut
 
-sub _dbh_sth {
-  my ($self, $dbh, $sql) = @_;
-  $dbh->prepare($sql);
+sub connect_info {
+    my $self = shift;
+    my $retval = shift->next::method(@_);
+    $self->disable_sth_caching(1);
+    $retval;
 }
 
 =head2 _prep_for_execute
@@ -38,7 +40,7 @@ sub _prep_for_execute {
   my $self = shift;
   my ($sql, @bind) = $self->next::method(@_);
 
-  $sql =~ s/\?/$self->_dbh->quote($_)/e for (@bind);
+  $sql =~ s/\?/$self->_dbh->quote(shift(@bind))/eg;
 
   return ($sql);
 }
index 0c98f91..8f0f30d 100644 (file)
@@ -3,7 +3,7 @@ package DBIx::Class::Storage::DBI::Pg;
 use strict;
 use warnings;
 
-use DBD::Pg;
+use DBD::Pg qw(:pg_types);
 
 use base qw/DBIx::Class::Storage::DBI/;
 
@@ -21,6 +21,9 @@ sub _dbh_last_insert_id {
 sub last_insert_id {
   my ($self,$source,$col) = @_;
   my $seq = ($source->column_info($col)->{sequence} ||= $self->get_autoinc_seq($source,$col));
+  $self->throw_exception("could not fetch primary key for " . $source->name . ", could not "
+    . "get autoinc sequence for $col (check that table and column specifications are correct "
+    . "and in the correct case)") unless defined $seq;
   $self->dbh_do($self->can('_dbh_last_insert_id'), $seq);
 }
 
@@ -55,6 +58,21 @@ sub sqlt_type {
 
 sub datetime_parser_type { return "DateTime::Format::Pg"; }
 
+sub bind_attribute_by_data_type {
+  my ($self,$data_type) = @_;
+
+  my $bind_attributes = {
+       bytea => { pg_type => DBD::Pg::PG_BYTEA },
+  };
+  if( defined $bind_attributes->{$data_type} ) {
+    return $bind_attributes->{$data_type};
+  }
+  else {
+    return;
+  }
+}
+
 1;
 
 =head1 NAME
index 2d7d9ad..02a3c51 100644 (file)
@@ -2,6 +2,9 @@ package DBIx::Class::Storage::DBI::SQLite;
 
 use strict;
 use warnings;
+use POSIX 'strftime';
+use File::Copy;
+use File::Spec;
 
 use base qw/DBIx::Class::Storage::DBI::MultiDistinctEmulation/;
 
@@ -10,6 +13,38 @@ sub _dbh_last_insert_id {
   $dbh->func('last_insert_rowid');
 }
 
+sub backup
+{
+  my ($self, $dir) = @_;
+  $dir ||= './';
+
+  ## Where is the db file?
+  my $dsn = $self->connect_info()->[0];
+
+  my $dbname = $1 if($dsn =~ /dbname=([^;]+)/);
+  if(!$dbname)
+  {
+    $dbname = $1 if($dsn =~ /^dbi:SQLite:(.+)$/i);
+  }
+  $self->throw_exception("Cannot determine name of SQLite db file") 
+    if(!$dbname || !-f $dbname);
+
+#  print "Found database: $dbname\n";
+#  my $dbfile = file($dbname);
+  my ($vol, $dbdir, $file) = File::Spec->splitpath($dbname);
+#  my $file = $dbfile->basename();
+  $file = strftime("%y%m%d%h%M%s", localtime()) . $file; 
+  $file = "B$file" while(-f $file);
+
+  mkdir($dir) unless -f $dir;
+  my $backupfile = File::Spec->catfile($dir, $file);
+
+  my $res = copy($dbname, $backupfile);
+  $self->throw_exception("Backup failed! ($!)") if(!$res);
+
+  return $backupfile;
+}
+
 1;
 
 =head1 NAME
index 09f79da..5d0ba47 100644 (file)
@@ -2,7 +2,8 @@ package DBIx::Class::Storage::Statistics;
 use strict;
 use warnings;
 
-use base qw/DBIx::Class::AccessorGroup Class::Data::Accessor/;
+use base qw/Class::Accessor::Grouped/;
+
 __PACKAGE__->mk_group_accessors(simple => qw/callback debugfh/);
 
 =head1 NAME
index bcd45cb..f060f81 100644 (file)
@@ -3,7 +3,16 @@ use strict;
 use warnings;
 use base qw/DBIx::Class/;
 
-use utf8;
+BEGIN {
+
+    # Perl 5.8.0 doesn't have utf8::is_utf8()
+    # Yes, 5.8.0 support for Unicode is suboptimal, but things like RHEL3 ship with it.
+    if ($] <= 5.008000) {
+        require Encode;
+    } else {
+        require utf8;
+    }
+}
 
 __PACKAGE__->mk_classdata( '_utf8_columns' );
 
@@ -60,8 +69,13 @@ sub get_column {
 
     my $cols = $self->_utf8_columns;
     if ( $cols and defined $value and $cols->{$column} ) {
-        utf8::decode($value) unless utf8::is_utf8($value);
-   }
+
+        if ($] <= 5.008000) {
+            Encode::_utf8_on($value) unless Encode::is_utf8($value);
+        } else {
+            utf8::decode($value) unless utf8::is_utf8($value);
+        }
+    }
 
     $value;
 }
@@ -75,7 +89,12 @@ sub get_columns {
     my %data = $self->next::method(@_);
 
     foreach my $col (grep { defined $data{$_} } keys %{ $self->_utf8_columns || {} }) {
-        utf8::decode($data{$col}) unless utf8::is_utf8($data{$col});
+
+        if ($] <= 5.008000) {
+            Encode::_utf8_on($data{$col}) unless Encode::is_utf8($data{$col});
+        } else {
+            utf8::decode($data{$col}) unless utf8::is_utf8($data{$col});
+        }
     }
 
     %data;
@@ -90,7 +109,12 @@ sub store_column {
 
     my $cols = $self->_utf8_columns;
     if ( $cols and defined $value and $cols->{$column} ) {
-        utf8::encode($value) if utf8::is_utf8($value);
+
+        if ($] <= 5.008000) {
+            Encode::_utf8_off($value) if Encode::is_utf8($value);
+        } else {
+            utf8::encode($value) if utf8::is_utf8($value);
+        }
     }
 
     $self->next::method( $column, $value );
index d8af4d6..edf6224 100644 (file)
@@ -26,10 +26,11 @@ use base qw(Exporter);
 # We're working with DBIx::Class Schemas, not data streams.
 # -------------------------------------------------------------------
 sub parse {
-    my ($tr, $data) = @_;
-    my $args        = $tr->parser_args;
-    my $dbixschema  = $args->{'DBIx::Schema'} || $data;
-    $dbixschema   ||= $args->{'package'};
+    my ($tr, $data)   = @_;
+    my $args          = $tr->parser_args;
+    my $dbixschema    = $args->{'DBIx::Schema'} || $data;
+    $dbixschema     ||= $args->{'package'};
+    my $limit_sources = $args->{'sources'};
     
     die 'No DBIx::Schema' unless ($dbixschema);
     if (!ref $dbixschema) {
@@ -46,7 +47,23 @@ sub parse {
 
     my %seen_tables;
 
-    foreach my $moniker ($dbixschema->sources)
+    my @monikers = $dbixschema->sources;
+    if ($limit_sources) {
+        my $ref = ref $limit_sources || '';
+        die "'sources' parameter must be an array or hash ref" unless $ref eq 'ARRAY' || ref eq 'HASH';
+
+        # limit monikers to those specified in 
+        my $sources;
+        if ($ref eq 'ARRAY') {
+            $sources->{$_} = 1 for (@$limit_sources);
+        } else {
+            $sources = $limit_sources;
+        }
+        @monikers = grep { $sources->{$_} } @monikers;
+    }
+
+
+    foreach my $moniker (@monikers)
     {
         #eval "use $tableclass";
         #print("Can't load $tableclass"), next if($@);
@@ -91,6 +108,9 @@ sub parse {
         }
 
         my @rels = $source->relationships();
+
+        my %created_FK_rels;
+
         foreach my $rel (@rels)
         {
             my $rel_info = $source->relationship_info($rel);
@@ -120,12 +140,22 @@ sub parse {
                     $on_update = $otherrelationship->{'attrs'}->{cascade_copy} ? 'CASCADE' : '';
                 }
 
+                # Make sure we dont create the same foreign key constraint twice
+                my $key_test = join("\x00", @keys);
+
                 #Decide if this is a foreign key based on whether the self
                 #items are our primary columns.
 
                 # If the sets are different, then we assume it's a foreign key from
                 # us to another table.
-                if (!$source->compare_relationship_keys(\@keys, \@primary)) {
+                # OR: If is_foreign_key attr is explicity set on one the local columns
+                if ( ! exists $created_FK_rels{$rel_table}->{$key_test} 
+                    && 
+                    ( !$source->compare_relationship_keys(\@keys, \@primary) ||
+                      grep { $source->column_info($_)->{is_foreign_key} } @keys 
+                    )
+                   ) {
+                    $created_FK_rels{$rel_table}->{$key_test} = 1;
                     $table->add_constraint(
                                 type             => 'foreign_key',
                                 name             => "fk_$keys[0]",
diff --git a/t/100populate.t b/t/100populate.t
new file mode 100644 (file)
index 0000000..7b89395
--- /dev/null
@@ -0,0 +1,10085 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+plan tests => 22;
+
+# perl -le'my $letter = 'a'; for my $i (4..10000) { $letter++; print "[ $i, \"$letter\" ]," }' > tests.txt
+
+my $schema = DBICTest->init_schema();
+$schema->populate('Artist', [
+[ qw/artistid name/ ],
+[ 4, "b" ],
+[ 5, "c" ],
+[ 6, "d" ],
+[ 7, "e" ],
+[ 8, "f" ],
+[ 9, "g" ],
+[ 10, "h" ],
+[ 11, "i" ],
+[ 12, "j" ],
+[ 13, "k" ],
+[ 14, "l" ],
+[ 15, "m" ],
+[ 16, "n" ],
+[ 17, "o" ],
+[ 18, "p" ],
+[ 19, "q" ],
+[ 20, "r" ],
+[ 21, "s" ],
+[ 22, "t" ],
+[ 23, "u" ],
+[ 24, "v" ],
+[ 25, "w" ],
+[ 26, "x" ],
+[ 27, "y" ],
+[ 28, "z" ],
+[ 29, "aa" ],
+[ 30, "ab" ],
+[ 31, "ac" ],
+[ 32, "ad" ],
+[ 33, "ae" ],
+[ 34, "af" ],
+[ 35, "ag" ],
+[ 36, "ah" ],
+[ 37, "ai" ],
+[ 38, "aj" ],
+[ 39, "ak" ],
+[ 40, "al" ],
+[ 41, "am" ],
+[ 42, "an" ],
+[ 43, "ao" ],
+[ 44, "ap" ],
+[ 45, "aq" ],
+[ 46, "ar" ],
+[ 47, "as" ],
+[ 48, "at" ],
+[ 49, "au" ],
+[ 50, "av" ],
+[ 51, "aw" ],
+[ 52, "ax" ],
+[ 53, "ay" ],
+[ 54, "az" ],
+[ 55, "ba" ],
+[ 56, "bb" ],
+[ 57, "bc" ],
+[ 58, "bd" ],
+[ 59, "be" ],
+[ 60, "bf" ],
+[ 61, "bg" ],
+[ 62, "bh" ],
+[ 63, "bi" ],
+[ 64, "bj" ],
+[ 65, "bk" ],
+[ 66, "bl" ],
+[ 67, "bm" ],
+[ 68, "bn" ],
+[ 69, "bo" ],
+[ 70, "bp" ],
+[ 71, "bq" ],
+[ 72, "br" ],
+[ 73, "bs" ],
+[ 74, "bt" ],
+[ 75, "bu" ],
+[ 76, "bv" ],
+[ 77, "bw" ],
+[ 78, "bx" ],
+[ 79, "by" ],
+[ 80, "bz" ],
+[ 81, "ca" ],
+[ 82, "cb" ],
+[ 83, "cc" ],
+[ 84, "cd" ],
+[ 85, "ce" ],
+[ 86, "cf" ],
+[ 87, "cg" ],
+[ 88, "ch" ],
+[ 89, "ci" ],
+[ 90, "cj" ],
+[ 91, "ck" ],
+[ 92, "cl" ],
+[ 93, "cm" ],
+[ 94, "cn" ],
+[ 95, "co" ],
+[ 96, "cp" ],
+[ 97, "cq" ],
+[ 98, "cr" ],
+[ 99, "cs" ],
+[ 100, "ct" ],
+[ 101, "cu" ],
+[ 102, "cv" ],
+[ 103, "cw" ],
+[ 104, "cx" ],
+[ 105, "cy" ],
+[ 106, "cz" ],
+[ 107, "da" ],
+[ 108, "db" ],
+[ 109, "dc" ],
+[ 110, "dd" ],
+[ 111, "de" ],
+[ 112, "df" ],
+[ 113, "dg" ],
+[ 114, "dh" ],
+[ 115, "di" ],
+[ 116, "dj" ],
+[ 117, "dk" ],
+[ 118, "dl" ],
+[ 119, "dm" ],
+[ 120, "dn" ],
+[ 121, "do" ],
+[ 122, "dp" ],
+[ 123, "dq" ],
+[ 124, "dr" ],
+[ 125, "ds" ],
+[ 126, "dt" ],
+[ 127, "du" ],
+[ 128, "dv" ],
+[ 129, "dw" ],
+[ 130, "dx" ],
+[ 131, "dy" ],
+[ 132, "dz" ],
+[ 133, "ea" ],
+[ 134, "eb" ],
+[ 135, "ec" ],
+[ 136, "ed" ],
+[ 137, "ee" ],
+[ 138, "ef" ],
+[ 139, "eg" ],
+[ 140, "eh" ],
+[ 141, "ei" ],
+[ 142, "ej" ],
+[ 143, "ek" ],
+[ 144, "el" ],
+[ 145, "em" ],
+[ 146, "en" ],
+[ 147, "eo" ],
+[ 148, "ep" ],
+[ 149, "eq" ],
+[ 150, "er" ],
+[ 151, "es" ],
+[ 152, "et" ],
+[ 153, "eu" ],
+[ 154, "ev" ],
+[ 155, "ew" ],
+[ 156, "ex" ],
+[ 157, "ey" ],
+[ 158, "ez" ],
+[ 159, "fa" ],
+[ 160, "fb" ],
+[ 161, "fc" ],
+[ 162, "fd" ],
+[ 163, "fe" ],
+[ 164, "ff" ],
+[ 165, "fg" ],
+[ 166, "fh" ],
+[ 167, "fi" ],
+[ 168, "fj" ],
+[ 169, "fk" ],
+[ 170, "fl" ],
+[ 171, "fm" ],
+[ 172, "fn" ],
+[ 173, "fo" ],
+[ 174, "fp" ],
+[ 175, "fq" ],
+[ 176, "fr" ],
+[ 177, "fs" ],
+[ 178, "ft" ],
+[ 179, "fu" ],
+[ 180, "fv" ],
+[ 181, "fw" ],
+[ 182, "fx" ],
+[ 183, "fy" ],
+[ 184, "fz" ],
+[ 185, "ga" ],
+[ 186, "gb" ],
+[ 187, "gc" ],
+[ 188, "gd" ],
+[ 189, "ge" ],
+[ 190, "gf" ],
+[ 191, "gg" ],
+[ 192, "gh" ],
+[ 193, "gi" ],
+[ 194, "gj" ],
+[ 195, "gk" ],
+[ 196, "gl" ],
+[ 197, "gm" ],
+[ 198, "gn" ],
+[ 199, "go" ],
+[ 200, "gp" ],
+[ 201, "gq" ],
+[ 202, "gr" ],
+[ 203, "gs" ],
+[ 204, "gt" ],
+[ 205, "gu" ],
+[ 206, "gv" ],
+[ 207, "gw" ],
+[ 208, "gx" ],
+[ 209, "gy" ],
+[ 210, "gz" ],
+[ 211, "ha" ],
+[ 212, "hb" ],
+[ 213, "hc" ],
+[ 214, "hd" ],
+[ 215, "he" ],
+[ 216, "hf" ],
+[ 217, "hg" ],
+[ 218, "hh" ],
+[ 219, "hi" ],
+[ 220, "hj" ],
+[ 221, "hk" ],
+[ 222, "hl" ],
+[ 223, "hm" ],
+[ 224, "hn" ],
+[ 225, "ho" ],
+[ 226, "hp" ],
+[ 227, "hq" ],
+[ 228, "hr" ],
+[ 229, "hs" ],
+[ 230, "ht" ],
+[ 231, "hu" ],
+[ 232, "hv" ],
+[ 233, "hw" ],
+[ 234, "hx" ],
+[ 235, "hy" ],
+[ 236, "hz" ],
+[ 237, "ia" ],
+[ 238, "ib" ],
+[ 239, "ic" ],
+[ 240, "id" ],
+[ 241, "ie" ],
+[ 242, "if" ],
+[ 243, "ig" ],
+[ 244, "ih" ],
+[ 245, "ii" ],
+[ 246, "ij" ],
+[ 247, "ik" ],
+[ 248, "il" ],
+[ 249, "im" ],
+[ 250, "in" ],
+[ 251, "io" ],
+[ 252, "ip" ],
+[ 253, "iq" ],
+[ 254, "ir" ],
+[ 255, "is" ],
+[ 256, "it" ],
+[ 257, "iu" ],
+[ 258, "iv" ],
+[ 259, "iw" ],
+[ 260, "ix" ],
+[ 261, "iy" ],
+[ 262, "iz" ],
+[ 263, "ja" ],
+[ 264, "jb" ],
+[ 265, "jc" ],
+[ 266, "jd" ],
+[ 267, "je" ],
+[ 268, "jf" ],
+[ 269, "jg" ],
+[ 270, "jh" ],
+[ 271, "ji" ],
+[ 272, "jj" ],
+[ 273, "jk" ],
+[ 274, "jl" ],
+[ 275, "jm" ],
+[ 276, "jn" ],
+[ 277, "jo" ],
+[ 278, "jp" ],
+[ 279, "jq" ],
+[ 280, "jr" ],
+[ 281, "js" ],
+[ 282, "jt" ],
+[ 283, "ju" ],
+[ 284, "jv" ],
+[ 285, "jw" ],
+[ 286, "jx" ],
+[ 287, "jy" ],
+[ 288, "jz" ],
+[ 289, "ka" ],
+[ 290, "kb" ],
+[ 291, "kc" ],
+[ 292, "kd" ],
+[ 293, "ke" ],
+[ 294, "kf" ],
+[ 295, "kg" ],
+[ 296, "kh" ],
+[ 297, "ki" ],
+[ 298, "kj" ],
+[ 299, "kk" ],
+[ 300, "kl" ],
+[ 301, "km" ],
+[ 302, "kn" ],
+[ 303, "ko" ],
+[ 304, "kp" ],
+[ 305, "kq" ],
+[ 306, "kr" ],
+[ 307, "ks" ],
+[ 308, "kt" ],
+[ 309, "ku" ],
+[ 310, "kv" ],
+[ 311, "kw" ],
+[ 312, "kx" ],
+[ 313, "ky" ],
+[ 314, "kz" ],
+[ 315, "la" ],
+[ 316, "lb" ],
+[ 317, "lc" ],
+[ 318, "ld" ],
+[ 319, "le" ],
+[ 320, "lf" ],
+[ 321, "lg" ],
+[ 322, "lh" ],
+[ 323, "li" ],
+[ 324, "lj" ],
+[ 325, "lk" ],
+[ 326, "ll" ],
+[ 327, "lm" ],
+[ 328, "ln" ],
+[ 329, "lo" ],
+[ 330, "lp" ],
+[ 331, "lq" ],
+[ 332, "lr" ],
+[ 333, "ls" ],
+[ 334, "lt" ],
+[ 335, "lu" ],
+[ 336, "lv" ],
+[ 337, "lw" ],
+[ 338, "lx" ],
+[ 339, "ly" ],
+[ 340, "lz" ],
+[ 341, "ma" ],
+[ 342, "mb" ],
+[ 343, "mc" ],
+[ 344, "md" ],
+[ 345, "me" ],
+[ 346, "mf" ],
+[ 347, "mg" ],
+[ 348, "mh" ],
+[ 349, "mi" ],
+[ 350, "mj" ],
+[ 351, "mk" ],
+[ 352, "ml" ],
+[ 353, "mm" ],
+[ 354, "mn" ],
+[ 355, "mo" ],
+[ 356, "mp" ],
+[ 357, "mq" ],
+[ 358, "mr" ],
+[ 359, "ms" ],
+[ 360, "mt" ],
+[ 361, "mu" ],
+[ 362, "mv" ],
+[ 363, "mw" ],
+[ 364, "mx" ],
+[ 365, "my" ],
+[ 366, "mz" ],
+[ 367, "na" ],
+[ 368, "nb" ],
+[ 369, "nc" ],
+[ 370, "nd" ],
+[ 371, "ne" ],
+[ 372, "nf" ],
+[ 373, "ng" ],
+[ 374, "nh" ],
+[ 375, "ni" ],
+[ 376, "nj" ],
+[ 377, "nk" ],
+[ 378, "nl" ],
+[ 379, "nm" ],
+[ 380, "nn" ],
+[ 381, "no" ],
+[ 382, "np" ],
+[ 383, "nq" ],
+[ 384, "nr" ],
+[ 385, "ns" ],
+[ 386, "nt" ],
+[ 387, "nu" ],
+[ 388, "nv" ],
+[ 389, "nw" ],
+[ 390, "nx" ],
+[ 391, "ny" ],
+[ 392, "nz" ],
+[ 393, "oa" ],
+[ 394, "ob" ],
+[ 395, "oc" ],
+[ 396, "od" ],
+[ 397, "oe" ],
+[ 398, "of" ],
+[ 399, "og" ],
+[ 400, "oh" ],
+[ 401, "oi" ],
+[ 402, "oj" ],
+[ 403, "ok" ],
+[ 404, "ol" ],
+[ 405, "om" ],
+[ 406, "on" ],
+[ 407, "oo" ],
+[ 408, "op" ],
+[ 409, "oq" ],
+[ 410, "or" ],
+[ 411, "os" ],
+[ 412, "ot" ],
+[ 413, "ou" ],
+[ 414, "ov" ],
+[ 415, "ow" ],
+[ 416, "ox" ],
+[ 417, "oy" ],
+[ 418, "oz" ],
+[ 419, "pa" ],
+[ 420, "pb" ],
+[ 421, "pc" ],
+[ 422, "pd" ],
+[ 423, "pe" ],
+[ 424, "pf" ],
+[ 425, "pg" ],
+[ 426, "ph" ],
+[ 427, "pi" ],
+[ 428, "pj" ],
+[ 429, "pk" ],
+[ 430, "pl" ],
+[ 431, "pm" ],
+[ 432, "pn" ],
+[ 433, "po" ],
+[ 434, "pp" ],
+[ 435, "pq" ],
+[ 436, "pr" ],
+[ 437, "ps" ],
+[ 438, "pt" ],
+[ 439, "pu" ],
+[ 440, "pv" ],
+[ 441, "pw" ],
+[ 442, "px" ],
+[ 443, "py" ],
+[ 444, "pz" ],
+[ 445, "qa" ],
+[ 446, "qb" ],
+[ 447, "qc" ],
+[ 448, "qd" ],
+[ 449, "qe" ],
+[ 450, "qf" ],
+[ 451, "qg" ],
+[ 452, "qh" ],
+[ 453, "qi" ],
+[ 454, "qj" ],
+[ 455, "qk" ],
+[ 456, "ql" ],
+[ 457, "qm" ],
+[ 458, "qn" ],
+[ 459, "qo" ],
+[ 460, "qp" ],
+[ 461, "qq" ],
+[ 462, "qr" ],
+[ 463, "qs" ],
+[ 464, "qt" ],
+[ 465, "qu" ],
+[ 466, "qv" ],
+[ 467, "qw" ],
+[ 468, "qx" ],
+[ 469, "qy" ],
+[ 470, "qz" ],
+[ 471, "ra" ],
+[ 472, "rb" ],
+[ 473, "rc" ],
+[ 474, "rd" ],
+[ 475, "re" ],
+[ 476, "rf" ],
+[ 477, "rg" ],
+[ 478, "rh" ],
+[ 479, "ri" ],
+[ 480, "rj" ],
+[ 481, "rk" ],
+[ 482, "rl" ],
+[ 483, "rm" ],
+[ 484, "rn" ],
+[ 485, "ro" ],
+[ 486, "rp" ],
+[ 487, "rq" ],
+[ 488, "rr" ],
+[ 489, "rs" ],
+[ 490, "rt" ],
+[ 491, "ru" ],
+[ 492, "rv" ],
+[ 493, "rw" ],
+[ 494, "rx" ],
+[ 495, "ry" ],
+[ 496, "rz" ],
+[ 497, "sa" ],
+[ 498, "sb" ],
+[ 499, "sc" ],
+[ 500, "sd" ],
+[ 501, "se" ],
+[ 502, "sf" ],
+[ 503, "sg" ],
+[ 504, "sh" ],
+[ 505, "si" ],
+[ 506, "sj" ],
+[ 507, "sk" ],
+[ 508, "sl" ],
+[ 509, "sm" ],
+[ 510, "sn" ],
+[ 511, "so" ],
+[ 512, "sp" ],
+[ 513, "sq" ],
+[ 514, "sr" ],
+[ 515, "ss" ],
+[ 516, "st" ],
+[ 517, "su" ],
+[ 518, "sv" ],
+[ 519, "sw" ],
+[ 520, "sx" ],
+[ 521, "sy" ],
+[ 522, "sz" ],
+[ 523, "ta" ],
+[ 524, "tb" ],
+[ 525, "tc" ],
+[ 526, "td" ],
+[ 527, "te" ],
+[ 528, "tf" ],
+[ 529, "tg" ],
+[ 530, "th" ],
+[ 531, "ti" ],
+[ 532, "tj" ],
+[ 533, "tk" ],
+[ 534, "tl" ],
+[ 535, "tm" ],
+[ 536, "tn" ],
+[ 537, "to" ],
+[ 538, "tp" ],
+[ 539, "tq" ],
+[ 540, "tr" ],
+[ 541, "ts" ],
+[ 542, "tt" ],
+[ 543, "tu" ],
+[ 544, "tv" ],
+[ 545, "tw" ],
+[ 546, "tx" ],
+[ 547, "ty" ],
+[ 548, "tz" ],
+[ 549, "ua" ],
+[ 550, "ub" ],
+[ 551, "uc" ],
+[ 552, "ud" ],
+[ 553, "ue" ],
+[ 554, "uf" ],
+[ 555, "ug" ],
+[ 556, "uh" ],
+[ 557, "ui" ],
+[ 558, "uj" ],
+[ 559, "uk" ],
+[ 560, "ul" ],
+[ 561, "um" ],
+[ 562, "un" ],
+[ 563, "uo" ],
+[ 564, "up" ],
+[ 565, "uq" ],
+[ 566, "ur" ],
+[ 567, "us" ],
+[ 568, "ut" ],
+[ 569, "uu" ],
+[ 570, "uv" ],
+[ 571, "uw" ],
+[ 572, "ux" ],
+[ 573, "uy" ],
+[ 574, "uz" ],
+[ 575, "va" ],
+[ 576, "vb" ],
+[ 577, "vc" ],
+[ 578, "vd" ],
+[ 579, "ve" ],
+[ 580, "vf" ],
+[ 581, "vg" ],
+[ 582, "vh" ],
+[ 583, "vi" ],
+[ 584, "vj" ],
+[ 585, "vk" ],
+[ 586, "vl" ],
+[ 587, "vm" ],
+[ 588, "vn" ],
+[ 589, "vo" ],
+[ 590, "vp" ],
+[ 591, "vq" ],
+[ 592, "vr" ],
+[ 593, "vs" ],
+[ 594, "vt" ],
+[ 595, "vu" ],
+[ 596, "vv" ],
+[ 597, "vw" ],
+[ 598, "vx" ],
+[ 599, "vy" ],
+[ 600, "vz" ],
+[ 601, "wa" ],
+[ 602, "wb" ],
+[ 603, "wc" ],
+[ 604, "wd" ],
+[ 605, "we" ],
+[ 606, "wf" ],
+[ 607, "wg" ],
+[ 608, "wh" ],
+[ 609, "wi" ],
+[ 610, "wj" ],
+[ 611, "wk" ],
+[ 612, "wl" ],
+[ 613, "wm" ],
+[ 614, "wn" ],
+[ 615, "wo" ],
+[ 616, "wp" ],
+[ 617, "wq" ],
+[ 618, "wr" ],
+[ 619, "ws" ],
+[ 620, "wt" ],
+[ 621, "wu" ],
+[ 622, "wv" ],
+[ 623, "ww" ],
+[ 624, "wx" ],
+[ 625, "wy" ],
+[ 626, "wz" ],
+[ 627, "xa" ],
+[ 628, "xb" ],
+[ 629, "xc" ],
+[ 630, "xd" ],
+[ 631, "xe" ],
+[ 632, "xf" ],
+[ 633, "xg" ],
+[ 634, "xh" ],
+[ 635, "xi" ],
+[ 636, "xj" ],
+[ 637, "xk" ],
+[ 638, "xl" ],
+[ 639, "xm" ],
+[ 640, "xn" ],
+[ 641, "xo" ],
+[ 642, "xp" ],
+[ 643, "xq" ],
+[ 644, "xr" ],
+[ 645, "xs" ],
+[ 646, "xt" ],
+[ 647, "xu" ],
+[ 648, "xv" ],
+[ 649, "xw" ],
+[ 650, "xx" ],
+[ 651, "xy" ],
+[ 652, "xz" ],
+[ 653, "ya" ],
+[ 654, "yb" ],
+[ 655, "yc" ],
+[ 656, "yd" ],
+[ 657, "ye" ],
+[ 658, "yf" ],
+[ 659, "yg" ],
+[ 660, "yh" ],
+[ 661, "yi" ],
+[ 662, "yj" ],
+[ 663, "yk" ],
+[ 664, "yl" ],
+[ 665, "ym" ],
+[ 666, "yn" ],
+[ 667, "yo" ],
+[ 668, "yp" ],
+[ 669, "yq" ],
+[ 670, "yr" ],
+[ 671, "ys" ],
+[ 672, "yt" ],
+[ 673, "yu" ],
+[ 674, "yv" ],
+[ 675, "yw" ],
+[ 676, "yx" ],
+[ 677, "yy" ],
+[ 678, "yz" ],
+[ 679, "za" ],
+[ 680, "zb" ],
+[ 681, "zc" ],
+[ 682, "zd" ],
+[ 683, "ze" ],
+[ 684, "zf" ],
+[ 685, "zg" ],
+[ 686, "zh" ],
+[ 687, "zi" ],
+[ 688, "zj" ],
+[ 689, "zk" ],
+[ 690, "zl" ],
+[ 691, "zm" ],
+[ 692, "zn" ],
+[ 693, "zo" ],
+[ 694, "zp" ],
+[ 695, "zq" ],
+[ 696, "zr" ],
+[ 697, "zs" ],
+[ 698, "zt" ],
+[ 699, "zu" ],
+[ 700, "zv" ],
+[ 701, "zw" ],
+[ 702, "zx" ],
+[ 703, "zy" ],
+[ 704, "zz" ],
+[ 705, "aaa" ],
+[ 706, "aab" ],
+[ 707, "aac" ],
+[ 708, "aad" ],
+[ 709, "aae" ],
+[ 710, "aaf" ],
+[ 711, "aag" ],
+[ 712, "aah" ],
+[ 713, "aai" ],
+[ 714, "aaj" ],
+[ 715, "aak" ],
+[ 716, "aal" ],
+[ 717, "aam" ],
+[ 718, "aan" ],
+[ 719, "aao" ],
+[ 720, "aap" ],
+[ 721, "aaq" ],
+[ 722, "aar" ],
+[ 723, "aas" ],
+[ 724, "aat" ],
+[ 725, "aau" ],
+[ 726, "aav" ],
+[ 727, "aaw" ],
+[ 728, "aax" ],
+[ 729, "aay" ],
+[ 730, "aaz" ],
+[ 731, "aba" ],
+[ 732, "abb" ],
+[ 733, "abc" ],
+[ 734, "abd" ],
+[ 735, "abe" ],
+[ 736, "abf" ],
+[ 737, "abg" ],
+[ 738, "abh" ],
+[ 739, "abi" ],
+[ 740, "abj" ],
+[ 741, "abk" ],
+[ 742, "abl" ],
+[ 743, "abm" ],
+[ 744, "abn" ],
+[ 745, "abo" ],
+[ 746, "abp" ],
+[ 747, "abq" ],
+[ 748, "abr" ],
+[ 749, "abs" ],
+[ 750, "abt" ],
+[ 751, "abu" ],
+[ 752, "abv" ],
+[ 753, "abw" ],
+[ 754, "abx" ],
+[ 755, "aby" ],
+[ 756, "abz" ],
+[ 757, "aca" ],
+[ 758, "acb" ],
+[ 759, "acc" ],
+[ 760, "acd" ],
+[ 761, "ace" ],
+[ 762, "acf" ],
+[ 763, "acg" ],
+[ 764, "ach" ],
+[ 765, "aci" ],
+[ 766, "acj" ],
+[ 767, "ack" ],
+[ 768, "acl" ],
+[ 769, "acm" ],
+[ 770, "acn" ],
+[ 771, "aco" ],
+[ 772, "acp" ],
+[ 773, "acq" ],
+[ 774, "acr" ],
+[ 775, "acs" ],
+[ 776, "act" ],
+[ 777, "acu" ],
+[ 778, "acv" ],
+[ 779, "acw" ],
+[ 780, "acx" ],
+[ 781, "acy" ],
+[ 782, "acz" ],
+[ 783, "ada" ],
+[ 784, "adb" ],
+[ 785, "adc" ],
+[ 786, "add" ],
+[ 787, "ade" ],
+[ 788, "adf" ],
+[ 789, "adg" ],
+[ 790, "adh" ],
+[ 791, "adi" ],
+[ 792, "adj" ],
+[ 793, "adk" ],
+[ 794, "adl" ],
+[ 795, "adm" ],
+[ 796, "adn" ],
+[ 797, "ado" ],
+[ 798, "adp" ],
+[ 799, "adq" ],
+[ 800, "adr" ],
+[ 801, "ads" ],
+[ 802, "adt" ],
+[ 803, "adu" ],
+[ 804, "adv" ],
+[ 805, "adw" ],
+[ 806, "adx" ],
+[ 807, "ady" ],
+[ 808, "adz" ],
+[ 809, "aea" ],
+[ 810, "aeb" ],
+[ 811, "aec" ],
+[ 812, "aed" ],
+[ 813, "aee" ],
+[ 814, "aef" ],
+[ 815, "aeg" ],
+[ 816, "aeh" ],
+[ 817, "aei" ],
+[ 818, "aej" ],
+[ 819, "aek" ],
+[ 820, "ael" ],
+[ 821, "aem" ],
+[ 822, "aen" ],
+[ 823, "aeo" ],
+[ 824, "aep" ],
+[ 825, "aeq" ],
+[ 826, "aer" ],
+[ 827, "aes" ],
+[ 828, "aet" ],
+[ 829, "aeu" ],
+[ 830, "aev" ],
+[ 831, "aew" ],
+[ 832, "aex" ],
+[ 833, "aey" ],
+[ 834, "aez" ],
+[ 835, "afa" ],
+[ 836, "afb" ],
+[ 837, "afc" ],
+[ 838, "afd" ],
+[ 839, "afe" ],
+[ 840, "aff" ],
+[ 841, "afg" ],
+[ 842, "afh" ],
+[ 843, "afi" ],
+[ 844, "afj" ],
+[ 845, "afk" ],
+[ 846, "afl" ],
+[ 847, "afm" ],
+[ 848, "afn" ],
+[ 849, "afo" ],
+[ 850, "afp" ],
+[ 851, "afq" ],
+[ 852, "afr" ],
+[ 853, "afs" ],
+[ 854, "aft" ],
+[ 855, "afu" ],
+[ 856, "afv" ],
+[ 857, "afw" ],
+[ 858, "afx" ],
+[ 859, "afy" ],
+[ 860, "afz" ],
+[ 861, "aga" ],
+[ 862, "agb" ],
+[ 863, "agc" ],
+[ 864, "agd" ],
+[ 865, "age" ],
+[ 866, "agf" ],
+[ 867, "agg" ],
+[ 868, "agh" ],
+[ 869, "agi" ],
+[ 870, "agj" ],
+[ 871, "agk" ],
+[ 872, "agl" ],
+[ 873, "agm" ],
+[ 874, "agn" ],
+[ 875, "ago" ],
+[ 876, "agp" ],
+[ 877, "agq" ],
+[ 878, "agr" ],
+[ 879, "ags" ],
+[ 880, "agt" ],
+[ 881, "agu" ],
+[ 882, "agv" ],
+[ 883, "agw" ],
+[ 884, "agx" ],
+[ 885, "agy" ],
+[ 886, "agz" ],
+[ 887, "aha" ],
+[ 888, "ahb" ],
+[ 889, "ahc" ],
+[ 890, "ahd" ],
+[ 891, "ahe" ],
+[ 892, "ahf" ],
+[ 893, "ahg" ],
+[ 894, "ahh" ],
+[ 895, "ahi" ],
+[ 896, "ahj" ],
+[ 897, "ahk" ],
+[ 898, "ahl" ],
+[ 899, "ahm" ],
+[ 900, "ahn" ],
+[ 901, "aho" ],
+[ 902, "ahp" ],
+[ 903, "ahq" ],
+[ 904, "ahr" ],
+[ 905, "ahs" ],
+[ 906, "aht" ],
+[ 907, "ahu" ],
+[ 908, "ahv" ],
+[ 909, "ahw" ],
+[ 910, "ahx" ],
+[ 911, "ahy" ],
+[ 912, "ahz" ],
+[ 913, "aia" ],
+[ 914, "aib" ],
+[ 915, "aic" ],
+[ 916, "aid" ],
+[ 917, "aie" ],
+[ 918, "aif" ],
+[ 919, "aig" ],
+[ 920, "aih" ],
+[ 921, "aii" ],
+[ 922, "aij" ],
+[ 923, "aik" ],
+[ 924, "ail" ],
+[ 925, "aim" ],
+[ 926, "ain" ],
+[ 927, "aio" ],
+[ 928, "aip" ],
+[ 929, "aiq" ],
+[ 930, "air" ],
+[ 931, "ais" ],
+[ 932, "ait" ],
+[ 933, "aiu" ],
+[ 934, "aiv" ],
+[ 935, "aiw" ],
+[ 936, "aix" ],
+[ 937, "aiy" ],
+[ 938, "aiz" ],
+[ 939, "aja" ],
+[ 940, "ajb" ],
+[ 941, "ajc" ],
+[ 942, "ajd" ],
+[ 943, "aje" ],
+[ 944, "ajf" ],
+[ 945, "ajg" ],
+[ 946, "ajh" ],
+[ 947, "aji" ],
+[ 948, "ajj" ],
+[ 949, "ajk" ],
+[ 950, "ajl" ],
+[ 951, "ajm" ],
+[ 952, "ajn" ],
+[ 953, "ajo" ],
+[ 954, "ajp" ],
+[ 955, "ajq" ],
+[ 956, "ajr" ],
+[ 957, "ajs" ],
+[ 958, "ajt" ],
+[ 959, "aju" ],
+[ 960, "ajv" ],
+[ 961, "ajw" ],
+[ 962, "ajx" ],
+[ 963, "ajy" ],
+[ 964, "ajz" ],
+[ 965, "aka" ],
+[ 966, "akb" ],
+[ 967, "akc" ],
+[ 968, "akd" ],
+[ 969, "ake" ],
+[ 970, "akf" ],
+[ 971, "akg" ],
+[ 972, "akh" ],
+[ 973, "aki" ],
+[ 974, "akj" ],
+[ 975, "akk" ],
+[ 976, "akl" ],
+[ 977, "akm" ],
+[ 978, "akn" ],
+[ 979, "ako" ],
+[ 980, "akp" ],
+[ 981, "akq" ],
+[ 982, "akr" ],
+[ 983, "aks" ],
+[ 984, "akt" ],
+[ 985, "aku" ],
+[ 986, "akv" ],
+[ 987, "akw" ],
+[ 988, "akx" ],
+[ 989, "aky" ],
+[ 990, "akz" ],
+[ 991, "ala" ],
+[ 992, "alb" ],
+[ 993, "alc" ],
+[ 994, "ald" ],
+[ 995, "ale" ],
+[ 996, "alf" ],
+[ 997, "alg" ],
+[ 998, "alh" ],
+[ 999, "ali" ],
+[ 1000, "alj" ],
+[ 1001, "alk" ],
+[ 1002, "all" ],
+[ 1003, "alm" ],
+[ 1004, "aln" ],
+[ 1005, "alo" ],
+[ 1006, "alp" ],
+[ 1007, "alq" ],
+[ 1008, "alr" ],
+[ 1009, "als" ],
+[ 1010, "alt" ],
+[ 1011, "alu" ],
+[ 1012, "alv" ],
+[ 1013, "alw" ],
+[ 1014, "alx" ],
+[ 1015, "aly" ],
+[ 1016, "alz" ],
+[ 1017, "ama" ],
+[ 1018, "amb" ],
+[ 1019, "amc" ],
+[ 1020, "amd" ],
+[ 1021, "ame" ],
+[ 1022, "amf" ],
+[ 1023, "amg" ],
+[ 1024, "amh" ],
+[ 1025, "ami" ],
+[ 1026, "amj" ],
+[ 1027, "amk" ],
+[ 1028, "aml" ],
+[ 1029, "amm" ],
+[ 1030, "amn" ],
+[ 1031, "amo" ],
+[ 1032, "amp" ],
+[ 1033, "amq" ],
+[ 1034, "amr" ],
+[ 1035, "ams" ],
+[ 1036, "amt" ],
+[ 1037, "amu" ],
+[ 1038, "amv" ],
+[ 1039, "amw" ],
+[ 1040, "amx" ],
+[ 1041, "amy" ],
+[ 1042, "amz" ],
+[ 1043, "ana" ],
+[ 1044, "anb" ],
+[ 1045, "anc" ],
+[ 1046, "and" ],
+[ 1047, "ane" ],
+[ 1048, "anf" ],
+[ 1049, "ang" ],
+[ 1050, "anh" ],
+[ 1051, "ani" ],
+[ 1052, "anj" ],
+[ 1053, "ank" ],
+[ 1054, "anl" ],
+[ 1055, "anm" ],
+[ 1056, "ann" ],
+[ 1057, "ano" ],
+[ 1058, "anp" ],
+[ 1059, "anq" ],
+[ 1060, "anr" ],
+[ 1061, "ans" ],
+[ 1062, "ant" ],
+[ 1063, "anu" ],
+[ 1064, "anv" ],
+[ 1065, "anw" ],
+[ 1066, "anx" ],
+[ 1067, "any" ],
+[ 1068, "anz" ],
+[ 1069, "aoa" ],
+[ 1070, "aob" ],
+[ 1071, "aoc" ],
+[ 1072, "aod" ],
+[ 1073, "aoe" ],
+[ 1074, "aof" ],
+[ 1075, "aog" ],
+[ 1076, "aoh" ],
+[ 1077, "aoi" ],
+[ 1078, "aoj" ],
+[ 1079, "aok" ],
+[ 1080, "aol" ],
+[ 1081, "aom" ],
+[ 1082, "aon" ],
+[ 1083, "aoo" ],
+[ 1084, "aop" ],
+[ 1085, "aoq" ],
+[ 1086, "aor" ],
+[ 1087, "aos" ],
+[ 1088, "aot" ],
+[ 1089, "aou" ],
+[ 1090, "aov" ],
+[ 1091, "aow" ],
+[ 1092, "aox" ],
+[ 1093, "aoy" ],
+[ 1094, "aoz" ],
+[ 1095, "apa" ],
+[ 1096, "apb" ],
+[ 1097, "apc" ],
+[ 1098, "apd" ],
+[ 1099, "ape" ],
+[ 1100, "apf" ],
+[ 1101, "apg" ],
+[ 1102, "aph" ],
+[ 1103, "api" ],
+[ 1104, "apj" ],
+[ 1105, "apk" ],
+[ 1106, "apl" ],
+[ 1107, "apm" ],
+[ 1108, "apn" ],
+[ 1109, "apo" ],
+[ 1110, "app" ],
+[ 1111, "apq" ],
+[ 1112, "apr" ],
+[ 1113, "aps" ],
+[ 1114, "apt" ],
+[ 1115, "apu" ],
+[ 1116, "apv" ],
+[ 1117, "apw" ],
+[ 1118, "apx" ],
+[ 1119, "apy" ],
+[ 1120, "apz" ],
+[ 1121, "aqa" ],
+[ 1122, "aqb" ],
+[ 1123, "aqc" ],
+[ 1124, "aqd" ],
+[ 1125, "aqe" ],
+[ 1126, "aqf" ],
+[ 1127, "aqg" ],
+[ 1128, "aqh" ],
+[ 1129, "aqi" ],
+[ 1130, "aqj" ],
+[ 1131, "aqk" ],
+[ 1132, "aql" ],
+[ 1133, "aqm" ],
+[ 1134, "aqn" ],
+[ 1135, "aqo" ],
+[ 1136, "aqp" ],
+[ 1137, "aqq" ],
+[ 1138, "aqr" ],
+[ 1139, "aqs" ],
+[ 1140, "aqt" ],
+[ 1141, "aqu" ],
+[ 1142, "aqv" ],
+[ 1143, "aqw" ],
+[ 1144, "aqx" ],
+[ 1145, "aqy" ],
+[ 1146, "aqz" ],
+[ 1147, "ara" ],
+[ 1148, "arb" ],
+[ 1149, "arc" ],
+[ 1150, "ard" ],
+[ 1151, "are" ],
+[ 1152, "arf" ],
+[ 1153, "arg" ],
+[ 1154, "arh" ],
+[ 1155, "ari" ],
+[ 1156, "arj" ],
+[ 1157, "ark" ],
+[ 1158, "arl" ],
+[ 1159, "arm" ],
+[ 1160, "arn" ],
+[ 1161, "aro" ],
+[ 1162, "arp" ],
+[ 1163, "arq" ],
+[ 1164, "arr" ],
+[ 1165, "ars" ],
+[ 1166, "art" ],
+[ 1167, "aru" ],
+[ 1168, "arv" ],
+[ 1169, "arw" ],
+[ 1170, "arx" ],
+[ 1171, "ary" ],
+[ 1172, "arz" ],
+[ 1173, "asa" ],
+[ 1174, "asb" ],
+[ 1175, "asc" ],
+[ 1176, "asd" ],
+[ 1177, "ase" ],
+[ 1178, "asf" ],
+[ 1179, "asg" ],
+[ 1180, "ash" ],
+[ 1181, "asi" ],
+[ 1182, "asj" ],
+[ 1183, "ask" ],
+[ 1184, "asl" ],
+[ 1185, "asm" ],
+[ 1186, "asn" ],
+[ 1187, "aso" ],
+[ 1188, "asp" ],
+[ 1189, "asq" ],
+[ 1190, "asr" ],
+[ 1191, "ass" ],
+[ 1192, "ast" ],
+[ 1193, "asu" ],
+[ 1194, "asv" ],
+[ 1195, "asw" ],
+[ 1196, "asx" ],
+[ 1197, "asy" ],
+[ 1198, "asz" ],
+[ 1199, "ata" ],
+[ 1200, "atb" ],
+[ 1201, "atc" ],
+[ 1202, "atd" ],
+[ 1203, "ate" ],
+[ 1204, "atf" ],
+[ 1205, "atg" ],
+[ 1206, "ath" ],
+[ 1207, "ati" ],
+[ 1208, "atj" ],
+[ 1209, "atk" ],
+[ 1210, "atl" ],
+[ 1211, "atm" ],
+[ 1212, "atn" ],
+[ 1213, "ato" ],
+[ 1214, "atp" ],
+[ 1215, "atq" ],
+[ 1216, "atr" ],
+[ 1217, "ats" ],
+[ 1218, "att" ],
+[ 1219, "atu" ],
+[ 1220, "atv" ],
+[ 1221, "atw" ],
+[ 1222, "atx" ],
+[ 1223, "aty" ],
+[ 1224, "atz" ],
+[ 1225, "aua" ],
+[ 1226, "aub" ],
+[ 1227, "auc" ],
+[ 1228, "aud" ],
+[ 1229, "aue" ],
+[ 1230, "auf" ],
+[ 1231, "aug" ],
+[ 1232, "auh" ],
+[ 1233, "aui" ],
+[ 1234, "auj" ],
+[ 1235, "auk" ],
+[ 1236, "aul" ],
+[ 1237, "aum" ],
+[ 1238, "aun" ],
+[ 1239, "auo" ],
+[ 1240, "aup" ],
+[ 1241, "auq" ],
+[ 1242, "aur" ],
+[ 1243, "aus" ],
+[ 1244, "aut" ],
+[ 1245, "auu" ],
+[ 1246, "auv" ],
+[ 1247, "auw" ],
+[ 1248, "aux" ],
+[ 1249, "auy" ],
+[ 1250, "auz" ],
+[ 1251, "ava" ],
+[ 1252, "avb" ],
+[ 1253, "avc" ],
+[ 1254, "avd" ],
+[ 1255, "ave" ],
+[ 1256, "avf" ],
+[ 1257, "avg" ],
+[ 1258, "avh" ],
+[ 1259, "avi" ],
+[ 1260, "avj" ],
+[ 1261, "avk" ],
+[ 1262, "avl" ],
+[ 1263, "avm" ],
+[ 1264, "avn" ],
+[ 1265, "avo" ],
+[ 1266, "avp" ],
+[ 1267, "avq" ],
+[ 1268, "avr" ],
+[ 1269, "avs" ],
+[ 1270, "avt" ],
+[ 1271, "avu" ],
+[ 1272, "avv" ],
+[ 1273, "avw" ],
+[ 1274, "avx" ],
+[ 1275, "avy" ],
+[ 1276, "avz" ],
+[ 1277, "awa" ],
+[ 1278, "awb" ],
+[ 1279, "awc" ],
+[ 1280, "awd" ],
+[ 1281, "awe" ],
+[ 1282, "awf" ],
+[ 1283, "awg" ],
+[ 1284, "awh" ],
+[ 1285, "awi" ],
+[ 1286, "awj" ],
+[ 1287, "awk" ],
+[ 1288, "awl" ],
+[ 1289, "awm" ],
+[ 1290, "awn" ],
+[ 1291, "awo" ],
+[ 1292, "awp" ],
+[ 1293, "awq" ],
+[ 1294, "awr" ],
+[ 1295, "aws" ],
+[ 1296, "awt" ],
+[ 1297, "awu" ],
+[ 1298, "awv" ],
+[ 1299, "aww" ],
+[ 1300, "awx" ],
+[ 1301, "awy" ],
+[ 1302, "awz" ],
+[ 1303, "axa" ],
+[ 1304, "axb" ],
+[ 1305, "axc" ],
+[ 1306, "axd" ],
+[ 1307, "axe" ],
+[ 1308, "axf" ],
+[ 1309, "axg" ],
+[ 1310, "axh" ],
+[ 1311, "axi" ],
+[ 1312, "axj" ],
+[ 1313, "axk" ],
+[ 1314, "axl" ],
+[ 1315, "axm" ],
+[ 1316, "axn" ],
+[ 1317, "axo" ],
+[ 1318, "axp" ],
+[ 1319, "axq" ],
+[ 1320, "axr" ],
+[ 1321, "axs" ],
+[ 1322, "axt" ],
+[ 1323, "axu" ],
+[ 1324, "axv" ],
+[ 1325, "axw" ],
+[ 1326, "axx" ],
+[ 1327, "axy" ],
+[ 1328, "axz" ],
+[ 1329, "aya" ],
+[ 1330, "ayb" ],
+[ 1331, "ayc" ],
+[ 1332, "ayd" ],
+[ 1333, "aye" ],
+[ 1334, "ayf" ],
+[ 1335, "ayg" ],
+[ 1336, "ayh" ],
+[ 1337, "ayi" ],
+[ 1338, "ayj" ],
+[ 1339, "ayk" ],
+[ 1340, "ayl" ],
+[ 1341, "aym" ],
+[ 1342, "ayn" ],
+[ 1343, "ayo" ],
+[ 1344, "ayp" ],
+[ 1345, "ayq" ],
+[ 1346, "ayr" ],
+[ 1347, "ays" ],
+[ 1348, "ayt" ],
+[ 1349, "ayu" ],
+[ 1350, "ayv" ],
+[ 1351, "ayw" ],
+[ 1352, "ayx" ],
+[ 1353, "ayy" ],
+[ 1354, "ayz" ],
+[ 1355, "aza" ],
+[ 1356, "azb" ],
+[ 1357, "azc" ],
+[ 1358, "azd" ],
+[ 1359, "aze" ],
+[ 1360, "azf" ],
+[ 1361, "azg" ],
+[ 1362, "azh" ],
+[ 1363, "azi" ],
+[ 1364, "azj" ],
+[ 1365, "azk" ],
+[ 1366, "azl" ],
+[ 1367, "azm" ],
+[ 1368, "azn" ],
+[ 1369, "azo" ],
+[ 1370, "azp" ],
+[ 1371, "azq" ],
+[ 1372, "azr" ],
+[ 1373, "azs" ],
+[ 1374, "azt" ],
+[ 1375, "azu" ],
+[ 1376, "azv" ],
+[ 1377, "azw" ],
+[ 1378, "azx" ],
+[ 1379, "azy" ],
+[ 1380, "azz" ],
+[ 1381, "baa" ],
+[ 1382, "bab" ],
+[ 1383, "bac" ],
+[ 1384, "bad" ],
+[ 1385, "bae" ],
+[ 1386, "baf" ],
+[ 1387, "bag" ],
+[ 1388, "bah" ],
+[ 1389, "bai" ],
+[ 1390, "baj" ],
+[ 1391, "bak" ],
+[ 1392, "bal" ],
+[ 1393, "bam" ],
+[ 1394, "ban" ],
+[ 1395, "bao" ],
+[ 1396, "bap" ],
+[ 1397, "baq" ],
+[ 1398, "bar" ],
+[ 1399, "bas" ],
+[ 1400, "bat" ],
+[ 1401, "bau" ],
+[ 1402, "bav" ],
+[ 1403, "baw" ],
+[ 1404, "bax" ],
+[ 1405, "bay" ],
+[ 1406, "baz" ],
+[ 1407, "bba" ],
+[ 1408, "bbb" ],
+[ 1409, "bbc" ],
+[ 1410, "bbd" ],
+[ 1411, "bbe" ],
+[ 1412, "bbf" ],
+[ 1413, "bbg" ],
+[ 1414, "bbh" ],
+[ 1415, "bbi" ],
+[ 1416, "bbj" ],
+[ 1417, "bbk" ],
+[ 1418, "bbl" ],
+[ 1419, "bbm" ],
+[ 1420, "bbn" ],
+[ 1421, "bbo" ],
+[ 1422, "bbp" ],
+[ 1423, "bbq" ],
+[ 1424, "bbr" ],
+[ 1425, "bbs" ],
+[ 1426, "bbt" ],
+[ 1427, "bbu" ],
+[ 1428, "bbv" ],
+[ 1429, "bbw" ],
+[ 1430, "bbx" ],
+[ 1431, "bby" ],
+[ 1432, "bbz" ],
+[ 1433, "bca" ],
+[ 1434, "bcb" ],
+[ 1435, "bcc" ],
+[ 1436, "bcd" ],
+[ 1437, "bce" ],
+[ 1438, "bcf" ],
+[ 1439, "bcg" ],
+[ 1440, "bch" ],
+[ 1441, "bci" ],
+[ 1442, "bcj" ],
+[ 1443, "bck" ],
+[ 1444, "bcl" ],
+[ 1445, "bcm" ],
+[ 1446, "bcn" ],
+[ 1447, "bco" ],
+[ 1448, "bcp" ],
+[ 1449, "bcq" ],
+[ 1450, "bcr" ],
+[ 1451, "bcs" ],
+[ 1452, "bct" ],
+[ 1453, "bcu" ],
+[ 1454, "bcv" ],
+[ 1455, "bcw" ],
+[ 1456, "bcx" ],
+[ 1457, "bcy" ],
+[ 1458, "bcz" ],
+[ 1459, "bda" ],
+[ 1460, "bdb" ],
+[ 1461, "bdc" ],
+[ 1462, "bdd" ],
+[ 1463, "bde" ],
+[ 1464, "bdf" ],
+[ 1465, "bdg" ],
+[ 1466, "bdh" ],
+[ 1467, "bdi" ],
+[ 1468, "bdj" ],
+[ 1469, "bdk" ],
+[ 1470, "bdl" ],
+[ 1471, "bdm" ],
+[ 1472, "bdn" ],
+[ 1473, "bdo" ],
+[ 1474, "bdp" ],
+[ 1475, "bdq" ],
+[ 1476, "bdr" ],
+[ 1477, "bds" ],
+[ 1478, "bdt" ],
+[ 1479, "bdu" ],
+[ 1480, "bdv" ],
+[ 1481, "bdw" ],
+[ 1482, "bdx" ],
+[ 1483, "bdy" ],
+[ 1484, "bdz" ],
+[ 1485, "bea" ],
+[ 1486, "beb" ],
+[ 1487, "bec" ],
+[ 1488, "bed" ],
+[ 1489, "bee" ],
+[ 1490, "bef" ],
+[ 1491, "beg" ],
+[ 1492, "beh" ],
+[ 1493, "bei" ],
+[ 1494, "bej" ],
+[ 1495, "bek" ],
+[ 1496, "bel" ],
+[ 1497, "bem" ],
+[ 1498, "ben" ],
+[ 1499, "beo" ],
+[ 1500, "bep" ],
+[ 1501, "beq" ],
+[ 1502, "ber" ],
+[ 1503, "bes" ],
+[ 1504, "bet" ],
+[ 1505, "beu" ],
+[ 1506, "bev" ],
+[ 1507, "bew" ],
+[ 1508, "bex" ],
+[ 1509, "bey" ],
+[ 1510, "bez" ],
+[ 1511, "bfa" ],
+[ 1512, "bfb" ],
+[ 1513, "bfc" ],
+[ 1514, "bfd" ],
+[ 1515, "bfe" ],
+[ 1516, "bff" ],
+[ 1517, "bfg" ],
+[ 1518, "bfh" ],
+[ 1519, "bfi" ],
+[ 1520, "bfj" ],
+[ 1521, "bfk" ],
+[ 1522, "bfl" ],
+[ 1523, "bfm" ],
+[ 1524, "bfn" ],
+[ 1525, "bfo" ],
+[ 1526, "bfp" ],
+[ 1527, "bfq" ],
+[ 1528, "bfr" ],
+[ 1529, "bfs" ],
+[ 1530, "bft" ],
+[ 1531, "bfu" ],
+[ 1532, "bfv" ],
+[ 1533, "bfw" ],
+[ 1534, "bfx" ],
+[ 1535, "bfy" ],
+[ 1536, "bfz" ],
+[ 1537, "bga" ],
+[ 1538, "bgb" ],
+[ 1539, "bgc" ],
+[ 1540, "bgd" ],
+[ 1541, "bge" ],
+[ 1542, "bgf" ],
+[ 1543, "bgg" ],
+[ 1544, "bgh" ],
+[ 1545, "bgi" ],
+[ 1546, "bgj" ],
+[ 1547, "bgk" ],
+[ 1548, "bgl" ],
+[ 1549, "bgm" ],
+[ 1550, "bgn" ],
+[ 1551, "bgo" ],
+[ 1552, "bgp" ],
+[ 1553, "bgq" ],
+[ 1554, "bgr" ],
+[ 1555, "bgs" ],
+[ 1556, "bgt" ],
+[ 1557, "bgu" ],
+[ 1558, "bgv" ],
+[ 1559, "bgw" ],
+[ 1560, "bgx" ],
+[ 1561, "bgy" ],
+[ 1562, "bgz" ],
+[ 1563, "bha" ],
+[ 1564, "bhb" ],
+[ 1565, "bhc" ],
+[ 1566, "bhd" ],
+[ 1567, "bhe" ],
+[ 1568, "bhf" ],
+[ 1569, "bhg" ],
+[ 1570, "bhh" ],
+[ 1571, "bhi" ],
+[ 1572, "bhj" ],
+[ 1573, "bhk" ],
+[ 1574, "bhl" ],
+[ 1575, "bhm" ],
+[ 1576, "bhn" ],
+[ 1577, "bho" ],
+[ 1578, "bhp" ],
+[ 1579, "bhq" ],
+[ 1580, "bhr" ],
+[ 1581, "bhs" ],
+[ 1582, "bht" ],
+[ 1583, "bhu" ],
+[ 1584, "bhv" ],
+[ 1585, "bhw" ],
+[ 1586, "bhx" ],
+[ 1587, "bhy" ],
+[ 1588, "bhz" ],
+[ 1589, "bia" ],
+[ 1590, "bib" ],
+[ 1591, "bic" ],
+[ 1592, "bid" ],
+[ 1593, "bie" ],
+[ 1594, "bif" ],
+[ 1595, "big" ],
+[ 1596, "bih" ],
+[ 1597, "bii" ],
+[ 1598, "bij" ],
+[ 1599, "bik" ],
+[ 1600, "bil" ],
+[ 1601, "bim" ],
+[ 1602, "bin" ],
+[ 1603, "bio" ],
+[ 1604, "bip" ],
+[ 1605, "biq" ],
+[ 1606, "bir" ],
+[ 1607, "bis" ],
+[ 1608, "bit" ],
+[ 1609, "biu" ],
+[ 1610, "biv" ],
+[ 1611, "biw" ],
+[ 1612, "bix" ],
+[ 1613, "biy" ],
+[ 1614, "biz" ],
+[ 1615, "bja" ],
+[ 1616, "bjb" ],
+[ 1617, "bjc" ],
+[ 1618, "bjd" ],
+[ 1619, "bje" ],
+[ 1620, "bjf" ],
+[ 1621, "bjg" ],
+[ 1622, "bjh" ],
+[ 1623, "bji" ],
+[ 1624, "bjj" ],
+[ 1625, "bjk" ],
+[ 1626, "bjl" ],
+[ 1627, "bjm" ],
+[ 1628, "bjn" ],
+[ 1629, "bjo" ],
+[ 1630, "bjp" ],
+[ 1631, "bjq" ],
+[ 1632, "bjr" ],
+[ 1633, "bjs" ],
+[ 1634, "bjt" ],
+[ 1635, "bju" ],
+[ 1636, "bjv" ],
+[ 1637, "bjw" ],
+[ 1638, "bjx" ],
+[ 1639, "bjy" ],
+[ 1640, "bjz" ],
+[ 1641, "bka" ],
+[ 1642, "bkb" ],
+[ 1643, "bkc" ],
+[ 1644, "bkd" ],
+[ 1645, "bke" ],
+[ 1646, "bkf" ],
+[ 1647, "bkg" ],
+[ 1648, "bkh" ],
+[ 1649, "bki" ],
+[ 1650, "bkj" ],
+[ 1651, "bkk" ],
+[ 1652, "bkl" ],
+[ 1653, "bkm" ],
+[ 1654, "bkn" ],
+[ 1655, "bko" ],
+[ 1656, "bkp" ],
+[ 1657, "bkq" ],
+[ 1658, "bkr" ],
+[ 1659, "bks" ],
+[ 1660, "bkt" ],
+[ 1661, "bku" ],
+[ 1662, "bkv" ],
+[ 1663, "bkw" ],
+[ 1664, "bkx" ],
+[ 1665, "bky" ],
+[ 1666, "bkz" ],
+[ 1667, "bla" ],
+[ 1668, "blb" ],
+[ 1669, "blc" ],
+[ 1670, "bld" ],
+[ 1671, "ble" ],
+[ 1672, "blf" ],
+[ 1673, "blg" ],
+[ 1674, "blh" ],
+[ 1675, "bli" ],
+[ 1676, "blj" ],
+[ 1677, "blk" ],
+[ 1678, "bll" ],
+[ 1679, "blm" ],
+[ 1680, "bln" ],
+[ 1681, "blo" ],
+[ 1682, "blp" ],
+[ 1683, "blq" ],
+[ 1684, "blr" ],
+[ 1685, "bls" ],
+[ 1686, "blt" ],
+[ 1687, "blu" ],
+[ 1688, "blv" ],
+[ 1689, "blw" ],
+[ 1690, "blx" ],
+[ 1691, "bly" ],
+[ 1692, "blz" ],
+[ 1693, "bma" ],
+[ 1694, "bmb" ],
+[ 1695, "bmc" ],
+[ 1696, "bmd" ],
+[ 1697, "bme" ],
+[ 1698, "bmf" ],
+[ 1699, "bmg" ],
+[ 1700, "bmh" ],
+[ 1701, "bmi" ],
+[ 1702, "bmj" ],
+[ 1703, "bmk" ],
+[ 1704, "bml" ],
+[ 1705, "bmm" ],
+[ 1706, "bmn" ],
+[ 1707, "bmo" ],
+[ 1708, "bmp" ],
+[ 1709, "bmq" ],
+[ 1710, "bmr" ],
+[ 1711, "bms" ],
+[ 1712, "bmt" ],
+[ 1713, "bmu" ],
+[ 1714, "bmv" ],
+[ 1715, "bmw" ],
+[ 1716, "bmx" ],
+[ 1717, "bmy" ],
+[ 1718, "bmz" ],
+[ 1719, "bna" ],
+[ 1720, "bnb" ],
+[ 1721, "bnc" ],
+[ 1722, "bnd" ],
+[ 1723, "bne" ],
+[ 1724, "bnf" ],
+[ 1725, "bng" ],
+[ 1726, "bnh" ],
+[ 1727, "bni" ],
+[ 1728, "bnj" ],
+[ 1729, "bnk" ],
+[ 1730, "bnl" ],
+[ 1731, "bnm" ],
+[ 1732, "bnn" ],
+[ 1733, "bno" ],
+[ 1734, "bnp" ],
+[ 1735, "bnq" ],
+[ 1736, "bnr" ],
+[ 1737, "bns" ],
+[ 1738, "bnt" ],
+[ 1739, "bnu" ],
+[ 1740, "bnv" ],
+[ 1741, "bnw" ],
+[ 1742, "bnx" ],
+[ 1743, "bny" ],
+[ 1744, "bnz" ],
+[ 1745, "boa" ],
+[ 1746, "bob" ],
+[ 1747, "boc" ],
+[ 1748, "bod" ],
+[ 1749, "boe" ],
+[ 1750, "bof" ],
+[ 1751, "bog" ],
+[ 1752, "boh" ],
+[ 1753, "boi" ],
+[ 1754, "boj" ],
+[ 1755, "bok" ],
+[ 1756, "bol" ],
+[ 1757, "bom" ],
+[ 1758, "bon" ],
+[ 1759, "boo" ],
+[ 1760, "bop" ],
+[ 1761, "boq" ],
+[ 1762, "bor" ],
+[ 1763, "bos" ],
+[ 1764, "bot" ],
+[ 1765, "bou" ],
+[ 1766, "bov" ],
+[ 1767, "bow" ],
+[ 1768, "box" ],
+[ 1769, "boy" ],
+[ 1770, "boz" ],
+[ 1771, "bpa" ],
+[ 1772, "bpb" ],
+[ 1773, "bpc" ],
+[ 1774, "bpd" ],
+[ 1775, "bpe" ],
+[ 1776, "bpf" ],
+[ 1777, "bpg" ],
+[ 1778, "bph" ],
+[ 1779, "bpi" ],
+[ 1780, "bpj" ],
+[ 1781, "bpk" ],
+[ 1782, "bpl" ],
+[ 1783, "bpm" ],
+[ 1784, "bpn" ],
+[ 1785, "bpo" ],
+[ 1786, "bpp" ],
+[ 1787, "bpq" ],
+[ 1788, "bpr" ],
+[ 1789, "bps" ],
+[ 1790, "bpt" ],
+[ 1791, "bpu" ],
+[ 1792, "bpv" ],
+[ 1793, "bpw" ],
+[ 1794, "bpx" ],
+[ 1795, "bpy" ],
+[ 1796, "bpz" ],
+[ 1797, "bqa" ],
+[ 1798, "bqb" ],
+[ 1799, "bqc" ],
+[ 1800, "bqd" ],
+[ 1801, "bqe" ],
+[ 1802, "bqf" ],
+[ 1803, "bqg" ],
+[ 1804, "bqh" ],
+[ 1805, "bqi" ],
+[ 1806, "bqj" ],
+[ 1807, "bqk" ],
+[ 1808, "bql" ],
+[ 1809, "bqm" ],
+[ 1810, "bqn" ],
+[ 1811, "bqo" ],
+[ 1812, "bqp" ],
+[ 1813, "bqq" ],
+[ 1814, "bqr" ],
+[ 1815, "bqs" ],
+[ 1816, "bqt" ],
+[ 1817, "bqu" ],
+[ 1818, "bqv" ],
+[ 1819, "bqw" ],
+[ 1820, "bqx" ],
+[ 1821, "bqy" ],
+[ 1822, "bqz" ],
+[ 1823, "bra" ],
+[ 1824, "brb" ],
+[ 1825, "brc" ],
+[ 1826, "brd" ],
+[ 1827, "bre" ],
+[ 1828, "brf" ],
+[ 1829, "brg" ],
+[ 1830, "brh" ],
+[ 1831, "bri" ],
+[ 1832, "brj" ],
+[ 1833, "brk" ],
+[ 1834, "brl" ],
+[ 1835, "brm" ],
+[ 1836, "brn" ],
+[ 1837, "bro" ],
+[ 1838, "brp" ],
+[ 1839, "brq" ],
+[ 1840, "brr" ],
+[ 1841, "brs" ],
+[ 1842, "brt" ],
+[ 1843, "bru" ],
+[ 1844, "brv" ],
+[ 1845, "brw" ],
+[ 1846, "brx" ],
+[ 1847, "bry" ],
+[ 1848, "brz" ],
+[ 1849, "bsa" ],
+[ 1850, "bsb" ],
+[ 1851, "bsc" ],
+[ 1852, "bsd" ],
+[ 1853, "bse" ],
+[ 1854, "bsf" ],
+[ 1855, "bsg" ],
+[ 1856, "bsh" ],
+[ 1857, "bsi" ],
+[ 1858, "bsj" ],
+[ 1859, "bsk" ],
+[ 1860, "bsl" ],
+[ 1861, "bsm" ],
+[ 1862, "bsn" ],
+[ 1863, "bso" ],
+[ 1864, "bsp" ],
+[ 1865, "bsq" ],
+[ 1866, "bsr" ],
+[ 1867, "bss" ],
+[ 1868, "bst" ],
+[ 1869, "bsu" ],
+[ 1870, "bsv" ],
+[ 1871, "bsw" ],
+[ 1872, "bsx" ],
+[ 1873, "bsy" ],
+[ 1874, "bsz" ],
+[ 1875, "bta" ],
+[ 1876, "btb" ],
+[ 1877, "btc" ],
+[ 1878, "btd" ],
+[ 1879, "bte" ],
+[ 1880, "btf" ],
+[ 1881, "btg" ],
+[ 1882, "bth" ],
+[ 1883, "bti" ],
+[ 1884, "btj" ],
+[ 1885, "btk" ],
+[ 1886, "btl" ],
+[ 1887, "btm" ],
+[ 1888, "btn" ],
+[ 1889, "bto" ],
+[ 1890, "btp" ],
+[ 1891, "btq" ],
+[ 1892, "btr" ],
+[ 1893, "bts" ],
+[ 1894, "btt" ],
+[ 1895, "btu" ],
+[ 1896, "btv" ],
+[ 1897, "btw" ],
+[ 1898, "btx" ],
+[ 1899, "bty" ],
+[ 1900, "btz" ],
+[ 1901, "bua" ],
+[ 1902, "bub" ],
+[ 1903, "buc" ],
+[ 1904, "bud" ],
+[ 1905, "bue" ],
+[ 1906, "buf" ],
+[ 1907, "bug" ],
+[ 1908, "buh" ],
+[ 1909, "bui" ],
+[ 1910, "buj" ],
+[ 1911, "buk" ],
+[ 1912, "bul" ],
+[ 1913, "bum" ],
+[ 1914, "bun" ],
+[ 1915, "buo" ],
+[ 1916, "bup" ],
+[ 1917, "buq" ],
+[ 1918, "bur" ],
+[ 1919, "bus" ],
+[ 1920, "but" ],
+[ 1921, "buu" ],
+[ 1922, "buv" ],
+[ 1923, "buw" ],
+[ 1924, "bux" ],
+[ 1925, "buy" ],
+[ 1926, "buz" ],
+[ 1927, "bva" ],
+[ 1928, "bvb" ],
+[ 1929, "bvc" ],
+[ 1930, "bvd" ],
+[ 1931, "bve" ],
+[ 1932, "bvf" ],
+[ 1933, "bvg" ],
+[ 1934, "bvh" ],
+[ 1935, "bvi" ],
+[ 1936, "bvj" ],
+[ 1937, "bvk" ],
+[ 1938, "bvl" ],
+[ 1939, "bvm" ],
+[ 1940, "bvn" ],
+[ 1941, "bvo" ],
+[ 1942, "bvp" ],
+[ 1943, "bvq" ],
+[ 1944, "bvr" ],
+[ 1945, "bvs" ],
+[ 1946, "bvt" ],
+[ 1947, "bvu" ],
+[ 1948, "bvv" ],
+[ 1949, "bvw" ],
+[ 1950, "bvx" ],
+[ 1951, "bvy" ],
+[ 1952, "bvz" ],
+[ 1953, "bwa" ],
+[ 1954, "bwb" ],
+[ 1955, "bwc" ],
+[ 1956, "bwd" ],
+[ 1957, "bwe" ],
+[ 1958, "bwf" ],
+[ 1959, "bwg" ],
+[ 1960, "bwh" ],
+[ 1961, "bwi" ],
+[ 1962, "bwj" ],
+[ 1963, "bwk" ],
+[ 1964, "bwl" ],
+[ 1965, "bwm" ],
+[ 1966, "bwn" ],
+[ 1967, "bwo" ],
+[ 1968, "bwp" ],
+[ 1969, "bwq" ],
+[ 1970, "bwr" ],
+[ 1971, "bws" ],
+[ 1972, "bwt" ],
+[ 1973, "bwu" ],
+[ 1974, "bwv" ],
+[ 1975, "bww" ],
+[ 1976, "bwx" ],
+[ 1977, "bwy" ],
+[ 1978, "bwz" ],
+[ 1979, "bxa" ],
+[ 1980, "bxb" ],
+[ 1981, "bxc" ],
+[ 1982, "bxd" ],
+[ 1983, "bxe" ],
+[ 1984, "bxf" ],
+[ 1985, "bxg" ],
+[ 1986, "bxh" ],
+[ 1987, "bxi" ],
+[ 1988, "bxj" ],
+[ 1989, "bxk" ],
+[ 1990, "bxl" ],
+[ 1991, "bxm" ],
+[ 1992, "bxn" ],
+[ 1993, "bxo" ],
+[ 1994, "bxp" ],
+[ 1995, "bxq" ],
+[ 1996, "bxr" ],
+[ 1997, "bxs" ],
+[ 1998, "bxt" ],
+[ 1999, "bxu" ],
+[ 2000, "bxv" ],
+[ 2001, "bxw" ],
+[ 2002, "bxx" ],
+[ 2003, "bxy" ],
+[ 2004, "bxz" ],
+[ 2005, "bya" ],
+[ 2006, "byb" ],
+[ 2007, "byc" ],
+[ 2008, "byd" ],
+[ 2009, "bye" ],
+[ 2010, "byf" ],
+[ 2011, "byg" ],
+[ 2012, "byh" ],
+[ 2013, "byi" ],
+[ 2014, "byj" ],
+[ 2015, "byk" ],
+[ 2016, "byl" ],
+[ 2017, "bym" ],
+[ 2018, "byn" ],
+[ 2019, "byo" ],
+[ 2020, "byp" ],
+[ 2021, "byq" ],
+[ 2022, "byr" ],
+[ 2023, "bys" ],
+[ 2024, "byt" ],
+[ 2025, "byu" ],
+[ 2026, "byv" ],
+[ 2027, "byw" ],
+[ 2028, "byx" ],
+[ 2029, "byy" ],
+[ 2030, "byz" ],
+[ 2031, "bza" ],
+[ 2032, "bzb" ],
+[ 2033, "bzc" ],
+[ 2034, "bzd" ],
+[ 2035, "bze" ],
+[ 2036, "bzf" ],
+[ 2037, "bzg" ],
+[ 2038, "bzh" ],
+[ 2039, "bzi" ],
+[ 2040, "bzj" ],
+[ 2041, "bzk" ],
+[ 2042, "bzl" ],
+[ 2043, "bzm" ],
+[ 2044, "bzn" ],
+[ 2045, "bzo" ],
+[ 2046, "bzp" ],
+[ 2047, "bzq" ],
+[ 2048, "bzr" ],
+[ 2049, "bzs" ],
+[ 2050, "bzt" ],
+[ 2051, "bzu" ],
+[ 2052, "bzv" ],
+[ 2053, "bzw" ],
+[ 2054, "bzx" ],
+[ 2055, "bzy" ],
+[ 2056, "bzz" ],
+[ 2057, "caa" ],
+[ 2058, "cab" ],
+[ 2059, "cac" ],
+[ 2060, "cad" ],
+[ 2061, "cae" ],
+[ 2062, "caf" ],
+[ 2063, "cag" ],
+[ 2064, "cah" ],
+[ 2065, "cai" ],
+[ 2066, "caj" ],
+[ 2067, "cak" ],
+[ 2068, "cal" ],
+[ 2069, "cam" ],
+[ 2070, "can" ],
+[ 2071, "cao" ],
+[ 2072, "cap" ],
+[ 2073, "caq" ],
+[ 2074, "car" ],
+[ 2075, "cas" ],
+[ 2076, "cat" ],
+[ 2077, "cau" ],
+[ 2078, "cav" ],
+[ 2079, "caw" ],
+[ 2080, "cax" ],
+[ 2081, "cay" ],
+[ 2082, "caz" ],
+[ 2083, "cba" ],
+[ 2084, "cbb" ],
+[ 2085, "cbc" ],
+[ 2086, "cbd" ],
+[ 2087, "cbe" ],
+[ 2088, "cbf" ],
+[ 2089, "cbg" ],
+[ 2090, "cbh" ],
+[ 2091, "cbi" ],
+[ 2092, "cbj" ],
+[ 2093, "cbk" ],
+[ 2094, "cbl" ],
+[ 2095, "cbm" ],
+[ 2096, "cbn" ],
+[ 2097, "cbo" ],
+[ 2098, "cbp" ],
+[ 2099, "cbq" ],
+[ 2100, "cbr" ],
+[ 2101, "cbs" ],
+[ 2102, "cbt" ],
+[ 2103, "cbu" ],
+[ 2104, "cbv" ],
+[ 2105, "cbw" ],
+[ 2106, "cbx" ],
+[ 2107, "cby" ],
+[ 2108, "cbz" ],
+[ 2109, "cca" ],
+[ 2110, "ccb" ],
+[ 2111, "ccc" ],
+[ 2112, "ccd" ],
+[ 2113, "cce" ],
+[ 2114, "ccf" ],
+[ 2115, "ccg" ],
+[ 2116, "cch" ],
+[ 2117, "cci" ],
+[ 2118, "ccj" ],
+[ 2119, "cck" ],
+[ 2120, "ccl" ],
+[ 2121, "ccm" ],
+[ 2122, "ccn" ],
+[ 2123, "cco" ],
+[ 2124, "ccp" ],
+[ 2125, "ccq" ],
+[ 2126, "ccr" ],
+[ 2127, "ccs" ],
+[ 2128, "cct" ],
+[ 2129, "ccu" ],
+[ 2130, "ccv" ],
+[ 2131, "ccw" ],
+[ 2132, "ccx" ],
+[ 2133, "ccy" ],
+[ 2134, "ccz" ],
+[ 2135, "cda" ],
+[ 2136, "cdb" ],
+[ 2137, "cdc" ],
+[ 2138, "cdd" ],
+[ 2139, "cde" ],
+[ 2140, "cdf" ],
+[ 2141, "cdg" ],
+[ 2142, "cdh" ],
+[ 2143, "cdi" ],
+[ 2144, "cdj" ],
+[ 2145, "cdk" ],
+[ 2146, "cdl" ],
+[ 2147, "cdm" ],
+[ 2148, "cdn" ],
+[ 2149, "cdo" ],
+[ 2150, "cdp" ],
+[ 2151, "cdq" ],
+[ 2152, "cdr" ],
+[ 2153, "cds" ],
+[ 2154, "cdt" ],
+[ 2155, "cdu" ],
+[ 2156, "cdv" ],
+[ 2157, "cdw" ],
+[ 2158, "cdx" ],
+[ 2159, "cdy" ],
+[ 2160, "cdz" ],
+[ 2161, "cea" ],
+[ 2162, "ceb" ],
+[ 2163, "cec" ],
+[ 2164, "ced" ],
+[ 2165, "cee" ],
+[ 2166, "cef" ],
+[ 2167, "ceg" ],
+[ 2168, "ceh" ],
+[ 2169, "cei" ],
+[ 2170, "cej" ],
+[ 2171, "cek" ],
+[ 2172, "cel" ],
+[ 2173, "cem" ],
+[ 2174, "cen" ],
+[ 2175, "ceo" ],
+[ 2176, "cep" ],
+[ 2177, "ceq" ],
+[ 2178, "cer" ],
+[ 2179, "ces" ],
+[ 2180, "cet" ],
+[ 2181, "ceu" ],
+[ 2182, "cev" ],
+[ 2183, "cew" ],
+[ 2184, "cex" ],
+[ 2185, "cey" ],
+[ 2186, "cez" ],
+[ 2187, "cfa" ],
+[ 2188, "cfb" ],
+[ 2189, "cfc" ],
+[ 2190, "cfd" ],
+[ 2191, "cfe" ],
+[ 2192, "cff" ],
+[ 2193, "cfg" ],
+[ 2194, "cfh" ],
+[ 2195, "cfi" ],
+[ 2196, "cfj" ],
+[ 2197, "cfk" ],
+[ 2198, "cfl" ],
+[ 2199, "cfm" ],
+[ 2200, "cfn" ],
+[ 2201, "cfo" ],
+[ 2202, "cfp" ],
+[ 2203, "cfq" ],
+[ 2204, "cfr" ],
+[ 2205, "cfs" ],
+[ 2206, "cft" ],
+[ 2207, "cfu" ],
+[ 2208, "cfv" ],
+[ 2209, "cfw" ],
+[ 2210, "cfx" ],
+[ 2211, "cfy" ],
+[ 2212, "cfz" ],
+[ 2213, "cga" ],
+[ 2214, "cgb" ],
+[ 2215, "cgc" ],
+[ 2216, "cgd" ],
+[ 2217, "cge" ],
+[ 2218, "cgf" ],
+[ 2219, "cgg" ],
+[ 2220, "cgh" ],
+[ 2221, "cgi" ],
+[ 2222, "cgj" ],
+[ 2223, "cgk" ],
+[ 2224, "cgl" ],
+[ 2225, "cgm" ],
+[ 2226, "cgn" ],
+[ 2227, "cgo" ],
+[ 2228, "cgp" ],
+[ 2229, "cgq" ],
+[ 2230, "cgr" ],
+[ 2231, "cgs" ],
+[ 2232, "cgt" ],
+[ 2233, "cgu" ],
+[ 2234, "cgv" ],
+[ 2235, "cgw" ],
+[ 2236, "cgx" ],
+[ 2237, "cgy" ],
+[ 2238, "cgz" ],
+[ 2239, "cha" ],
+[ 2240, "chb" ],
+[ 2241, "chc" ],
+[ 2242, "chd" ],
+[ 2243, "che" ],
+[ 2244, "chf" ],
+[ 2245, "chg" ],
+[ 2246, "chh" ],
+[ 2247, "chi" ],
+[ 2248, "chj" ],
+[ 2249, "chk" ],
+[ 2250, "chl" ],
+[ 2251, "chm" ],
+[ 2252, "chn" ],
+[ 2253, "cho" ],
+[ 2254, "chp" ],
+[ 2255, "chq" ],
+[ 2256, "chr" ],
+[ 2257, "chs" ],
+[ 2258, "cht" ],
+[ 2259, "chu" ],
+[ 2260, "chv" ],
+[ 2261, "chw" ],
+[ 2262, "chx" ],
+[ 2263, "chy" ],
+[ 2264, "chz" ],
+[ 2265, "cia" ],
+[ 2266, "cib" ],
+[ 2267, "cic" ],
+[ 2268, "cid" ],
+[ 2269, "cie" ],
+[ 2270, "cif" ],
+[ 2271, "cig" ],
+[ 2272, "cih" ],
+[ 2273, "cii" ],
+[ 2274, "cij" ],
+[ 2275, "cik" ],
+[ 2276, "cil" ],
+[ 2277, "cim" ],
+[ 2278, "cin" ],
+[ 2279, "cio" ],
+[ 2280, "cip" ],
+[ 2281, "ciq" ],
+[ 2282, "cir" ],
+[ 2283, "cis" ],
+[ 2284, "cit" ],
+[ 2285, "ciu" ],
+[ 2286, "civ" ],
+[ 2287, "ciw" ],
+[ 2288, "cix" ],
+[ 2289, "ciy" ],
+[ 2290, "ciz" ],
+[ 2291, "cja" ],
+[ 2292, "cjb" ],
+[ 2293, "cjc" ],
+[ 2294, "cjd" ],
+[ 2295, "cje" ],
+[ 2296, "cjf" ],
+[ 2297, "cjg" ],
+[ 2298, "cjh" ],
+[ 2299, "cji" ],
+[ 2300, "cjj" ],
+[ 2301, "cjk" ],
+[ 2302, "cjl" ],
+[ 2303, "cjm" ],
+[ 2304, "cjn" ],
+[ 2305, "cjo" ],
+[ 2306, "cjp" ],
+[ 2307, "cjq" ],
+[ 2308, "cjr" ],
+[ 2309, "cjs" ],
+[ 2310, "cjt" ],
+[ 2311, "cju" ],
+[ 2312, "cjv" ],
+[ 2313, "cjw" ],
+[ 2314, "cjx" ],
+[ 2315, "cjy" ],
+[ 2316, "cjz" ],
+[ 2317, "cka" ],
+[ 2318, "ckb" ],
+[ 2319, "ckc" ],
+[ 2320, "ckd" ],
+[ 2321, "cke" ],
+[ 2322, "ckf" ],
+[ 2323, "ckg" ],
+[ 2324, "ckh" ],
+[ 2325, "cki" ],
+[ 2326, "ckj" ],
+[ 2327, "ckk" ],
+[ 2328, "ckl" ],
+[ 2329, "ckm" ],
+[ 2330, "ckn" ],
+[ 2331, "cko" ],
+[ 2332, "ckp" ],
+[ 2333, "ckq" ],
+[ 2334, "ckr" ],
+[ 2335, "cks" ],
+[ 2336, "ckt" ],
+[ 2337, "cku" ],
+[ 2338, "ckv" ],
+[ 2339, "ckw" ],
+[ 2340, "ckx" ],
+[ 2341, "cky" ],
+[ 2342, "ckz" ],
+[ 2343, "cla" ],
+[ 2344, "clb" ],
+[ 2345, "clc" ],
+[ 2346, "cld" ],
+[ 2347, "cle" ],
+[ 2348, "clf" ],
+[ 2349, "clg" ],
+[ 2350, "clh" ],
+[ 2351, "cli" ],
+[ 2352, "clj" ],
+[ 2353, "clk" ],
+[ 2354, "cll" ],
+[ 2355, "clm" ],
+[ 2356, "cln" ],
+[ 2357, "clo" ],
+[ 2358, "clp" ],
+[ 2359, "clq" ],
+[ 2360, "clr" ],
+[ 2361, "cls" ],
+[ 2362, "clt" ],
+[ 2363, "clu" ],
+[ 2364, "clv" ],
+[ 2365, "clw" ],
+[ 2366, "clx" ],
+[ 2367, "cly" ],
+[ 2368, "clz" ],
+[ 2369, "cma" ],
+[ 2370, "cmb" ],
+[ 2371, "cmc" ],
+[ 2372, "cmd" ],
+[ 2373, "cme" ],
+[ 2374, "cmf" ],
+[ 2375, "cmg" ],
+[ 2376, "cmh" ],
+[ 2377, "cmi" ],
+[ 2378, "cmj" ],
+[ 2379, "cmk" ],
+[ 2380, "cml" ],
+[ 2381, "cmm" ],
+[ 2382, "cmn" ],
+[ 2383, "cmo" ],
+[ 2384, "cmp" ],
+[ 2385, "cmq" ],
+[ 2386, "cmr" ],
+[ 2387, "cms" ],
+[ 2388, "cmt" ],
+[ 2389, "cmu" ],
+[ 2390, "cmv" ],
+[ 2391, "cmw" ],
+[ 2392, "cmx" ],
+[ 2393, "cmy" ],
+[ 2394, "cmz" ],
+[ 2395, "cna" ],
+[ 2396, "cnb" ],
+[ 2397, "cnc" ],
+[ 2398, "cnd" ],
+[ 2399, "cne" ],
+[ 2400, "cnf" ],
+[ 2401, "cng" ],
+[ 2402, "cnh" ],
+[ 2403, "cni" ],
+[ 2404, "cnj" ],
+[ 2405, "cnk" ],
+[ 2406, "cnl" ],
+[ 2407, "cnm" ],
+[ 2408, "cnn" ],
+[ 2409, "cno" ],
+[ 2410, "cnp" ],
+[ 2411, "cnq" ],
+[ 2412, "cnr" ],
+[ 2413, "cns" ],
+[ 2414, "cnt" ],
+[ 2415, "cnu" ],
+[ 2416, "cnv" ],
+[ 2417, "cnw" ],
+[ 2418, "cnx" ],
+[ 2419, "cny" ],
+[ 2420, "cnz" ],
+[ 2421, "coa" ],
+[ 2422, "cob" ],
+[ 2423, "coc" ],
+[ 2424, "cod" ],
+[ 2425, "coe" ],
+[ 2426, "cof" ],
+[ 2427, "cog" ],
+[ 2428, "coh" ],
+[ 2429, "coi" ],
+[ 2430, "coj" ],
+[ 2431, "cok" ],
+[ 2432, "col" ],
+[ 2433, "com" ],
+[ 2434, "con" ],
+[ 2435, "coo" ],
+[ 2436, "cop" ],
+[ 2437, "coq" ],
+[ 2438, "cor" ],
+[ 2439, "cos" ],
+[ 2440, "cot" ],
+[ 2441, "cou" ],
+[ 2442, "cov" ],
+[ 2443, "cow" ],
+[ 2444, "cox" ],
+[ 2445, "coy" ],
+[ 2446, "coz" ],
+[ 2447, "cpa" ],
+[ 2448, "cpb" ],
+[ 2449, "cpc" ],
+[ 2450, "cpd" ],
+[ 2451, "cpe" ],
+[ 2452, "cpf" ],
+[ 2453, "cpg" ],
+[ 2454, "cph" ],
+[ 2455, "cpi" ],
+[ 2456, "cpj" ],
+[ 2457, "cpk" ],
+[ 2458, "cpl" ],
+[ 2459, "cpm" ],
+[ 2460, "cpn" ],
+[ 2461, "cpo" ],
+[ 2462, "cpp" ],
+[ 2463, "cpq" ],
+[ 2464, "cpr" ],
+[ 2465, "cps" ],
+[ 2466, "cpt" ],
+[ 2467, "cpu" ],
+[ 2468, "cpv" ],
+[ 2469, "cpw" ],
+[ 2470, "cpx" ],
+[ 2471, "cpy" ],
+[ 2472, "cpz" ],
+[ 2473, "cqa" ],
+[ 2474, "cqb" ],
+[ 2475, "cqc" ],
+[ 2476, "cqd" ],
+[ 2477, "cqe" ],
+[ 2478, "cqf" ],
+[ 2479, "cqg" ],
+[ 2480, "cqh" ],
+[ 2481, "cqi" ],
+[ 2482, "cqj" ],
+[ 2483, "cqk" ],
+[ 2484, "cql" ],
+[ 2485, "cqm" ],
+[ 2486, "cqn" ],
+[ 2487, "cqo" ],
+[ 2488, "cqp" ],
+[ 2489, "cqq" ],
+[ 2490, "cqr" ],
+[ 2491, "cqs" ],
+[ 2492, "cqt" ],
+[ 2493, "cqu" ],
+[ 2494, "cqv" ],
+[ 2495, "cqw" ],
+[ 2496, "cqx" ],
+[ 2497, "cqy" ],
+[ 2498, "cqz" ],
+[ 2499, "cra" ],
+[ 2500, "crb" ],
+[ 2501, "crc" ],
+[ 2502, "crd" ],
+[ 2503, "cre" ],
+[ 2504, "crf" ],
+[ 2505, "crg" ],
+[ 2506, "crh" ],
+[ 2507, "cri" ],
+[ 2508, "crj" ],
+[ 2509, "crk" ],
+[ 2510, "crl" ],
+[ 2511, "crm" ],
+[ 2512, "crn" ],
+[ 2513, "cro" ],
+[ 2514, "crp" ],
+[ 2515, "crq" ],
+[ 2516, "crr" ],
+[ 2517, "crs" ],
+[ 2518, "crt" ],
+[ 2519, "cru" ],
+[ 2520, "crv" ],
+[ 2521, "crw" ],
+[ 2522, "crx" ],
+[ 2523, "cry" ],
+[ 2524, "crz" ],
+[ 2525, "csa" ],
+[ 2526, "csb" ],
+[ 2527, "csc" ],
+[ 2528, "csd" ],
+[ 2529, "cse" ],
+[ 2530, "csf" ],
+[ 2531, "csg" ],
+[ 2532, "csh" ],
+[ 2533, "csi" ],
+[ 2534, "csj" ],
+[ 2535, "csk" ],
+[ 2536, "csl" ],
+[ 2537, "csm" ],
+[ 2538, "csn" ],
+[ 2539, "cso" ],
+[ 2540, "csp" ],
+[ 2541, "csq" ],
+[ 2542, "csr" ],
+[ 2543, "css" ],
+[ 2544, "cst" ],
+[ 2545, "csu" ],
+[ 2546, "csv" ],
+[ 2547, "csw" ],
+[ 2548, "csx" ],
+[ 2549, "csy" ],
+[ 2550, "csz" ],
+[ 2551, "cta" ],
+[ 2552, "ctb" ],
+[ 2553, "ctc" ],
+[ 2554, "ctd" ],
+[ 2555, "cte" ],
+[ 2556, "ctf" ],
+[ 2557, "ctg" ],
+[ 2558, "cth" ],
+[ 2559, "cti" ],
+[ 2560, "ctj" ],
+[ 2561, "ctk" ],
+[ 2562, "ctl" ],
+[ 2563, "ctm" ],
+[ 2564, "ctn" ],
+[ 2565, "cto" ],
+[ 2566, "ctp" ],
+[ 2567, "ctq" ],
+[ 2568, "ctr" ],
+[ 2569, "cts" ],
+[ 2570, "ctt" ],
+[ 2571, "ctu" ],
+[ 2572, "ctv" ],
+[ 2573, "ctw" ],
+[ 2574, "ctx" ],
+[ 2575, "cty" ],
+[ 2576, "ctz" ],
+[ 2577, "cua" ],
+[ 2578, "cub" ],
+[ 2579, "cuc" ],
+[ 2580, "cud" ],
+[ 2581, "cue" ],
+[ 2582, "cuf" ],
+[ 2583, "cug" ],
+[ 2584, "cuh" ],
+[ 2585, "cui" ],
+[ 2586, "cuj" ],
+[ 2587, "cuk" ],
+[ 2588, "cul" ],
+[ 2589, "cum" ],
+[ 2590, "cun" ],
+[ 2591, "cuo" ],
+[ 2592, "cup" ],
+[ 2593, "cuq" ],
+[ 2594, "cur" ],
+[ 2595, "cus" ],
+[ 2596, "cut" ],
+[ 2597, "cuu" ],
+[ 2598, "cuv" ],
+[ 2599, "cuw" ],
+[ 2600, "cux" ],
+[ 2601, "cuy" ],
+[ 2602, "cuz" ],
+[ 2603, "cva" ],
+[ 2604, "cvb" ],
+[ 2605, "cvc" ],
+[ 2606, "cvd" ],
+[ 2607, "cve" ],
+[ 2608, "cvf" ],
+[ 2609, "cvg" ],
+[ 2610, "cvh" ],
+[ 2611, "cvi" ],
+[ 2612, "cvj" ],
+[ 2613, "cvk" ],
+[ 2614, "cvl" ],
+[ 2615, "cvm" ],
+[ 2616, "cvn" ],
+[ 2617, "cvo" ],
+[ 2618, "cvp" ],
+[ 2619, "cvq" ],
+[ 2620, "cvr" ],
+[ 2621, "cvs" ],
+[ 2622, "cvt" ],
+[ 2623, "cvu" ],
+[ 2624, "cvv" ],
+[ 2625, "cvw" ],
+[ 2626, "cvx" ],
+[ 2627, "cvy" ],
+[ 2628, "cvz" ],
+[ 2629, "cwa" ],
+[ 2630, "cwb" ],
+[ 2631, "cwc" ],
+[ 2632, "cwd" ],
+[ 2633, "cwe" ],
+[ 2634, "cwf" ],
+[ 2635, "cwg" ],
+[ 2636, "cwh" ],
+[ 2637, "cwi" ],
+[ 2638, "cwj" ],
+[ 2639, "cwk" ],
+[ 2640, "cwl" ],
+[ 2641, "cwm" ],
+[ 2642, "cwn" ],
+[ 2643, "cwo" ],
+[ 2644, "cwp" ],
+[ 2645, "cwq" ],
+[ 2646, "cwr" ],
+[ 2647, "cws" ],
+[ 2648, "cwt" ],
+[ 2649, "cwu" ],
+[ 2650, "cwv" ],
+[ 2651, "cww" ],
+[ 2652, "cwx" ],
+[ 2653, "cwy" ],
+[ 2654, "cwz" ],
+[ 2655, "cxa" ],
+[ 2656, "cxb" ],
+[ 2657, "cxc" ],
+[ 2658, "cxd" ],
+[ 2659, "cxe" ],
+[ 2660, "cxf" ],
+[ 2661, "cxg" ],
+[ 2662, "cxh" ],
+[ 2663, "cxi" ],
+[ 2664, "cxj" ],
+[ 2665, "cxk" ],
+[ 2666, "cxl" ],
+[ 2667, "cxm" ],
+[ 2668, "cxn" ],
+[ 2669, "cxo" ],
+[ 2670, "cxp" ],
+[ 2671, "cxq" ],
+[ 2672, "cxr" ],
+[ 2673, "cxs" ],
+[ 2674, "cxt" ],
+[ 2675, "cxu" ],
+[ 2676, "cxv" ],
+[ 2677, "cxw" ],
+[ 2678, "cxx" ],
+[ 2679, "cxy" ],
+[ 2680, "cxz" ],
+[ 2681, "cya" ],
+[ 2682, "cyb" ],
+[ 2683, "cyc" ],
+[ 2684, "cyd" ],
+[ 2685, "cye" ],
+[ 2686, "cyf" ],
+[ 2687, "cyg" ],
+[ 2688, "cyh" ],
+[ 2689, "cyi" ],
+[ 2690, "cyj" ],
+[ 2691, "cyk" ],
+[ 2692, "cyl" ],
+[ 2693, "cym" ],
+[ 2694, "cyn" ],
+[ 2695, "cyo" ],
+[ 2696, "cyp" ],
+[ 2697, "cyq" ],
+[ 2698, "cyr" ],
+[ 2699, "cys" ],
+[ 2700, "cyt" ],
+[ 2701, "cyu" ],
+[ 2702, "cyv" ],
+[ 2703, "cyw" ],
+[ 2704, "cyx" ],
+[ 2705, "cyy" ],
+[ 2706, "cyz" ],
+[ 2707, "cza" ],
+[ 2708, "czb" ],
+[ 2709, "czc" ],
+[ 2710, "czd" ],
+[ 2711, "cze" ],
+[ 2712, "czf" ],
+[ 2713, "czg" ],
+[ 2714, "czh" ],
+[ 2715, "czi" ],
+[ 2716, "czj" ],
+[ 2717, "czk" ],
+[ 2718, "czl" ],
+[ 2719, "czm" ],
+[ 2720, "czn" ],
+[ 2721, "czo" ],
+[ 2722, "czp" ],
+[ 2723, "czq" ],
+[ 2724, "czr" ],
+[ 2725, "czs" ],
+[ 2726, "czt" ],
+[ 2727, "czu" ],
+[ 2728, "czv" ],
+[ 2729, "czw" ],
+[ 2730, "czx" ],
+[ 2731, "czy" ],
+[ 2732, "czz" ],
+[ 2733, "daa" ],
+[ 2734, "dab" ],
+[ 2735, "dac" ],
+[ 2736, "dad" ],
+[ 2737, "dae" ],
+[ 2738, "daf" ],
+[ 2739, "dag" ],
+[ 2740, "dah" ],
+[ 2741, "dai" ],
+[ 2742, "daj" ],
+[ 2743, "dak" ],
+[ 2744, "dal" ],
+[ 2745, "dam" ],
+[ 2746, "dan" ],
+[ 2747, "dao" ],
+[ 2748, "dap" ],
+[ 2749, "daq" ],
+[ 2750, "dar" ],
+[ 2751, "das" ],
+[ 2752, "dat" ],
+[ 2753, "dau" ],
+[ 2754, "dav" ],
+[ 2755, "daw" ],
+[ 2756, "dax" ],
+[ 2757, "day" ],
+[ 2758, "daz" ],
+[ 2759, "dba" ],
+[ 2760, "dbb" ],
+[ 2761, "dbc" ],
+[ 2762, "dbd" ],
+[ 2763, "dbe" ],
+[ 2764, "dbf" ],
+[ 2765, "dbg" ],
+[ 2766, "dbh" ],
+[ 2767, "dbi" ],
+[ 2768, "dbj" ],
+[ 2769, "dbk" ],
+[ 2770, "dbl" ],
+[ 2771, "dbm" ],
+[ 2772, "dbn" ],
+[ 2773, "dbo" ],
+[ 2774, "dbp" ],
+[ 2775, "dbq" ],
+[ 2776, "dbr" ],
+[ 2777, "dbs" ],
+[ 2778, "dbt" ],
+[ 2779, "dbu" ],
+[ 2780, "dbv" ],
+[ 2781, "dbw" ],
+[ 2782, "dbx" ],
+[ 2783, "dby" ],
+[ 2784, "dbz" ],
+[ 2785, "dca" ],
+[ 2786, "dcb" ],
+[ 2787, "dcc" ],
+[ 2788, "dcd" ],
+[ 2789, "dce" ],
+[ 2790, "dcf" ],
+[ 2791, "dcg" ],
+[ 2792, "dch" ],
+[ 2793, "dci" ],
+[ 2794, "dcj" ],
+[ 2795, "dck" ],
+[ 2796, "dcl" ],
+[ 2797, "dcm" ],
+[ 2798, "dcn" ],
+[ 2799, "dco" ],
+[ 2800, "dcp" ],
+[ 2801, "dcq" ],
+[ 2802, "dcr" ],
+[ 2803, "dcs" ],
+[ 2804, "dct" ],
+[ 2805, "dcu" ],
+[ 2806, "dcv" ],
+[ 2807, "dcw" ],
+[ 2808, "dcx" ],
+[ 2809, "dcy" ],
+[ 2810, "dcz" ],
+[ 2811, "dda" ],
+[ 2812, "ddb" ],
+[ 2813, "ddc" ],
+[ 2814, "ddd" ],
+[ 2815, "dde" ],
+[ 2816, "ddf" ],
+[ 2817, "ddg" ],
+[ 2818, "ddh" ],
+[ 2819, "ddi" ],
+[ 2820, "ddj" ],
+[ 2821, "ddk" ],
+[ 2822, "ddl" ],
+[ 2823, "ddm" ],
+[ 2824, "ddn" ],
+[ 2825, "ddo" ],
+[ 2826, "ddp" ],
+[ 2827, "ddq" ],
+[ 2828, "ddr" ],
+[ 2829, "dds" ],
+[ 2830, "ddt" ],
+[ 2831, "ddu" ],
+[ 2832, "ddv" ],
+[ 2833, "ddw" ],
+[ 2834, "ddx" ],
+[ 2835, "ddy" ],
+[ 2836, "ddz" ],
+[ 2837, "dea" ],
+[ 2838, "deb" ],
+[ 2839, "dec" ],
+[ 2840, "ded" ],
+[ 2841, "dee" ],
+[ 2842, "def" ],
+[ 2843, "deg" ],
+[ 2844, "deh" ],
+[ 2845, "dei" ],
+[ 2846, "dej" ],
+[ 2847, "dek" ],
+[ 2848, "del" ],
+[ 2849, "dem" ],
+[ 2850, "den" ],
+[ 2851, "deo" ],
+[ 2852, "dep" ],
+[ 2853, "deq" ],
+[ 2854, "der" ],
+[ 2855, "des" ],
+[ 2856, "det" ],
+[ 2857, "deu" ],
+[ 2858, "dev" ],
+[ 2859, "dew" ],
+[ 2860, "dex" ],
+[ 2861, "dey" ],
+[ 2862, "dez" ],
+[ 2863, "dfa" ],
+[ 2864, "dfb" ],
+[ 2865, "dfc" ],
+[ 2866, "dfd" ],
+[ 2867, "dfe" ],
+[ 2868, "dff" ],
+[ 2869, "dfg" ],
+[ 2870, "dfh" ],
+[ 2871, "dfi" ],
+[ 2872, "dfj" ],
+[ 2873, "dfk" ],
+[ 2874, "dfl" ],
+[ 2875, "dfm" ],
+[ 2876, "dfn" ],
+[ 2877, "dfo" ],
+[ 2878, "dfp" ],
+[ 2879, "dfq" ],
+[ 2880, "dfr" ],
+[ 2881, "dfs" ],
+[ 2882, "dft" ],
+[ 2883, "dfu" ],
+[ 2884, "dfv" ],
+[ 2885, "dfw" ],
+[ 2886, "dfx" ],
+[ 2887, "dfy" ],
+[ 2888, "dfz" ],
+[ 2889, "dga" ],
+[ 2890, "dgb" ],
+[ 2891, "dgc" ],
+[ 2892, "dgd" ],
+[ 2893, "dge" ],
+[ 2894, "dgf" ],
+[ 2895, "dgg" ],
+[ 2896, "dgh" ],
+[ 2897, "dgi" ],
+[ 2898, "dgj" ],
+[ 2899, "dgk" ],
+[ 2900, "dgl" ],
+[ 2901, "dgm" ],
+[ 2902, "dgn" ],
+[ 2903, "dgo" ],
+[ 2904, "dgp" ],
+[ 2905, "dgq" ],
+[ 2906, "dgr" ],
+[ 2907, "dgs" ],
+[ 2908, "dgt" ],
+[ 2909, "dgu" ],
+[ 2910, "dgv" ],
+[ 2911, "dgw" ],
+[ 2912, "dgx" ],
+[ 2913, "dgy" ],
+[ 2914, "dgz" ],
+[ 2915, "dha" ],
+[ 2916, "dhb" ],
+[ 2917, "dhc" ],
+[ 2918, "dhd" ],
+[ 2919, "dhe" ],
+[ 2920, "dhf" ],
+[ 2921, "dhg" ],
+[ 2922, "dhh" ],
+[ 2923, "dhi" ],
+[ 2924, "dhj" ],
+[ 2925, "dhk" ],
+[ 2926, "dhl" ],
+[ 2927, "dhm" ],
+[ 2928, "dhn" ],
+[ 2929, "dho" ],
+[ 2930, "dhp" ],
+[ 2931, "dhq" ],
+[ 2932, "dhr" ],
+[ 2933, "dhs" ],
+[ 2934, "dht" ],
+[ 2935, "dhu" ],
+[ 2936, "dhv" ],
+[ 2937, "dhw" ],
+[ 2938, "dhx" ],
+[ 2939, "dhy" ],
+[ 2940, "dhz" ],
+[ 2941, "dia" ],
+[ 2942, "dib" ],
+[ 2943, "dic" ],
+[ 2944, "did" ],
+[ 2945, "die" ],
+[ 2946, "dif" ],
+[ 2947, "dig" ],
+[ 2948, "dih" ],
+[ 2949, "dii" ],
+[ 2950, "dij" ],
+[ 2951, "dik" ],
+[ 2952, "dil" ],
+[ 2953, "dim" ],
+[ 2954, "din" ],
+[ 2955, "dio" ],
+[ 2956, "dip" ],
+[ 2957, "diq" ],
+[ 2958, "dir" ],
+[ 2959, "dis" ],
+[ 2960, "dit" ],
+[ 2961, "diu" ],
+[ 2962, "div" ],
+[ 2963, "diw" ],
+[ 2964, "dix" ],
+[ 2965, "diy" ],
+[ 2966, "diz" ],
+[ 2967, "dja" ],
+[ 2968, "djb" ],
+[ 2969, "djc" ],
+[ 2970, "djd" ],
+[ 2971, "dje" ],
+[ 2972, "djf" ],
+[ 2973, "djg" ],
+[ 2974, "djh" ],
+[ 2975, "dji" ],
+[ 2976, "djj" ],
+[ 2977, "djk" ],
+[ 2978, "djl" ],
+[ 2979, "djm" ],
+[ 2980, "djn" ],
+[ 2981, "djo" ],
+[ 2982, "djp" ],
+[ 2983, "djq" ],
+[ 2984, "djr" ],
+[ 2985, "djs" ],
+[ 2986, "djt" ],
+[ 2987, "dju" ],
+[ 2988, "djv" ],
+[ 2989, "djw" ],
+[ 2990, "djx" ],
+[ 2991, "djy" ],
+[ 2992, "djz" ],
+[ 2993, "dka" ],
+[ 2994, "dkb" ],
+[ 2995, "dkc" ],
+[ 2996, "dkd" ],
+[ 2997, "dke" ],
+[ 2998, "dkf" ],
+[ 2999, "dkg" ],
+[ 3000, "dkh" ],
+[ 3001, "dki" ],
+[ 3002, "dkj" ],
+[ 3003, "dkk" ],
+[ 3004, "dkl" ],
+[ 3005, "dkm" ],
+[ 3006, "dkn" ],
+[ 3007, "dko" ],
+[ 3008, "dkp" ],
+[ 3009, "dkq" ],
+[ 3010, "dkr" ],
+[ 3011, "dks" ],
+[ 3012, "dkt" ],
+[ 3013, "dku" ],
+[ 3014, "dkv" ],
+[ 3015, "dkw" ],
+[ 3016, "dkx" ],
+[ 3017, "dky" ],
+[ 3018, "dkz" ],
+[ 3019, "dla" ],
+[ 3020, "dlb" ],
+[ 3021, "dlc" ],
+[ 3022, "dld" ],
+[ 3023, "dle" ],
+[ 3024, "dlf" ],
+[ 3025, "dlg" ],
+[ 3026, "dlh" ],
+[ 3027, "dli" ],
+[ 3028, "dlj" ],
+[ 3029, "dlk" ],
+[ 3030, "dll" ],
+[ 3031, "dlm" ],
+[ 3032, "dln" ],
+[ 3033, "dlo" ],
+[ 3034, "dlp" ],
+[ 3035, "dlq" ],
+[ 3036, "dlr" ],
+[ 3037, "dls" ],
+[ 3038, "dlt" ],
+[ 3039, "dlu" ],
+[ 3040, "dlv" ],
+[ 3041, "dlw" ],
+[ 3042, "dlx" ],
+[ 3043, "dly" ],
+[ 3044, "dlz" ],
+[ 3045, "dma" ],
+[ 3046, "dmb" ],
+[ 3047, "dmc" ],
+[ 3048, "dmd" ],
+[ 3049, "dme" ],
+[ 3050, "dmf" ],
+[ 3051, "dmg" ],
+[ 3052, "dmh" ],
+[ 3053, "dmi" ],
+[ 3054, "dmj" ],
+[ 3055, "dmk" ],
+[ 3056, "dml" ],
+[ 3057, "dmm" ],
+[ 3058, "dmn" ],
+[ 3059, "dmo" ],
+[ 3060, "dmp" ],
+[ 3061, "dmq" ],
+[ 3062, "dmr" ],
+[ 3063, "dms" ],
+[ 3064, "dmt" ],
+[ 3065, "dmu" ],
+[ 3066, "dmv" ],
+[ 3067, "dmw" ],
+[ 3068, "dmx" ],
+[ 3069, "dmy" ],
+[ 3070, "dmz" ],
+[ 3071, "dna" ],
+[ 3072, "dnb" ],
+[ 3073, "dnc" ],
+[ 3074, "dnd" ],
+[ 3075, "dne" ],
+[ 3076, "dnf" ],
+[ 3077, "dng" ],
+[ 3078, "dnh" ],
+[ 3079, "dni" ],
+[ 3080, "dnj" ],
+[ 3081, "dnk" ],
+[ 3082, "dnl" ],
+[ 3083, "dnm" ],
+[ 3084, "dnn" ],
+[ 3085, "dno" ],
+[ 3086, "dnp" ],
+[ 3087, "dnq" ],
+[ 3088, "dnr" ],
+[ 3089, "dns" ],
+[ 3090, "dnt" ],
+[ 3091, "dnu" ],
+[ 3092, "dnv" ],
+[ 3093, "dnw" ],
+[ 3094, "dnx" ],
+[ 3095, "dny" ],
+[ 3096, "dnz" ],
+[ 3097, "doa" ],
+[ 3098, "dob" ],
+[ 3099, "doc" ],
+[ 3100, "dod" ],
+[ 3101, "doe" ],
+[ 3102, "dof" ],
+[ 3103, "dog" ],
+[ 3104, "doh" ],
+[ 3105, "doi" ],
+[ 3106, "doj" ],
+[ 3107, "dok" ],
+[ 3108, "dol" ],
+[ 3109, "dom" ],
+[ 3110, "don" ],
+[ 3111, "doo" ],
+[ 3112, "dop" ],
+[ 3113, "doq" ],
+[ 3114, "dor" ],
+[ 3115, "dos" ],
+[ 3116, "dot" ],
+[ 3117, "dou" ],
+[ 3118, "dov" ],
+[ 3119, "dow" ],
+[ 3120, "dox" ],
+[ 3121, "doy" ],
+[ 3122, "doz" ],
+[ 3123, "dpa" ],
+[ 3124, "dpb" ],
+[ 3125, "dpc" ],
+[ 3126, "dpd" ],
+[ 3127, "dpe" ],
+[ 3128, "dpf" ],
+[ 3129, "dpg" ],
+[ 3130, "dph" ],
+[ 3131, "dpi" ],
+[ 3132, "dpj" ],
+[ 3133, "dpk" ],
+[ 3134, "dpl" ],
+[ 3135, "dpm" ],
+[ 3136, "dpn" ],
+[ 3137, "dpo" ],
+[ 3138, "dpp" ],
+[ 3139, "dpq" ],
+[ 3140, "dpr" ],
+[ 3141, "dps" ],
+[ 3142, "dpt" ],
+[ 3143, "dpu" ],
+[ 3144, "dpv" ],
+[ 3145, "dpw" ],
+[ 3146, "dpx" ],
+[ 3147, "dpy" ],
+[ 3148, "dpz" ],
+[ 3149, "dqa" ],
+[ 3150, "dqb" ],
+[ 3151, "dqc" ],
+[ 3152, "dqd" ],
+[ 3153, "dqe" ],
+[ 3154, "dqf" ],
+[ 3155, "dqg" ],
+[ 3156, "dqh" ],
+[ 3157, "dqi" ],
+[ 3158, "dqj" ],
+[ 3159, "dqk" ],
+[ 3160, "dql" ],
+[ 3161, "dqm" ],
+[ 3162, "dqn" ],
+[ 3163, "dqo" ],
+[ 3164, "dqp" ],
+[ 3165, "dqq" ],
+[ 3166, "dqr" ],
+[ 3167, "dqs" ],
+[ 3168, "dqt" ],
+[ 3169, "dqu" ],
+[ 3170, "dqv" ],
+[ 3171, "dqw" ],
+[ 3172, "dqx" ],
+[ 3173, "dqy" ],
+[ 3174, "dqz" ],
+[ 3175, "dra" ],
+[ 3176, "drb" ],
+[ 3177, "drc" ],
+[ 3178, "drd" ],
+[ 3179, "dre" ],
+[ 3180, "drf" ],
+[ 3181, "drg" ],
+[ 3182, "drh" ],
+[ 3183, "dri" ],
+[ 3184, "drj" ],
+[ 3185, "drk" ],
+[ 3186, "drl" ],
+[ 3187, "drm" ],
+[ 3188, "drn" ],
+[ 3189, "dro" ],
+[ 3190, "drp" ],
+[ 3191, "drq" ],
+[ 3192, "drr" ],
+[ 3193, "drs" ],
+[ 3194, "drt" ],
+[ 3195, "dru" ],
+[ 3196, "drv" ],
+[ 3197, "drw" ],
+[ 3198, "drx" ],
+[ 3199, "dry" ],
+[ 3200, "drz" ],
+[ 3201, "dsa" ],
+[ 3202, "dsb" ],
+[ 3203, "dsc" ],
+[ 3204, "dsd" ],
+[ 3205, "dse" ],
+[ 3206, "dsf" ],
+[ 3207, "dsg" ],
+[ 3208, "dsh" ],
+[ 3209, "dsi" ],
+[ 3210, "dsj" ],
+[ 3211, "dsk" ],
+[ 3212, "dsl" ],
+[ 3213, "dsm" ],
+[ 3214, "dsn" ],
+[ 3215, "dso" ],
+[ 3216, "dsp" ],
+[ 3217, "dsq" ],
+[ 3218, "dsr" ],
+[ 3219, "dss" ],
+[ 3220, "dst" ],
+[ 3221, "dsu" ],
+[ 3222, "dsv" ],
+[ 3223, "dsw" ],
+[ 3224, "dsx" ],
+[ 3225, "dsy" ],
+[ 3226, "dsz" ],
+[ 3227, "dta" ],
+[ 3228, "dtb" ],
+[ 3229, "dtc" ],
+[ 3230, "dtd" ],
+[ 3231, "dte" ],
+[ 3232, "dtf" ],
+[ 3233, "dtg" ],
+[ 3234, "dth" ],
+[ 3235, "dti" ],
+[ 3236, "dtj" ],
+[ 3237, "dtk" ],
+[ 3238, "dtl" ],
+[ 3239, "dtm" ],
+[ 3240, "dtn" ],
+[ 3241, "dto" ],
+[ 3242, "dtp" ],
+[ 3243, "dtq" ],
+[ 3244, "dtr" ],
+[ 3245, "dts" ],
+[ 3246, "dtt" ],
+[ 3247, "dtu" ],
+[ 3248, "dtv" ],
+[ 3249, "dtw" ],
+[ 3250, "dtx" ],
+[ 3251, "dty" ],
+[ 3252, "dtz" ],
+[ 3253, "dua" ],
+[ 3254, "dub" ],
+[ 3255, "duc" ],
+[ 3256, "dud" ],
+[ 3257, "due" ],
+[ 3258, "duf" ],
+[ 3259, "dug" ],
+[ 3260, "duh" ],
+[ 3261, "dui" ],
+[ 3262, "duj" ],
+[ 3263, "duk" ],
+[ 3264, "dul" ],
+[ 3265, "dum" ],
+[ 3266, "dun" ],
+[ 3267, "duo" ],
+[ 3268, "dup" ],
+[ 3269, "duq" ],
+[ 3270, "dur" ],
+[ 3271, "dus" ],
+[ 3272, "dut" ],
+[ 3273, "duu" ],
+[ 3274, "duv" ],
+[ 3275, "duw" ],
+[ 3276, "dux" ],
+[ 3277, "duy" ],
+[ 3278, "duz" ],
+[ 3279, "dva" ],
+[ 3280, "dvb" ],
+[ 3281, "dvc" ],
+[ 3282, "dvd" ],
+[ 3283, "dve" ],
+[ 3284, "dvf" ],
+[ 3285, "dvg" ],
+[ 3286, "dvh" ],
+[ 3287, "dvi" ],
+[ 3288, "dvj" ],
+[ 3289, "dvk" ],
+[ 3290, "dvl" ],
+[ 3291, "dvm" ],
+[ 3292, "dvn" ],
+[ 3293, "dvo" ],
+[ 3294, "dvp" ],
+[ 3295, "dvq" ],
+[ 3296, "dvr" ],
+[ 3297, "dvs" ],
+[ 3298, "dvt" ],
+[ 3299, "dvu" ],
+[ 3300, "dvv" ],
+[ 3301, "dvw" ],
+[ 3302, "dvx" ],
+[ 3303, "dvy" ],
+[ 3304, "dvz" ],
+[ 3305, "dwa" ],
+[ 3306, "dwb" ],
+[ 3307, "dwc" ],
+[ 3308, "dwd" ],
+[ 3309, "dwe" ],
+[ 3310, "dwf" ],
+[ 3311, "dwg" ],
+[ 3312, "dwh" ],
+[ 3313, "dwi" ],
+[ 3314, "dwj" ],
+[ 3315, "dwk" ],
+[ 3316, "dwl" ],
+[ 3317, "dwm" ],
+[ 3318, "dwn" ],
+[ 3319, "dwo" ],
+[ 3320, "dwp" ],
+[ 3321, "dwq" ],
+[ 3322, "dwr" ],
+[ 3323, "dws" ],
+[ 3324, "dwt" ],
+[ 3325, "dwu" ],
+[ 3326, "dwv" ],
+[ 3327, "dww" ],
+[ 3328, "dwx" ],
+[ 3329, "dwy" ],
+[ 3330, "dwz" ],
+[ 3331, "dxa" ],
+[ 3332, "dxb" ],
+[ 3333, "dxc" ],
+[ 3334, "dxd" ],
+[ 3335, "dxe" ],
+[ 3336, "dxf" ],
+[ 3337, "dxg" ],
+[ 3338, "dxh" ],
+[ 3339, "dxi" ],
+[ 3340, "dxj" ],
+[ 3341, "dxk" ],
+[ 3342, "dxl" ],
+[ 3343, "dxm" ],
+[ 3344, "dxn" ],
+[ 3345, "dxo" ],
+[ 3346, "dxp" ],
+[ 3347, "dxq" ],
+[ 3348, "dxr" ],
+[ 3349, "dxs" ],
+[ 3350, "dxt" ],
+[ 3351, "dxu" ],
+[ 3352, "dxv" ],
+[ 3353, "dxw" ],
+[ 3354, "dxx" ],
+[ 3355, "dxy" ],
+[ 3356, "dxz" ],
+[ 3357, "dya" ],
+[ 3358, "dyb" ],
+[ 3359, "dyc" ],
+[ 3360, "dyd" ],
+[ 3361, "dye" ],
+[ 3362, "dyf" ],
+[ 3363, "dyg" ],
+[ 3364, "dyh" ],
+[ 3365, "dyi" ],
+[ 3366, "dyj" ],
+[ 3367, "dyk" ],
+[ 3368, "dyl" ],
+[ 3369, "dym" ],
+[ 3370, "dyn" ],
+[ 3371, "dyo" ],
+[ 3372, "dyp" ],
+[ 3373, "dyq" ],
+[ 3374, "dyr" ],
+[ 3375, "dys" ],
+[ 3376, "dyt" ],
+[ 3377, "dyu" ],
+[ 3378, "dyv" ],
+[ 3379, "dyw" ],
+[ 3380, "dyx" ],
+[ 3381, "dyy" ],
+[ 3382, "dyz" ],
+[ 3383, "dza" ],
+[ 3384, "dzb" ],
+[ 3385, "dzc" ],
+[ 3386, "dzd" ],
+[ 3387, "dze" ],
+[ 3388, "dzf" ],
+[ 3389, "dzg" ],
+[ 3390, "dzh" ],
+[ 3391, "dzi" ],
+[ 3392, "dzj" ],
+[ 3393, "dzk" ],
+[ 3394, "dzl" ],
+[ 3395, "dzm" ],
+[ 3396, "dzn" ],
+[ 3397, "dzo" ],
+[ 3398, "dzp" ],
+[ 3399, "dzq" ],
+[ 3400, "dzr" ],
+[ 3401, "dzs" ],
+[ 3402, "dzt" ],
+[ 3403, "dzu" ],
+[ 3404, "dzv" ],
+[ 3405, "dzw" ],
+[ 3406, "dzx" ],
+[ 3407, "dzy" ],
+[ 3408, "dzz" ],
+[ 3409, "eaa" ],
+[ 3410, "eab" ],
+[ 3411, "eac" ],
+[ 3412, "ead" ],
+[ 3413, "eae" ],
+[ 3414, "eaf" ],
+[ 3415, "eag" ],
+[ 3416, "eah" ],
+[ 3417, "eai" ],
+[ 3418, "eaj" ],
+[ 3419, "eak" ],
+[ 3420, "eal" ],
+[ 3421, "eam" ],
+[ 3422, "ean" ],
+[ 3423, "eao" ],
+[ 3424, "eap" ],
+[ 3425, "eaq" ],
+[ 3426, "ear" ],
+[ 3427, "eas" ],
+[ 3428, "eat" ],
+[ 3429, "eau" ],
+[ 3430, "eav" ],
+[ 3431, "eaw" ],
+[ 3432, "eax" ],
+[ 3433, "eay" ],
+[ 3434, "eaz" ],
+[ 3435, "eba" ],
+[ 3436, "ebb" ],
+[ 3437, "ebc" ],
+[ 3438, "ebd" ],
+[ 3439, "ebe" ],
+[ 3440, "ebf" ],
+[ 3441, "ebg" ],
+[ 3442, "ebh" ],
+[ 3443, "ebi" ],
+[ 3444, "ebj" ],
+[ 3445, "ebk" ],
+[ 3446, "ebl" ],
+[ 3447, "ebm" ],
+[ 3448, "ebn" ],
+[ 3449, "ebo" ],
+[ 3450, "ebp" ],
+[ 3451, "ebq" ],
+[ 3452, "ebr" ],
+[ 3453, "ebs" ],
+[ 3454, "ebt" ],
+[ 3455, "ebu" ],
+[ 3456, "ebv" ],
+[ 3457, "ebw" ],
+[ 3458, "ebx" ],
+[ 3459, "eby" ],
+[ 3460, "ebz" ],
+[ 3461, "eca" ],
+[ 3462, "ecb" ],
+[ 3463, "ecc" ],
+[ 3464, "ecd" ],
+[ 3465, "ece" ],
+[ 3466, "ecf" ],
+[ 3467, "ecg" ],
+[ 3468, "ech" ],
+[ 3469, "eci" ],
+[ 3470, "ecj" ],
+[ 3471, "eck" ],
+[ 3472, "ecl" ],
+[ 3473, "ecm" ],
+[ 3474, "ecn" ],
+[ 3475, "eco" ],
+[ 3476, "ecp" ],
+[ 3477, "ecq" ],
+[ 3478, "ecr" ],
+[ 3479, "ecs" ],
+[ 3480, "ect" ],
+[ 3481, "ecu" ],
+[ 3482, "ecv" ],
+[ 3483, "ecw" ],
+[ 3484, "ecx" ],
+[ 3485, "ecy" ],
+[ 3486, "ecz" ],
+[ 3487, "eda" ],
+[ 3488, "edb" ],
+[ 3489, "edc" ],
+[ 3490, "edd" ],
+[ 3491, "ede" ],
+[ 3492, "edf" ],
+[ 3493, "edg" ],
+[ 3494, "edh" ],
+[ 3495, "edi" ],
+[ 3496, "edj" ],
+[ 3497, "edk" ],
+[ 3498, "edl" ],
+[ 3499, "edm" ],
+[ 3500, "edn" ],
+[ 3501, "edo" ],
+[ 3502, "edp" ],
+[ 3503, "edq" ],
+[ 3504, "edr" ],
+[ 3505, "eds" ],
+[ 3506, "edt" ],
+[ 3507, "edu" ],
+[ 3508, "edv" ],
+[ 3509, "edw" ],
+[ 3510, "edx" ],
+[ 3511, "edy" ],
+[ 3512, "edz" ],
+[ 3513, "eea" ],
+[ 3514, "eeb" ],
+[ 3515, "eec" ],
+[ 3516, "eed" ],
+[ 3517, "eee" ],
+[ 3518, "eef" ],
+[ 3519, "eeg" ],
+[ 3520, "eeh" ],
+[ 3521, "eei" ],
+[ 3522, "eej" ],
+[ 3523, "eek" ],
+[ 3524, "eel" ],
+[ 3525, "eem" ],
+[ 3526, "een" ],
+[ 3527, "eeo" ],
+[ 3528, "eep" ],
+[ 3529, "eeq" ],
+[ 3530, "eer" ],
+[ 3531, "ees" ],
+[ 3532, "eet" ],
+[ 3533, "eeu" ],
+[ 3534, "eev" ],
+[ 3535, "eew" ],
+[ 3536, "eex" ],
+[ 3537, "eey" ],
+[ 3538, "eez" ],
+[ 3539, "efa" ],
+[ 3540, "efb" ],
+[ 3541, "efc" ],
+[ 3542, "efd" ],
+[ 3543, "efe" ],
+[ 3544, "eff" ],
+[ 3545, "efg" ],
+[ 3546, "efh" ],
+[ 3547, "efi" ],
+[ 3548, "efj" ],
+[ 3549, "efk" ],
+[ 3550, "efl" ],
+[ 3551, "efm" ],
+[ 3552, "efn" ],
+[ 3553, "efo" ],
+[ 3554, "efp" ],
+[ 3555, "efq" ],
+[ 3556, "efr" ],
+[ 3557, "efs" ],
+[ 3558, "eft" ],
+[ 3559, "efu" ],
+[ 3560, "efv" ],
+[ 3561, "efw" ],
+[ 3562, "efx" ],
+[ 3563, "efy" ],
+[ 3564, "efz" ],
+[ 3565, "ega" ],
+[ 3566, "egb" ],
+[ 3567, "egc" ],
+[ 3568, "egd" ],
+[ 3569, "ege" ],
+[ 3570, "egf" ],
+[ 3571, "egg" ],
+[ 3572, "egh" ],
+[ 3573, "egi" ],
+[ 3574, "egj" ],
+[ 3575, "egk" ],
+[ 3576, "egl" ],
+[ 3577, "egm" ],
+[ 3578, "egn" ],
+[ 3579, "ego" ],
+[ 3580, "egp" ],
+[ 3581, "egq" ],
+[ 3582, "egr" ],
+[ 3583, "egs" ],
+[ 3584, "egt" ],
+[ 3585, "egu" ],
+[ 3586, "egv" ],
+[ 3587, "egw" ],
+[ 3588, "egx" ],
+[ 3589, "egy" ],
+[ 3590, "egz" ],
+[ 3591, "eha" ],
+[ 3592, "ehb" ],
+[ 3593, "ehc" ],
+[ 3594, "ehd" ],
+[ 3595, "ehe" ],
+[ 3596, "ehf" ],
+[ 3597, "ehg" ],
+[ 3598, "ehh" ],
+[ 3599, "ehi" ],
+[ 3600, "ehj" ],
+[ 3601, "ehk" ],
+[ 3602, "ehl" ],
+[ 3603, "ehm" ],
+[ 3604, "ehn" ],
+[ 3605, "eho" ],
+[ 3606, "ehp" ],
+[ 3607, "ehq" ],
+[ 3608, "ehr" ],
+[ 3609, "ehs" ],
+[ 3610, "eht" ],
+[ 3611, "ehu" ],
+[ 3612, "ehv" ],
+[ 3613, "ehw" ],
+[ 3614, "ehx" ],
+[ 3615, "ehy" ],
+[ 3616, "ehz" ],
+[ 3617, "eia" ],
+[ 3618, "eib" ],
+[ 3619, "eic" ],
+[ 3620, "eid" ],
+[ 3621, "eie" ],
+[ 3622, "eif" ],
+[ 3623, "eig" ],
+[ 3624, "eih" ],
+[ 3625, "eii" ],
+[ 3626, "eij" ],
+[ 3627, "eik" ],
+[ 3628, "eil" ],
+[ 3629, "eim" ],
+[ 3630, "ein" ],
+[ 3631, "eio" ],
+[ 3632, "eip" ],
+[ 3633, "eiq" ],
+[ 3634, "eir" ],
+[ 3635, "eis" ],
+[ 3636, "eit" ],
+[ 3637, "eiu" ],
+[ 3638, "eiv" ],
+[ 3639, "eiw" ],
+[ 3640, "eix" ],
+[ 3641, "eiy" ],
+[ 3642, "eiz" ],
+[ 3643, "eja" ],
+[ 3644, "ejb" ],
+[ 3645, "ejc" ],
+[ 3646, "ejd" ],
+[ 3647, "eje" ],
+[ 3648, "ejf" ],
+[ 3649, "ejg" ],
+[ 3650, "ejh" ],
+[ 3651, "eji" ],
+[ 3652, "ejj" ],
+[ 3653, "ejk" ],
+[ 3654, "ejl" ],
+[ 3655, "ejm" ],
+[ 3656, "ejn" ],
+[ 3657, "ejo" ],
+[ 3658, "ejp" ],
+[ 3659, "ejq" ],
+[ 3660, "ejr" ],
+[ 3661, "ejs" ],
+[ 3662, "ejt" ],
+[ 3663, "eju" ],
+[ 3664, "ejv" ],
+[ 3665, "ejw" ],
+[ 3666, "ejx" ],
+[ 3667, "ejy" ],
+[ 3668, "ejz" ],
+[ 3669, "eka" ],
+[ 3670, "ekb" ],
+[ 3671, "ekc" ],
+[ 3672, "ekd" ],
+[ 3673, "eke" ],
+[ 3674, "ekf" ],
+[ 3675, "ekg" ],
+[ 3676, "ekh" ],
+[ 3677, "eki" ],
+[ 3678, "ekj" ],
+[ 3679, "ekk" ],
+[ 3680, "ekl" ],
+[ 3681, "ekm" ],
+[ 3682, "ekn" ],
+[ 3683, "eko" ],
+[ 3684, "ekp" ],
+[ 3685, "ekq" ],
+[ 3686, "ekr" ],
+[ 3687, "eks" ],
+[ 3688, "ekt" ],
+[ 3689, "eku" ],
+[ 3690, "ekv" ],
+[ 3691, "ekw" ],
+[ 3692, "ekx" ],
+[ 3693, "eky" ],
+[ 3694, "ekz" ],
+[ 3695, "ela" ],
+[ 3696, "elb" ],
+[ 3697, "elc" ],
+[ 3698, "eld" ],
+[ 3699, "ele" ],
+[ 3700, "elf" ],
+[ 3701, "elg" ],
+[ 3702, "elh" ],
+[ 3703, "eli" ],
+[ 3704, "elj" ],
+[ 3705, "elk" ],
+[ 3706, "ell" ],
+[ 3707, "elm" ],
+[ 3708, "eln" ],
+[ 3709, "elo" ],
+[ 3710, "elp" ],
+[ 3711, "elq" ],
+[ 3712, "elr" ],
+[ 3713, "els" ],
+[ 3714, "elt" ],
+[ 3715, "elu" ],
+[ 3716, "elv" ],
+[ 3717, "elw" ],
+[ 3718, "elx" ],
+[ 3719, "ely" ],
+[ 3720, "elz" ],
+[ 3721, "ema" ],
+[ 3722, "emb" ],
+[ 3723, "emc" ],
+[ 3724, "emd" ],
+[ 3725, "eme" ],
+[ 3726, "emf" ],
+[ 3727, "emg" ],
+[ 3728, "emh" ],
+[ 3729, "emi" ],
+[ 3730, "emj" ],
+[ 3731, "emk" ],
+[ 3732, "eml" ],
+[ 3733, "emm" ],
+[ 3734, "emn" ],
+[ 3735, "emo" ],
+[ 3736, "emp" ],
+[ 3737, "emq" ],
+[ 3738, "emr" ],
+[ 3739, "ems" ],
+[ 3740, "emt" ],
+[ 3741, "emu" ],
+[ 3742, "emv" ],
+[ 3743, "emw" ],
+[ 3744, "emx" ],
+[ 3745, "emy" ],
+[ 3746, "emz" ],
+[ 3747, "ena" ],
+[ 3748, "enb" ],
+[ 3749, "enc" ],
+[ 3750, "end" ],
+[ 3751, "ene" ],
+[ 3752, "enf" ],
+[ 3753, "eng" ],
+[ 3754, "enh" ],
+[ 3755, "eni" ],
+[ 3756, "enj" ],
+[ 3757, "enk" ],
+[ 3758, "enl" ],
+[ 3759, "enm" ],
+[ 3760, "enn" ],
+[ 3761, "eno" ],
+[ 3762, "enp" ],
+[ 3763, "enq" ],
+[ 3764, "enr" ],
+[ 3765, "ens" ],
+[ 3766, "ent" ],
+[ 3767, "enu" ],
+[ 3768, "env" ],
+[ 3769, "enw" ],
+[ 3770, "enx" ],
+[ 3771, "eny" ],
+[ 3772, "enz" ],
+[ 3773, "eoa" ],
+[ 3774, "eob" ],
+[ 3775, "eoc" ],
+[ 3776, "eod" ],
+[ 3777, "eoe" ],
+[ 3778, "eof" ],
+[ 3779, "eog" ],
+[ 3780, "eoh" ],
+[ 3781, "eoi" ],
+[ 3782, "eoj" ],
+[ 3783, "eok" ],
+[ 3784, "eol" ],
+[ 3785, "eom" ],
+[ 3786, "eon" ],
+[ 3787, "eoo" ],
+[ 3788, "eop" ],
+[ 3789, "eoq" ],
+[ 3790, "eor" ],
+[ 3791, "eos" ],
+[ 3792, "eot" ],
+[ 3793, "eou" ],
+[ 3794, "eov" ],
+[ 3795, "eow" ],
+[ 3796, "eox" ],
+[ 3797, "eoy" ],
+[ 3798, "eoz" ],
+[ 3799, "epa" ],
+[ 3800, "epb" ],
+[ 3801, "epc" ],
+[ 3802, "epd" ],
+[ 3803, "epe" ],
+[ 3804, "epf" ],
+[ 3805, "epg" ],
+[ 3806, "eph" ],
+[ 3807, "epi" ],
+[ 3808, "epj" ],
+[ 3809, "epk" ],
+[ 3810, "epl" ],
+[ 3811, "epm" ],
+[ 3812, "epn" ],
+[ 3813, "epo" ],
+[ 3814, "epp" ],
+[ 3815, "epq" ],
+[ 3816, "epr" ],
+[ 3817, "eps" ],
+[ 3818, "ept" ],
+[ 3819, "epu" ],
+[ 3820, "epv" ],
+[ 3821, "epw" ],
+[ 3822, "epx" ],
+[ 3823, "epy" ],
+[ 3824, "epz" ],
+[ 3825, "eqa" ],
+[ 3826, "eqb" ],
+[ 3827, "eqc" ],
+[ 3828, "eqd" ],
+[ 3829, "eqe" ],
+[ 3830, "eqf" ],
+[ 3831, "eqg" ],
+[ 3832, "eqh" ],
+[ 3833, "eqi" ],
+[ 3834, "eqj" ],
+[ 3835, "eqk" ],
+[ 3836, "eql" ],
+[ 3837, "eqm" ],
+[ 3838, "eqn" ],
+[ 3839, "eqo" ],
+[ 3840, "eqp" ],
+[ 3841, "eqq" ],
+[ 3842, "eqr" ],
+[ 3843, "eqs" ],
+[ 3844, "eqt" ],
+[ 3845, "equ" ],
+[ 3846, "eqv" ],
+[ 3847, "eqw" ],
+[ 3848, "eqx" ],
+[ 3849, "eqy" ],
+[ 3850, "eqz" ],
+[ 3851, "era" ],
+[ 3852, "erb" ],
+[ 3853, "erc" ],
+[ 3854, "erd" ],
+[ 3855, "ere" ],
+[ 3856, "erf" ],
+[ 3857, "erg" ],
+[ 3858, "erh" ],
+[ 3859, "eri" ],
+[ 3860, "erj" ],
+[ 3861, "erk" ],
+[ 3862, "erl" ],
+[ 3863, "erm" ],
+[ 3864, "ern" ],
+[ 3865, "ero" ],
+[ 3866, "erp" ],
+[ 3867, "erq" ],
+[ 3868, "err" ],
+[ 3869, "ers" ],
+[ 3870, "ert" ],
+[ 3871, "eru" ],
+[ 3872, "erv" ],
+[ 3873, "erw" ],
+[ 3874, "erx" ],
+[ 3875, "ery" ],
+[ 3876, "erz" ],
+[ 3877, "esa" ],
+[ 3878, "esb" ],
+[ 3879, "esc" ],
+[ 3880, "esd" ],
+[ 3881, "ese" ],
+[ 3882, "esf" ],
+[ 3883, "esg" ],
+[ 3884, "esh" ],
+[ 3885, "esi" ],
+[ 3886, "esj" ],
+[ 3887, "esk" ],
+[ 3888, "esl" ],
+[ 3889, "esm" ],
+[ 3890, "esn" ],
+[ 3891, "eso" ],
+[ 3892, "esp" ],
+[ 3893, "esq" ],
+[ 3894, "esr" ],
+[ 3895, "ess" ],
+[ 3896, "est" ],
+[ 3897, "esu" ],
+[ 3898, "esv" ],
+[ 3899, "esw" ],
+[ 3900, "esx" ],
+[ 3901, "esy" ],
+[ 3902, "esz" ],
+[ 3903, "eta" ],
+[ 3904, "etb" ],
+[ 3905, "etc" ],
+[ 3906, "etd" ],
+[ 3907, "ete" ],
+[ 3908, "etf" ],
+[ 3909, "etg" ],
+[ 3910, "eth" ],
+[ 3911, "eti" ],
+[ 3912, "etj" ],
+[ 3913, "etk" ],
+[ 3914, "etl" ],
+[ 3915, "etm" ],
+[ 3916, "etn" ],
+[ 3917, "eto" ],
+[ 3918, "etp" ],
+[ 3919, "etq" ],
+[ 3920, "etr" ],
+[ 3921, "ets" ],
+[ 3922, "ett" ],
+[ 3923, "etu" ],
+[ 3924, "etv" ],
+[ 3925, "etw" ],
+[ 3926, "etx" ],
+[ 3927, "ety" ],
+[ 3928, "etz" ],
+[ 3929, "eua" ],
+[ 3930, "eub" ],
+[ 3931, "euc" ],
+[ 3932, "eud" ],
+[ 3933, "eue" ],
+[ 3934, "euf" ],
+[ 3935, "eug" ],
+[ 3936, "euh" ],
+[ 3937, "eui" ],
+[ 3938, "euj" ],
+[ 3939, "euk" ],
+[ 3940, "eul" ],
+[ 3941, "eum" ],
+[ 3942, "eun" ],
+[ 3943, "euo" ],
+[ 3944, "eup" ],
+[ 3945, "euq" ],
+[ 3946, "eur" ],
+[ 3947, "eus" ],
+[ 3948, "eut" ],
+[ 3949, "euu" ],
+[ 3950, "euv" ],
+[ 3951, "euw" ],
+[ 3952, "eux" ],
+[ 3953, "euy" ],
+[ 3954, "euz" ],
+[ 3955, "eva" ],
+[ 3956, "evb" ],
+[ 3957, "evc" ],
+[ 3958, "evd" ],
+[ 3959, "eve" ],
+[ 3960, "evf" ],
+[ 3961, "evg" ],
+[ 3962, "evh" ],
+[ 3963, "evi" ],
+[ 3964, "evj" ],
+[ 3965, "evk" ],
+[ 3966, "evl" ],
+[ 3967, "evm" ],
+[ 3968, "evn" ],
+[ 3969, "evo" ],
+[ 3970, "evp" ],
+[ 3971, "evq" ],
+[ 3972, "evr" ],
+[ 3973, "evs" ],
+[ 3974, "evt" ],
+[ 3975, "evu" ],
+[ 3976, "evv" ],
+[ 3977, "evw" ],
+[ 3978, "evx" ],
+[ 3979, "evy" ],
+[ 3980, "evz" ],
+[ 3981, "ewa" ],
+[ 3982, "ewb" ],
+[ 3983, "ewc" ],
+[ 3984, "ewd" ],
+[ 3985, "ewe" ],
+[ 3986, "ewf" ],
+[ 3987, "ewg" ],
+[ 3988, "ewh" ],
+[ 3989, "ewi" ],
+[ 3990, "ewj" ],
+[ 3991, "ewk" ],
+[ 3992, "ewl" ],
+[ 3993, "ewm" ],
+[ 3994, "ewn" ],
+[ 3995, "ewo" ],
+[ 3996, "ewp" ],
+[ 3997, "ewq" ],
+[ 3998, "ewr" ],
+[ 3999, "ews" ],
+[ 4000, "ewt" ],
+[ 4001, "ewu" ],
+[ 4002, "ewv" ],
+[ 4003, "eww" ],
+[ 4004, "ewx" ],
+[ 4005, "ewy" ],
+[ 4006, "ewz" ],
+[ 4007, "exa" ],
+[ 4008, "exb" ],
+[ 4009, "exc" ],
+[ 4010, "exd" ],
+[ 4011, "exe" ],
+[ 4012, "exf" ],
+[ 4013, "exg" ],
+[ 4014, "exh" ],
+[ 4015, "exi" ],
+[ 4016, "exj" ],
+[ 4017, "exk" ],
+[ 4018, "exl" ],
+[ 4019, "exm" ],
+[ 4020, "exn" ],
+[ 4021, "exo" ],
+[ 4022, "exp" ],
+[ 4023, "exq" ],
+[ 4024, "exr" ],
+[ 4025, "exs" ],
+[ 4026, "ext" ],
+[ 4027, "exu" ],
+[ 4028, "exv" ],
+[ 4029, "exw" ],
+[ 4030, "exx" ],
+[ 4031, "exy" ],
+[ 4032, "exz" ],
+[ 4033, "eya" ],
+[ 4034, "eyb" ],
+[ 4035, "eyc" ],
+[ 4036, "eyd" ],
+[ 4037, "eye" ],
+[ 4038, "eyf" ],
+[ 4039, "eyg" ],
+[ 4040, "eyh" ],
+[ 4041, "eyi" ],
+[ 4042, "eyj" ],
+[ 4043, "eyk" ],
+[ 4044, "eyl" ],
+[ 4045, "eym" ],
+[ 4046, "eyn" ],
+[ 4047, "eyo" ],
+[ 4048, "eyp" ],
+[ 4049, "eyq" ],
+[ 4050, "eyr" ],
+[ 4051, "eys" ],
+[ 4052, "eyt" ],
+[ 4053, "eyu" ],
+[ 4054, "eyv" ],
+[ 4055, "eyw" ],
+[ 4056, "eyx" ],
+[ 4057, "eyy" ],
+[ 4058, "eyz" ],
+[ 4059, "eza" ],
+[ 4060, "ezb" ],
+[ 4061, "ezc" ],
+[ 4062, "ezd" ],
+[ 4063, "eze" ],
+[ 4064, "ezf" ],
+[ 4065, "ezg" ],
+[ 4066, "ezh" ],
+[ 4067, "ezi" ],
+[ 4068, "ezj" ],
+[ 4069, "ezk" ],
+[ 4070, "ezl" ],
+[ 4071, "ezm" ],
+[ 4072, "ezn" ],
+[ 4073, "ezo" ],
+[ 4074, "ezp" ],
+[ 4075, "ezq" ],
+[ 4076, "ezr" ],
+[ 4077, "ezs" ],
+[ 4078, "ezt" ],
+[ 4079, "ezu" ],
+[ 4080, "ezv" ],
+[ 4081, "ezw" ],
+[ 4082, "ezx" ],
+[ 4083, "ezy" ],
+[ 4084, "ezz" ],
+[ 4085, "faa" ],
+[ 4086, "fab" ],
+[ 4087, "fac" ],
+[ 4088, "fad" ],
+[ 4089, "fae" ],
+[ 4090, "faf" ],
+[ 4091, "fag" ],
+[ 4092, "fah" ],
+[ 4093, "fai" ],
+[ 4094, "faj" ],
+[ 4095, "fak" ],
+[ 4096, "fal" ],
+[ 4097, "fam" ],
+[ 4098, "fan" ],
+[ 4099, "fao" ],
+[ 4100, "fap" ],
+[ 4101, "faq" ],
+[ 4102, "far" ],
+[ 4103, "fas" ],
+[ 4104, "fat" ],
+[ 4105, "fau" ],
+[ 4106, "fav" ],
+[ 4107, "faw" ],
+[ 4108, "fax" ],
+[ 4109, "fay" ],
+[ 4110, "faz" ],
+[ 4111, "fba" ],
+[ 4112, "fbb" ],
+[ 4113, "fbc" ],
+[ 4114, "fbd" ],
+[ 4115, "fbe" ],
+[ 4116, "fbf" ],
+[ 4117, "fbg" ],
+[ 4118, "fbh" ],
+[ 4119, "fbi" ],
+[ 4120, "fbj" ],
+[ 4121, "fbk" ],
+[ 4122, "fbl" ],
+[ 4123, "fbm" ],
+[ 4124, "fbn" ],
+[ 4125, "fbo" ],
+[ 4126, "fbp" ],
+[ 4127, "fbq" ],
+[ 4128, "fbr" ],
+[ 4129, "fbs" ],
+[ 4130, "fbt" ],
+[ 4131, "fbu" ],
+[ 4132, "fbv" ],
+[ 4133, "fbw" ],
+[ 4134, "fbx" ],
+[ 4135, "fby" ],
+[ 4136, "fbz" ],
+[ 4137, "fca" ],
+[ 4138, "fcb" ],
+[ 4139, "fcc" ],
+[ 4140, "fcd" ],
+[ 4141, "fce" ],
+[ 4142, "fcf" ],
+[ 4143, "fcg" ],
+[ 4144, "fch" ],
+[ 4145, "fci" ],
+[ 4146, "fcj" ],
+[ 4147, "fck" ],
+[ 4148, "fcl" ],
+[ 4149, "fcm" ],
+[ 4150, "fcn" ],
+[ 4151, "fco" ],
+[ 4152, "fcp" ],
+[ 4153, "fcq" ],
+[ 4154, "fcr" ],
+[ 4155, "fcs" ],
+[ 4156, "fct" ],
+[ 4157, "fcu" ],
+[ 4158, "fcv" ],
+[ 4159, "fcw" ],
+[ 4160, "fcx" ],
+[ 4161, "fcy" ],
+[ 4162, "fcz" ],
+[ 4163, "fda" ],
+[ 4164, "fdb" ],
+[ 4165, "fdc" ],
+[ 4166, "fdd" ],
+[ 4167, "fde" ],
+[ 4168, "fdf" ],
+[ 4169, "fdg" ],
+[ 4170, "fdh" ],
+[ 4171, "fdi" ],
+[ 4172, "fdj" ],
+[ 4173, "fdk" ],
+[ 4174, "fdl" ],
+[ 4175, "fdm" ],
+[ 4176, "fdn" ],
+[ 4177, "fdo" ],
+[ 4178, "fdp" ],
+[ 4179, "fdq" ],
+[ 4180, "fdr" ],
+[ 4181, "fds" ],
+[ 4182, "fdt" ],
+[ 4183, "fdu" ],
+[ 4184, "fdv" ],
+[ 4185, "fdw" ],
+[ 4186, "fdx" ],
+[ 4187, "fdy" ],
+[ 4188, "fdz" ],
+[ 4189, "fea" ],
+[ 4190, "feb" ],
+[ 4191, "fec" ],
+[ 4192, "fed" ],
+[ 4193, "fee" ],
+[ 4194, "fef" ],
+[ 4195, "feg" ],
+[ 4196, "feh" ],
+[ 4197, "fei" ],
+[ 4198, "fej" ],
+[ 4199, "fek" ],
+[ 4200, "fel" ],
+[ 4201, "fem" ],
+[ 4202, "fen" ],
+[ 4203, "feo" ],
+[ 4204, "fep" ],
+[ 4205, "feq" ],
+[ 4206, "fer" ],
+[ 4207, "fes" ],
+[ 4208, "fet" ],
+[ 4209, "feu" ],
+[ 4210, "fev" ],
+[ 4211, "few" ],
+[ 4212, "fex" ],
+[ 4213, "fey" ],
+[ 4214, "fez" ],
+[ 4215, "ffa" ],
+[ 4216, "ffb" ],
+[ 4217, "ffc" ],
+[ 4218, "ffd" ],
+[ 4219, "ffe" ],
+[ 4220, "fff" ],
+[ 4221, "ffg" ],
+[ 4222, "ffh" ],
+[ 4223, "ffi" ],
+[ 4224, "ffj" ],
+[ 4225, "ffk" ],
+[ 4226, "ffl" ],
+[ 4227, "ffm" ],
+[ 4228, "ffn" ],
+[ 4229, "ffo" ],
+[ 4230, "ffp" ],
+[ 4231, "ffq" ],
+[ 4232, "ffr" ],
+[ 4233, "ffs" ],
+[ 4234, "fft" ],
+[ 4235, "ffu" ],
+[ 4236, "ffv" ],
+[ 4237, "ffw" ],
+[ 4238, "ffx" ],
+[ 4239, "ffy" ],
+[ 4240, "ffz" ],
+[ 4241, "fga" ],
+[ 4242, "fgb" ],
+[ 4243, "fgc" ],
+[ 4244, "fgd" ],
+[ 4245, "fge" ],
+[ 4246, "fgf" ],
+[ 4247, "fgg" ],
+[ 4248, "fgh" ],
+[ 4249, "fgi" ],
+[ 4250, "fgj" ],
+[ 4251, "fgk" ],
+[ 4252, "fgl" ],
+[ 4253, "fgm" ],
+[ 4254, "fgn" ],
+[ 4255, "fgo" ],
+[ 4256, "fgp" ],
+[ 4257, "fgq" ],
+[ 4258, "fgr" ],
+[ 4259, "fgs" ],
+[ 4260, "fgt" ],
+[ 4261, "fgu" ],
+[ 4262, "fgv" ],
+[ 4263, "fgw" ],
+[ 4264, "fgx" ],
+[ 4265, "fgy" ],
+[ 4266, "fgz" ],
+[ 4267, "fha" ],
+[ 4268, "fhb" ],
+[ 4269, "fhc" ],
+[ 4270, "fhd" ],
+[ 4271, "fhe" ],
+[ 4272, "fhf" ],
+[ 4273, "fhg" ],
+[ 4274, "fhh" ],
+[ 4275, "fhi" ],
+[ 4276, "fhj" ],
+[ 4277, "fhk" ],
+[ 4278, "fhl" ],
+[ 4279, "fhm" ],
+[ 4280, "fhn" ],
+[ 4281, "fho" ],
+[ 4282, "fhp" ],
+[ 4283, "fhq" ],
+[ 4284, "fhr" ],
+[ 4285, "fhs" ],
+[ 4286, "fht" ],
+[ 4287, "fhu" ],
+[ 4288, "fhv" ],
+[ 4289, "fhw" ],
+[ 4290, "fhx" ],
+[ 4291, "fhy" ],
+[ 4292, "fhz" ],
+[ 4293, "fia" ],
+[ 4294, "fib" ],
+[ 4295, "fic" ],
+[ 4296, "fid" ],
+[ 4297, "fie" ],
+[ 4298, "fif" ],
+[ 4299, "fig" ],
+[ 4300, "fih" ],
+[ 4301, "fii" ],
+[ 4302, "fij" ],
+[ 4303, "fik" ],
+[ 4304, "fil" ],
+[ 4305, "fim" ],
+[ 4306, "fin" ],
+[ 4307, "fio" ],
+[ 4308, "fip" ],
+[ 4309, "fiq" ],
+[ 4310, "fir" ],
+[ 4311, "fis" ],
+[ 4312, "fit" ],
+[ 4313, "fiu" ],
+[ 4314, "fiv" ],
+[ 4315, "fiw" ],
+[ 4316, "fix" ],
+[ 4317, "fiy" ],
+[ 4318, "fiz" ],
+[ 4319, "fja" ],
+[ 4320, "fjb" ],
+[ 4321, "fjc" ],
+[ 4322, "fjd" ],
+[ 4323, "fje" ],
+[ 4324, "fjf" ],
+[ 4325, "fjg" ],
+[ 4326, "fjh" ],
+[ 4327, "fji" ],
+[ 4328, "fjj" ],
+[ 4329, "fjk" ],
+[ 4330, "fjl" ],
+[ 4331, "fjm" ],
+[ 4332, "fjn" ],
+[ 4333, "fjo" ],
+[ 4334, "fjp" ],
+[ 4335, "fjq" ],
+[ 4336, "fjr" ],
+[ 4337, "fjs" ],
+[ 4338, "fjt" ],
+[ 4339, "fju" ],
+[ 4340, "fjv" ],
+[ 4341, "fjw" ],
+[ 4342, "fjx" ],
+[ 4343, "fjy" ],
+[ 4344, "fjz" ],
+[ 4345, "fka" ],
+[ 4346, "fkb" ],
+[ 4347, "fkc" ],
+[ 4348, "fkd" ],
+[ 4349, "fke" ],
+[ 4350, "fkf" ],
+[ 4351, "fkg" ],
+[ 4352, "fkh" ],
+[ 4353, "fki" ],
+[ 4354, "fkj" ],
+[ 4355, "fkk" ],
+[ 4356, "fkl" ],
+[ 4357, "fkm" ],
+[ 4358, "fkn" ],
+[ 4359, "fko" ],
+[ 4360, "fkp" ],
+[ 4361, "fkq" ],
+[ 4362, "fkr" ],
+[ 4363, "fks" ],
+[ 4364, "fkt" ],
+[ 4365, "fku" ],
+[ 4366, "fkv" ],
+[ 4367, "fkw" ],
+[ 4368, "fkx" ],
+[ 4369, "fky" ],
+[ 4370, "fkz" ],
+[ 4371, "fla" ],
+[ 4372, "flb" ],
+[ 4373, "flc" ],
+[ 4374, "fld" ],
+[ 4375, "fle" ],
+[ 4376, "flf" ],
+[ 4377, "flg" ],
+[ 4378, "flh" ],
+[ 4379, "fli" ],
+[ 4380, "flj" ],
+[ 4381, "flk" ],
+[ 4382, "fll" ],
+[ 4383, "flm" ],
+[ 4384, "fln" ],
+[ 4385, "flo" ],
+[ 4386, "flp" ],
+[ 4387, "flq" ],
+[ 4388, "flr" ],
+[ 4389, "fls" ],
+[ 4390, "flt" ],
+[ 4391, "flu" ],
+[ 4392, "flv" ],
+[ 4393, "flw" ],
+[ 4394, "flx" ],
+[ 4395, "fly" ],
+[ 4396, "flz" ],
+[ 4397, "fma" ],
+[ 4398, "fmb" ],
+[ 4399, "fmc" ],
+[ 4400, "fmd" ],
+[ 4401, "fme" ],
+[ 4402, "fmf" ],
+[ 4403, "fmg" ],
+[ 4404, "fmh" ],
+[ 4405, "fmi" ],
+[ 4406, "fmj" ],
+[ 4407, "fmk" ],
+[ 4408, "fml" ],
+[ 4409, "fmm" ],
+[ 4410, "fmn" ],
+[ 4411, "fmo" ],
+[ 4412, "fmp" ],
+[ 4413, "fmq" ],
+[ 4414, "fmr" ],
+[ 4415, "fms" ],
+[ 4416, "fmt" ],
+[ 4417, "fmu" ],
+[ 4418, "fmv" ],
+[ 4419, "fmw" ],
+[ 4420, "fmx" ],
+[ 4421, "fmy" ],
+[ 4422, "fmz" ],
+[ 4423, "fna" ],
+[ 4424, "fnb" ],
+[ 4425, "fnc" ],
+[ 4426, "fnd" ],
+[ 4427, "fne" ],
+[ 4428, "fnf" ],
+[ 4429, "fng" ],
+[ 4430, "fnh" ],
+[ 4431, "fni" ],
+[ 4432, "fnj" ],
+[ 4433, "fnk" ],
+[ 4434, "fnl" ],
+[ 4435, "fnm" ],
+[ 4436, "fnn" ],
+[ 4437, "fno" ],
+[ 4438, "fnp" ],
+[ 4439, "fnq" ],
+[ 4440, "fnr" ],
+[ 4441, "fns" ],
+[ 4442, "fnt" ],
+[ 4443, "fnu" ],
+[ 4444, "fnv" ],
+[ 4445, "fnw" ],
+[ 4446, "fnx" ],
+[ 4447, "fny" ],
+[ 4448, "fnz" ],
+[ 4449, "foa" ],
+[ 4450, "fob" ],
+[ 4451, "foc" ],
+[ 4452, "fod" ],
+[ 4453, "foe" ],
+[ 4454, "fof" ],
+[ 4455, "fog" ],
+[ 4456, "foh" ],
+[ 4457, "foi" ],
+[ 4458, "foj" ],
+[ 4459, "fok" ],
+[ 4460, "fol" ],
+[ 4461, "fom" ],
+[ 4462, "fon" ],
+[ 4463, "foo" ],
+[ 4464, "fop" ],
+[ 4465, "foq" ],
+[ 4466, "for" ],
+[ 4467, "fos" ],
+[ 4468, "fot" ],
+[ 4469, "fou" ],
+[ 4470, "fov" ],
+[ 4471, "fow" ],
+[ 4472, "fox" ],
+[ 4473, "foy" ],
+[ 4474, "foz" ],
+[ 4475, "fpa" ],
+[ 4476, "fpb" ],
+[ 4477, "fpc" ],
+[ 4478, "fpd" ],
+[ 4479, "fpe" ],
+[ 4480, "fpf" ],
+[ 4481, "fpg" ],
+[ 4482, "fph" ],
+[ 4483, "fpi" ],
+[ 4484, "fpj" ],
+[ 4485, "fpk" ],
+[ 4486, "fpl" ],
+[ 4487, "fpm" ],
+[ 4488, "fpn" ],
+[ 4489, "fpo" ],
+[ 4490, "fpp" ],
+[ 4491, "fpq" ],
+[ 4492, "fpr" ],
+[ 4493, "fps" ],
+[ 4494, "fpt" ],
+[ 4495, "fpu" ],
+[ 4496, "fpv" ],
+[ 4497, "fpw" ],
+[ 4498, "fpx" ],
+[ 4499, "fpy" ],
+[ 4500, "fpz" ],
+[ 4501, "fqa" ],
+[ 4502, "fqb" ],
+[ 4503, "fqc" ],
+[ 4504, "fqd" ],
+[ 4505, "fqe" ],
+[ 4506, "fqf" ],
+[ 4507, "fqg" ],
+[ 4508, "fqh" ],
+[ 4509, "fqi" ],
+[ 4510, "fqj" ],
+[ 4511, "fqk" ],
+[ 4512, "fql" ],
+[ 4513, "fqm" ],
+[ 4514, "fqn" ],
+[ 4515, "fqo" ],
+[ 4516, "fqp" ],
+[ 4517, "fqq" ],
+[ 4518, "fqr" ],
+[ 4519, "fqs" ],
+[ 4520, "fqt" ],
+[ 4521, "fqu" ],
+[ 4522, "fqv" ],
+[ 4523, "fqw" ],
+[ 4524, "fqx" ],
+[ 4525, "fqy" ],
+[ 4526, "fqz" ],
+[ 4527, "fra" ],
+[ 4528, "frb" ],
+[ 4529, "frc" ],
+[ 4530, "frd" ],
+[ 4531, "fre" ],
+[ 4532, "frf" ],
+[ 4533, "frg" ],
+[ 4534, "frh" ],
+[ 4535, "fri" ],
+[ 4536, "frj" ],
+[ 4537, "frk" ],
+[ 4538, "frl" ],
+[ 4539, "frm" ],
+[ 4540, "frn" ],
+[ 4541, "fro" ],
+[ 4542, "frp" ],
+[ 4543, "frq" ],
+[ 4544, "frr" ],
+[ 4545, "frs" ],
+[ 4546, "frt" ],
+[ 4547, "fru" ],
+[ 4548, "frv" ],
+[ 4549, "frw" ],
+[ 4550, "frx" ],
+[ 4551, "fry" ],
+[ 4552, "frz" ],
+[ 4553, "fsa" ],
+[ 4554, "fsb" ],
+[ 4555, "fsc" ],
+[ 4556, "fsd" ],
+[ 4557, "fse" ],
+[ 4558, "fsf" ],
+[ 4559, "fsg" ],
+[ 4560, "fsh" ],
+[ 4561, "fsi" ],
+[ 4562, "fsj" ],
+[ 4563, "fsk" ],
+[ 4564, "fsl" ],
+[ 4565, "fsm" ],
+[ 4566, "fsn" ],
+[ 4567, "fso" ],
+[ 4568, "fsp" ],
+[ 4569, "fsq" ],
+[ 4570, "fsr" ],
+[ 4571, "fss" ],
+[ 4572, "fst" ],
+[ 4573, "fsu" ],
+[ 4574, "fsv" ],
+[ 4575, "fsw" ],
+[ 4576, "fsx" ],
+[ 4577, "fsy" ],
+[ 4578, "fsz" ],
+[ 4579, "fta" ],
+[ 4580, "ftb" ],
+[ 4581, "ftc" ],
+[ 4582, "ftd" ],
+[ 4583, "fte" ],
+[ 4584, "ftf" ],
+[ 4585, "ftg" ],
+[ 4586, "fth" ],
+[ 4587, "fti" ],
+[ 4588, "ftj" ],
+[ 4589, "ftk" ],
+[ 4590, "ftl" ],
+[ 4591, "ftm" ],
+[ 4592, "ftn" ],
+[ 4593, "fto" ],
+[ 4594, "ftp" ],
+[ 4595, "ftq" ],
+[ 4596, "ftr" ],
+[ 4597, "fts" ],
+[ 4598, "ftt" ],
+[ 4599, "ftu" ],
+[ 4600, "ftv" ],
+[ 4601, "ftw" ],
+[ 4602, "ftx" ],
+[ 4603, "fty" ],
+[ 4604, "ftz" ],
+[ 4605, "fua" ],
+[ 4606, "fub" ],
+[ 4607, "fuc" ],
+[ 4608, "fud" ],
+[ 4609, "fue" ],
+[ 4610, "fuf" ],
+[ 4611, "fug" ],
+[ 4612, "fuh" ],
+[ 4613, "fui" ],
+[ 4614, "fuj" ],
+[ 4615, "fuk" ],
+[ 4616, "ful" ],
+[ 4617, "fum" ],
+[ 4618, "fun" ],
+[ 4619, "fuo" ],
+[ 4620, "fup" ],
+[ 4621, "fuq" ],
+[ 4622, "fur" ],
+[ 4623, "fus" ],
+[ 4624, "fut" ],
+[ 4625, "fuu" ],
+[ 4626, "fuv" ],
+[ 4627, "fuw" ],
+[ 4628, "fux" ],
+[ 4629, "fuy" ],
+[ 4630, "fuz" ],
+[ 4631, "fva" ],
+[ 4632, "fvb" ],
+[ 4633, "fvc" ],
+[ 4634, "fvd" ],
+[ 4635, "fve" ],
+[ 4636, "fvf" ],
+[ 4637, "fvg" ],
+[ 4638, "fvh" ],
+[ 4639, "fvi" ],
+[ 4640, "fvj" ],
+[ 4641, "fvk" ],
+[ 4642, "fvl" ],
+[ 4643, "fvm" ],
+[ 4644, "fvn" ],
+[ 4645, "fvo" ],
+[ 4646, "fvp" ],
+[ 4647, "fvq" ],
+[ 4648, "fvr" ],
+[ 4649, "fvs" ],
+[ 4650, "fvt" ],
+[ 4651, "fvu" ],
+[ 4652, "fvv" ],
+[ 4653, "fvw" ],
+[ 4654, "fvx" ],
+[ 4655, "fvy" ],
+[ 4656, "fvz" ],
+[ 4657, "fwa" ],
+[ 4658, "fwb" ],
+[ 4659, "fwc" ],
+[ 4660, "fwd" ],
+[ 4661, "fwe" ],
+[ 4662, "fwf" ],
+[ 4663, "fwg" ],
+[ 4664, "fwh" ],
+[ 4665, "fwi" ],
+[ 4666, "fwj" ],
+[ 4667, "fwk" ],
+[ 4668, "fwl" ],
+[ 4669, "fwm" ],
+[ 4670, "fwn" ],
+[ 4671, "fwo" ],
+[ 4672, "fwp" ],
+[ 4673, "fwq" ],
+[ 4674, "fwr" ],
+[ 4675, "fws" ],
+[ 4676, "fwt" ],
+[ 4677, "fwu" ],
+[ 4678, "fwv" ],
+[ 4679, "fww" ],
+[ 4680, "fwx" ],
+[ 4681, "fwy" ],
+[ 4682, "fwz" ],
+[ 4683, "fxa" ],
+[ 4684, "fxb" ],
+[ 4685, "fxc" ],
+[ 4686, "fxd" ],
+[ 4687, "fxe" ],
+[ 4688, "fxf" ],
+[ 4689, "fxg" ],
+[ 4690, "fxh" ],
+[ 4691, "fxi" ],
+[ 4692, "fxj" ],
+[ 4693, "fxk" ],
+[ 4694, "fxl" ],
+[ 4695, "fxm" ],
+[ 4696, "fxn" ],
+[ 4697, "fxo" ],
+[ 4698, "fxp" ],
+[ 4699, "fxq" ],
+[ 4700, "fxr" ],
+[ 4701, "fxs" ],
+[ 4702, "fxt" ],
+[ 4703, "fxu" ],
+[ 4704, "fxv" ],
+[ 4705, "fxw" ],
+[ 4706, "fxx" ],
+[ 4707, "fxy" ],
+[ 4708, "fxz" ],
+[ 4709, "fya" ],
+[ 4710, "fyb" ],
+[ 4711, "fyc" ],
+[ 4712, "fyd" ],
+[ 4713, "fye" ],
+[ 4714, "fyf" ],
+[ 4715, "fyg" ],
+[ 4716, "fyh" ],
+[ 4717, "fyi" ],
+[ 4718, "fyj" ],
+[ 4719, "fyk" ],
+[ 4720, "fyl" ],
+[ 4721, "fym" ],
+[ 4722, "fyn" ],
+[ 4723, "fyo" ],
+[ 4724, "fyp" ],
+[ 4725, "fyq" ],
+[ 4726, "fyr" ],
+[ 4727, "fys" ],
+[ 4728, "fyt" ],
+[ 4729, "fyu" ],
+[ 4730, "fyv" ],
+[ 4731, "fyw" ],
+[ 4732, "fyx" ],
+[ 4733, "fyy" ],
+[ 4734, "fyz" ],
+[ 4735, "fza" ],
+[ 4736, "fzb" ],
+[ 4737, "fzc" ],
+[ 4738, "fzd" ],
+[ 4739, "fze" ],
+[ 4740, "fzf" ],
+[ 4741, "fzg" ],
+[ 4742, "fzh" ],
+[ 4743, "fzi" ],
+[ 4744, "fzj" ],
+[ 4745, "fzk" ],
+[ 4746, "fzl" ],
+[ 4747, "fzm" ],
+[ 4748, "fzn" ],
+[ 4749, "fzo" ],
+[ 4750, "fzp" ],
+[ 4751, "fzq" ],
+[ 4752, "fzr" ],
+[ 4753, "fzs" ],
+[ 4754, "fzt" ],
+[ 4755, "fzu" ],
+[ 4756, "fzv" ],
+[ 4757, "fzw" ],
+[ 4758, "fzx" ],
+[ 4759, "fzy" ],
+[ 4760, "fzz" ],
+[ 4761, "gaa" ],
+[ 4762, "gab" ],
+[ 4763, "gac" ],
+[ 4764, "gad" ],
+[ 4765, "gae" ],
+[ 4766, "gaf" ],
+[ 4767, "gag" ],
+[ 4768, "gah" ],
+[ 4769, "gai" ],
+[ 4770, "gaj" ],
+[ 4771, "gak" ],
+[ 4772, "gal" ],
+[ 4773, "gam" ],
+[ 4774, "gan" ],
+[ 4775, "gao" ],
+[ 4776, "gap" ],
+[ 4777, "gaq" ],
+[ 4778, "gar" ],
+[ 4779, "gas" ],
+[ 4780, "gat" ],
+[ 4781, "gau" ],
+[ 4782, "gav" ],
+[ 4783, "gaw" ],
+[ 4784, "gax" ],
+[ 4785, "gay" ],
+[ 4786, "gaz" ],
+[ 4787, "gba" ],
+[ 4788, "gbb" ],
+[ 4789, "gbc" ],
+[ 4790, "gbd" ],
+[ 4791, "gbe" ],
+[ 4792, "gbf" ],
+[ 4793, "gbg" ],
+[ 4794, "gbh" ],
+[ 4795, "gbi" ],
+[ 4796, "gbj" ],
+[ 4797, "gbk" ],
+[ 4798, "gbl" ],
+[ 4799, "gbm" ],
+[ 4800, "gbn" ],
+[ 4801, "gbo" ],
+[ 4802, "gbp" ],
+[ 4803, "gbq" ],
+[ 4804, "gbr" ],
+[ 4805, "gbs" ],
+[ 4806, "gbt" ],
+[ 4807, "gbu" ],
+[ 4808, "gbv" ],
+[ 4809, "gbw" ],
+[ 4810, "gbx" ],
+[ 4811, "gby" ],
+[ 4812, "gbz" ],
+[ 4813, "gca" ],
+[ 4814, "gcb" ],
+[ 4815, "gcc" ],
+[ 4816, "gcd" ],
+[ 4817, "gce" ],
+[ 4818, "gcf" ],
+[ 4819, "gcg" ],
+[ 4820, "gch" ],
+[ 4821, "gci" ],
+[ 4822, "gcj" ],
+[ 4823, "gck" ],
+[ 4824, "gcl" ],
+[ 4825, "gcm" ],
+[ 4826, "gcn" ],
+[ 4827, "gco" ],
+[ 4828, "gcp" ],
+[ 4829, "gcq" ],
+[ 4830, "gcr" ],
+[ 4831, "gcs" ],
+[ 4832, "gct" ],
+[ 4833, "gcu" ],
+[ 4834, "gcv" ],
+[ 4835, "gcw" ],
+[ 4836, "gcx" ],
+[ 4837, "gcy" ],
+[ 4838, "gcz" ],
+[ 4839, "gda" ],
+[ 4840, "gdb" ],
+[ 4841, "gdc" ],
+[ 4842, "gdd" ],
+[ 4843, "gde" ],
+[ 4844, "gdf" ],
+[ 4845, "gdg" ],
+[ 4846, "gdh" ],
+[ 4847, "gdi" ],
+[ 4848, "gdj" ],
+[ 4849, "gdk" ],
+[ 4850, "gdl" ],
+[ 4851, "gdm" ],
+[ 4852, "gdn" ],
+[ 4853, "gdo" ],
+[ 4854, "gdp" ],
+[ 4855, "gdq" ],
+[ 4856, "gdr" ],
+[ 4857, "gds" ],
+[ 4858, "gdt" ],
+[ 4859, "gdu" ],
+[ 4860, "gdv" ],
+[ 4861, "gdw" ],
+[ 4862, "gdx" ],
+[ 4863, "gdy" ],
+[ 4864, "gdz" ],
+[ 4865, "gea" ],
+[ 4866, "geb" ],
+[ 4867, "gec" ],
+[ 4868, "ged" ],
+[ 4869, "gee" ],
+[ 4870, "gef" ],
+[ 4871, "geg" ],
+[ 4872, "geh" ],
+[ 4873, "gei" ],
+[ 4874, "gej" ],
+[ 4875, "gek" ],
+[ 4876, "gel" ],
+[ 4877, "gem" ],
+[ 4878, "gen" ],
+[ 4879, "geo" ],
+[ 4880, "gep" ],
+[ 4881, "geq" ],
+[ 4882, "ger" ],
+[ 4883, "ges" ],
+[ 4884, "get" ],
+[ 4885, "geu" ],
+[ 4886, "gev" ],
+[ 4887, "gew" ],
+[ 4888, "gex" ],
+[ 4889, "gey" ],
+[ 4890, "gez" ],
+[ 4891, "gfa" ],
+[ 4892, "gfb" ],
+[ 4893, "gfc" ],
+[ 4894, "gfd" ],
+[ 4895, "gfe" ],
+[ 4896, "gff" ],
+[ 4897, "gfg" ],
+[ 4898, "gfh" ],
+[ 4899, "gfi" ],
+[ 4900, "gfj" ],
+[ 4901, "gfk" ],
+[ 4902, "gfl" ],
+[ 4903, "gfm" ],
+[ 4904, "gfn" ],
+[ 4905, "gfo" ],
+[ 4906, "gfp" ],
+[ 4907, "gfq" ],
+[ 4908, "gfr" ],
+[ 4909, "gfs" ],
+[ 4910, "gft" ],
+[ 4911, "gfu" ],
+[ 4912, "gfv" ],
+[ 4913, "gfw" ],
+[ 4914, "gfx" ],
+[ 4915, "gfy" ],
+[ 4916, "gfz" ],
+[ 4917, "gga" ],
+[ 4918, "ggb" ],
+[ 4919, "ggc" ],
+[ 4920, "ggd" ],
+[ 4921, "gge" ],
+[ 4922, "ggf" ],
+[ 4923, "ggg" ],
+[ 4924, "ggh" ],
+[ 4925, "ggi" ],
+[ 4926, "ggj" ],
+[ 4927, "ggk" ],
+[ 4928, "ggl" ],
+[ 4929, "ggm" ],
+[ 4930, "ggn" ],
+[ 4931, "ggo" ],
+[ 4932, "ggp" ],
+[ 4933, "ggq" ],
+[ 4934, "ggr" ],
+[ 4935, "ggs" ],
+[ 4936, "ggt" ],
+[ 4937, "ggu" ],
+[ 4938, "ggv" ],
+[ 4939, "ggw" ],
+[ 4940, "ggx" ],
+[ 4941, "ggy" ],
+[ 4942, "ggz" ],
+[ 4943, "gha" ],
+[ 4944, "ghb" ],
+[ 4945, "ghc" ],
+[ 4946, "ghd" ],
+[ 4947, "ghe" ],
+[ 4948, "ghf" ],
+[ 4949, "ghg" ],
+[ 4950, "ghh" ],
+[ 4951, "ghi" ],
+[ 4952, "ghj" ],
+[ 4953, "ghk" ],
+[ 4954, "ghl" ],
+[ 4955, "ghm" ],
+[ 4956, "ghn" ],
+[ 4957, "gho" ],
+[ 4958, "ghp" ],
+[ 4959, "ghq" ],
+[ 4960, "ghr" ],
+[ 4961, "ghs" ],
+[ 4962, "ght" ],
+[ 4963, "ghu" ],
+[ 4964, "ghv" ],
+[ 4965, "ghw" ],
+[ 4966, "ghx" ],
+[ 4967, "ghy" ],
+[ 4968, "ghz" ],
+[ 4969, "gia" ],
+[ 4970, "gib" ],
+[ 4971, "gic" ],
+[ 4972, "gid" ],
+[ 4973, "gie" ],
+[ 4974, "gif" ],
+[ 4975, "gig" ],
+[ 4976, "gih" ],
+[ 4977, "gii" ],
+[ 4978, "gij" ],
+[ 4979, "gik" ],
+[ 4980, "gil" ],
+[ 4981, "gim" ],
+[ 4982, "gin" ],
+[ 4983, "gio" ],
+[ 4984, "gip" ],
+[ 4985, "giq" ],
+[ 4986, "gir" ],
+[ 4987, "gis" ],
+[ 4988, "git" ],
+[ 4989, "giu" ],
+[ 4990, "giv" ],
+[ 4991, "giw" ],
+[ 4992, "gix" ],
+[ 4993, "giy" ],
+[ 4994, "giz" ],
+[ 4995, "gja" ],
+[ 4996, "gjb" ],
+[ 4997, "gjc" ],
+[ 4998, "gjd" ],
+[ 4999, "gje" ],
+[ 5000, "gjf" ],
+[ 5001, "gjg" ],
+[ 5002, "gjh" ],
+[ 5003, "gji" ],
+[ 5004, "gjj" ],
+[ 5005, "gjk" ],
+[ 5006, "gjl" ],
+[ 5007, "gjm" ],
+[ 5008, "gjn" ],
+[ 5009, "gjo" ],
+[ 5010, "gjp" ],
+[ 5011, "gjq" ],
+[ 5012, "gjr" ],
+[ 5013, "gjs" ],
+[ 5014, "gjt" ],
+[ 5015, "gju" ],
+[ 5016, "gjv" ],
+[ 5017, "gjw" ],
+[ 5018, "gjx" ],
+[ 5019, "gjy" ],
+[ 5020, "gjz" ],
+[ 5021, "gka" ],
+[ 5022, "gkb" ],
+[ 5023, "gkc" ],
+[ 5024, "gkd" ],
+[ 5025, "gke" ],
+[ 5026, "gkf" ],
+[ 5027, "gkg" ],
+[ 5028, "gkh" ],
+[ 5029, "gki" ],
+[ 5030, "gkj" ],
+[ 5031, "gkk" ],
+[ 5032, "gkl" ],
+[ 5033, "gkm" ],
+[ 5034, "gkn" ],
+[ 5035, "gko" ],
+[ 5036, "gkp" ],
+[ 5037, "gkq" ],
+[ 5038, "gkr" ],
+[ 5039, "gks" ],
+[ 5040, "gkt" ],
+[ 5041, "gku" ],
+[ 5042, "gkv" ],
+[ 5043, "gkw" ],
+[ 5044, "gkx" ],
+[ 5045, "gky" ],
+[ 5046, "gkz" ],
+[ 5047, "gla" ],
+[ 5048, "glb" ],
+[ 5049, "glc" ],
+[ 5050, "gld" ],
+[ 5051, "gle" ],
+[ 5052, "glf" ],
+[ 5053, "glg" ],
+[ 5054, "glh" ],
+[ 5055, "gli" ],
+[ 5056, "glj" ],
+[ 5057, "glk" ],
+[ 5058, "gll" ],
+[ 5059, "glm" ],
+[ 5060, "gln" ],
+[ 5061, "glo" ],
+[ 5062, "glp" ],
+[ 5063, "glq" ],
+[ 5064, "glr" ],
+[ 5065, "gls" ],
+[ 5066, "glt" ],
+[ 5067, "glu" ],
+[ 5068, "glv" ],
+[ 5069, "glw" ],
+[ 5070, "glx" ],
+[ 5071, "gly" ],
+[ 5072, "glz" ],
+[ 5073, "gma" ],
+[ 5074, "gmb" ],
+[ 5075, "gmc" ],
+[ 5076, "gmd" ],
+[ 5077, "gme" ],
+[ 5078, "gmf" ],
+[ 5079, "gmg" ],
+[ 5080, "gmh" ],
+[ 5081, "gmi" ],
+[ 5082, "gmj" ],
+[ 5083, "gmk" ],
+[ 5084, "gml" ],
+[ 5085, "gmm" ],
+[ 5086, "gmn" ],
+[ 5087, "gmo" ],
+[ 5088, "gmp" ],
+[ 5089, "gmq" ],
+[ 5090, "gmr" ],
+[ 5091, "gms" ],
+[ 5092, "gmt" ],
+[ 5093, "gmu" ],
+[ 5094, "gmv" ],
+[ 5095, "gmw" ],
+[ 5096, "gmx" ],
+[ 5097, "gmy" ],
+[ 5098, "gmz" ],
+[ 5099, "gna" ],
+[ 5100, "gnb" ],
+[ 5101, "gnc" ],
+[ 5102, "gnd" ],
+[ 5103, "gne" ],
+[ 5104, "gnf" ],
+[ 5105, "gng" ],
+[ 5106, "gnh" ],
+[ 5107, "gni" ],
+[ 5108, "gnj" ],
+[ 5109, "gnk" ],
+[ 5110, "gnl" ],
+[ 5111, "gnm" ],
+[ 5112, "gnn" ],
+[ 5113, "gno" ],
+[ 5114, "gnp" ],
+[ 5115, "gnq" ],
+[ 5116, "gnr" ],
+[ 5117, "gns" ],
+[ 5118, "gnt" ],
+[ 5119, "gnu" ],
+[ 5120, "gnv" ],
+[ 5121, "gnw" ],
+[ 5122, "gnx" ],
+[ 5123, "gny" ],
+[ 5124, "gnz" ],
+[ 5125, "goa" ],
+[ 5126, "gob" ],
+[ 5127, "goc" ],
+[ 5128, "god" ],
+[ 5129, "goe" ],
+[ 5130, "gof" ],
+[ 5131, "gog" ],
+[ 5132, "goh" ],
+[ 5133, "goi" ],
+[ 5134, "goj" ],
+[ 5135, "gok" ],
+[ 5136, "gol" ],
+[ 5137, "gom" ],
+[ 5138, "gon" ],
+[ 5139, "goo" ],
+[ 5140, "gop" ],
+[ 5141, "goq" ],
+[ 5142, "gor" ],
+[ 5143, "gos" ],
+[ 5144, "got" ],
+[ 5145, "gou" ],
+[ 5146, "gov" ],
+[ 5147, "gow" ],
+[ 5148, "gox" ],
+[ 5149, "goy" ],
+[ 5150, "goz" ],
+[ 5151, "gpa" ],
+[ 5152, "gpb" ],
+[ 5153, "gpc" ],
+[ 5154, "gpd" ],
+[ 5155, "gpe" ],
+[ 5156, "gpf" ],
+[ 5157, "gpg" ],
+[ 5158, "gph" ],
+[ 5159, "gpi" ],
+[ 5160, "gpj" ],
+[ 5161, "gpk" ],
+[ 5162, "gpl" ],
+[ 5163, "gpm" ],
+[ 5164, "gpn" ],
+[ 5165, "gpo" ],
+[ 5166, "gpp" ],
+[ 5167, "gpq" ],
+[ 5168, "gpr" ],
+[ 5169, "gps" ],
+[ 5170, "gpt" ],
+[ 5171, "gpu" ],
+[ 5172, "gpv" ],
+[ 5173, "gpw" ],
+[ 5174, "gpx" ],
+[ 5175, "gpy" ],
+[ 5176, "gpz" ],
+[ 5177, "gqa" ],
+[ 5178, "gqb" ],
+[ 5179, "gqc" ],
+[ 5180, "gqd" ],
+[ 5181, "gqe" ],
+[ 5182, "gqf" ],
+[ 5183, "gqg" ],
+[ 5184, "gqh" ],
+[ 5185, "gqi" ],
+[ 5186, "gqj" ],
+[ 5187, "gqk" ],
+[ 5188, "gql" ],
+[ 5189, "gqm" ],
+[ 5190, "gqn" ],
+[ 5191, "gqo" ],
+[ 5192, "gqp" ],
+[ 5193, "gqq" ],
+[ 5194, "gqr" ],
+[ 5195, "gqs" ],
+[ 5196, "gqt" ],
+[ 5197, "gqu" ],
+[ 5198, "gqv" ],
+[ 5199, "gqw" ],
+[ 5200, "gqx" ],
+[ 5201, "gqy" ],
+[ 5202, "gqz" ],
+[ 5203, "gra" ],
+[ 5204, "grb" ],
+[ 5205, "grc" ],
+[ 5206, "grd" ],
+[ 5207, "gre" ],
+[ 5208, "grf" ],
+[ 5209, "grg" ],
+[ 5210, "grh" ],
+[ 5211, "gri" ],
+[ 5212, "grj" ],
+[ 5213, "grk" ],
+[ 5214, "grl" ],
+[ 5215, "grm" ],
+[ 5216, "grn" ],
+[ 5217, "gro" ],
+[ 5218, "grp" ],
+[ 5219, "grq" ],
+[ 5220, "grr" ],
+[ 5221, "grs" ],
+[ 5222, "grt" ],
+[ 5223, "gru" ],
+[ 5224, "grv" ],
+[ 5225, "grw" ],
+[ 5226, "grx" ],
+[ 5227, "gry" ],
+[ 5228, "grz" ],
+[ 5229, "gsa" ],
+[ 5230, "gsb" ],
+[ 5231, "gsc" ],
+[ 5232, "gsd" ],
+[ 5233, "gse" ],
+[ 5234, "gsf" ],
+[ 5235, "gsg" ],
+[ 5236, "gsh" ],
+[ 5237, "gsi" ],
+[ 5238, "gsj" ],
+[ 5239, "gsk" ],
+[ 5240, "gsl" ],
+[ 5241, "gsm" ],
+[ 5242, "gsn" ],
+[ 5243, "gso" ],
+[ 5244, "gsp" ],
+[ 5245, "gsq" ],
+[ 5246, "gsr" ],
+[ 5247, "gss" ],
+[ 5248, "gst" ],
+[ 5249, "gsu" ],
+[ 5250, "gsv" ],
+[ 5251, "gsw" ],
+[ 5252, "gsx" ],
+[ 5253, "gsy" ],
+[ 5254, "gsz" ],
+[ 5255, "gta" ],
+[ 5256, "gtb" ],
+[ 5257, "gtc" ],
+[ 5258, "gtd" ],
+[ 5259, "gte" ],
+[ 5260, "gtf" ],
+[ 5261, "gtg" ],
+[ 5262, "gth" ],
+[ 5263, "gti" ],
+[ 5264, "gtj" ],
+[ 5265, "gtk" ],
+[ 5266, "gtl" ],
+[ 5267, "gtm" ],
+[ 5268, "gtn" ],
+[ 5269, "gto" ],
+[ 5270, "gtp" ],
+[ 5271, "gtq" ],
+[ 5272, "gtr" ],
+[ 5273, "gts" ],
+[ 5274, "gtt" ],
+[ 5275, "gtu" ],
+[ 5276, "gtv" ],
+[ 5277, "gtw" ],
+[ 5278, "gtx" ],
+[ 5279, "gty" ],
+[ 5280, "gtz" ],
+[ 5281, "gua" ],
+[ 5282, "gub" ],
+[ 5283, "guc" ],
+[ 5284, "gud" ],
+[ 5285, "gue" ],
+[ 5286, "guf" ],
+[ 5287, "gug" ],
+[ 5288, "guh" ],
+[ 5289, "gui" ],
+[ 5290, "guj" ],
+[ 5291, "guk" ],
+[ 5292, "gul" ],
+[ 5293, "gum" ],
+[ 5294, "gun" ],
+[ 5295, "guo" ],
+[ 5296, "gup" ],
+[ 5297, "guq" ],
+[ 5298, "gur" ],
+[ 5299, "gus" ],
+[ 5300, "gut" ],
+[ 5301, "guu" ],
+[ 5302, "guv" ],
+[ 5303, "guw" ],
+[ 5304, "gux" ],
+[ 5305, "guy" ],
+[ 5306, "guz" ],
+[ 5307, "gva" ],
+[ 5308, "gvb" ],
+[ 5309, "gvc" ],
+[ 5310, "gvd" ],
+[ 5311, "gve" ],
+[ 5312, "gvf" ],
+[ 5313, "gvg" ],
+[ 5314, "gvh" ],
+[ 5315, "gvi" ],
+[ 5316, "gvj" ],
+[ 5317, "gvk" ],
+[ 5318, "gvl" ],
+[ 5319, "gvm" ],
+[ 5320, "gvn" ],
+[ 5321, "gvo" ],
+[ 5322, "gvp" ],
+[ 5323, "gvq" ],
+[ 5324, "gvr" ],
+[ 5325, "gvs" ],
+[ 5326, "gvt" ],
+[ 5327, "gvu" ],
+[ 5328, "gvv" ],
+[ 5329, "gvw" ],
+[ 5330, "gvx" ],
+[ 5331, "gvy" ],
+[ 5332, "gvz" ],
+[ 5333, "gwa" ],
+[ 5334, "gwb" ],
+[ 5335, "gwc" ],
+[ 5336, "gwd" ],
+[ 5337, "gwe" ],
+[ 5338, "gwf" ],
+[ 5339, "gwg" ],
+[ 5340, "gwh" ],
+[ 5341, "gwi" ],
+[ 5342, "gwj" ],
+[ 5343, "gwk" ],
+[ 5344, "gwl" ],
+[ 5345, "gwm" ],
+[ 5346, "gwn" ],
+[ 5347, "gwo" ],
+[ 5348, "gwp" ],
+[ 5349, "gwq" ],
+[ 5350, "gwr" ],
+[ 5351, "gws" ],
+[ 5352, "gwt" ],
+[ 5353, "gwu" ],
+[ 5354, "gwv" ],
+[ 5355, "gww" ],
+[ 5356, "gwx" ],
+[ 5357, "gwy" ],
+[ 5358, "gwz" ],
+[ 5359, "gxa" ],
+[ 5360, "gxb" ],
+[ 5361, "gxc" ],
+[ 5362, "gxd" ],
+[ 5363, "gxe" ],
+[ 5364, "gxf" ],
+[ 5365, "gxg" ],
+[ 5366, "gxh" ],
+[ 5367, "gxi" ],
+[ 5368, "gxj" ],
+[ 5369, "gxk" ],
+[ 5370, "gxl" ],
+[ 5371, "gxm" ],
+[ 5372, "gxn" ],
+[ 5373, "gxo" ],
+[ 5374, "gxp" ],
+[ 5375, "gxq" ],
+[ 5376, "gxr" ],
+[ 5377, "gxs" ],
+[ 5378, "gxt" ],
+[ 5379, "gxu" ],
+[ 5380, "gxv" ],
+[ 5381, "gxw" ],
+[ 5382, "gxx" ],
+[ 5383, "gxy" ],
+[ 5384, "gxz" ],
+[ 5385, "gya" ],
+[ 5386, "gyb" ],
+[ 5387, "gyc" ],
+[ 5388, "gyd" ],
+[ 5389, "gye" ],
+[ 5390, "gyf" ],
+[ 5391, "gyg" ],
+[ 5392, "gyh" ],
+[ 5393, "gyi" ],
+[ 5394, "gyj" ],
+[ 5395, "gyk" ],
+[ 5396, "gyl" ],
+[ 5397, "gym" ],
+[ 5398, "gyn" ],
+[ 5399, "gyo" ],
+[ 5400, "gyp" ],
+[ 5401, "gyq" ],
+[ 5402, "gyr" ],
+[ 5403, "gys" ],
+[ 5404, "gyt" ],
+[ 5405, "gyu" ],
+[ 5406, "gyv" ],
+[ 5407, "gyw" ],
+[ 5408, "gyx" ],
+[ 5409, "gyy" ],
+[ 5410, "gyz" ],
+[ 5411, "gza" ],
+[ 5412, "gzb" ],
+[ 5413, "gzc" ],
+[ 5414, "gzd" ],
+[ 5415, "gze" ],
+[ 5416, "gzf" ],
+[ 5417, "gzg" ],
+[ 5418, "gzh" ],
+[ 5419, "gzi" ],
+[ 5420, "gzj" ],
+[ 5421, "gzk" ],
+[ 5422, "gzl" ],
+[ 5423, "gzm" ],
+[ 5424, "gzn" ],
+[ 5425, "gzo" ],
+[ 5426, "gzp" ],
+[ 5427, "gzq" ],
+[ 5428, "gzr" ],
+[ 5429, "gzs" ],
+[ 5430, "gzt" ],
+[ 5431, "gzu" ],
+[ 5432, "gzv" ],
+[ 5433, "gzw" ],
+[ 5434, "gzx" ],
+[ 5435, "gzy" ],
+[ 5436, "gzz" ],
+[ 5437, "haa" ],
+[ 5438, "hab" ],
+[ 5439, "hac" ],
+[ 5440, "had" ],
+[ 5441, "hae" ],
+[ 5442, "haf" ],
+[ 5443, "hag" ],
+[ 5444, "hah" ],
+[ 5445, "hai" ],
+[ 5446, "haj" ],
+[ 5447, "hak" ],
+[ 5448, "hal" ],
+[ 5449, "ham" ],
+[ 5450, "han" ],
+[ 5451, "hao" ],
+[ 5452, "hap" ],
+[ 5453, "haq" ],
+[ 5454, "har" ],
+[ 5455, "has" ],
+[ 5456, "hat" ],
+[ 5457, "hau" ],
+[ 5458, "hav" ],
+[ 5459, "haw" ],
+[ 5460, "hax" ],
+[ 5461, "hay" ],
+[ 5462, "haz" ],
+[ 5463, "hba" ],
+[ 5464, "hbb" ],
+[ 5465, "hbc" ],
+[ 5466, "hbd" ],
+[ 5467, "hbe" ],
+[ 5468, "hbf" ],
+[ 5469, "hbg" ],
+[ 5470, "hbh" ],
+[ 5471, "hbi" ],
+[ 5472, "hbj" ],
+[ 5473, "hbk" ],
+[ 5474, "hbl" ],
+[ 5475, "hbm" ],
+[ 5476, "hbn" ],
+[ 5477, "hbo" ],
+[ 5478, "hbp" ],
+[ 5479, "hbq" ],
+[ 5480, "hbr" ],
+[ 5481, "hbs" ],
+[ 5482, "hbt" ],
+[ 5483, "hbu" ],
+[ 5484, "hbv" ],
+[ 5485, "hbw" ],
+[ 5486, "hbx" ],
+[ 5487, "hby" ],
+[ 5488, "hbz" ],
+[ 5489, "hca" ],
+[ 5490, "hcb" ],
+[ 5491, "hcc" ],
+[ 5492, "hcd" ],
+[ 5493, "hce" ],
+[ 5494, "hcf" ],
+[ 5495, "hcg" ],
+[ 5496, "hch" ],
+[ 5497, "hci" ],
+[ 5498, "hcj" ],
+[ 5499, "hck" ],
+[ 5500, "hcl" ],
+[ 5501, "hcm" ],
+[ 5502, "hcn" ],
+[ 5503, "hco" ],
+[ 5504, "hcp" ],
+[ 5505, "hcq" ],
+[ 5506, "hcr" ],
+[ 5507, "hcs" ],
+[ 5508, "hct" ],
+[ 5509, "hcu" ],
+[ 5510, "hcv" ],
+[ 5511, "hcw" ],
+[ 5512, "hcx" ],
+[ 5513, "hcy" ],
+[ 5514, "hcz" ],
+[ 5515, "hda" ],
+[ 5516, "hdb" ],
+[ 5517, "hdc" ],
+[ 5518, "hdd" ],
+[ 5519, "hde" ],
+[ 5520, "hdf" ],
+[ 5521, "hdg" ],
+[ 5522, "hdh" ],
+[ 5523, "hdi" ],
+[ 5524, "hdj" ],
+[ 5525, "hdk" ],
+[ 5526, "hdl" ],
+[ 5527, "hdm" ],
+[ 5528, "hdn" ],
+[ 5529, "hdo" ],
+[ 5530, "hdp" ],
+[ 5531, "hdq" ],
+[ 5532, "hdr" ],
+[ 5533, "hds" ],
+[ 5534, "hdt" ],
+[ 5535, "hdu" ],
+[ 5536, "hdv" ],
+[ 5537, "hdw" ],
+[ 5538, "hdx" ],
+[ 5539, "hdy" ],
+[ 5540, "hdz" ],
+[ 5541, "hea" ],
+[ 5542, "heb" ],
+[ 5543, "hec" ],
+[ 5544, "hed" ],
+[ 5545, "hee" ],
+[ 5546, "hef" ],
+[ 5547, "heg" ],
+[ 5548, "heh" ],
+[ 5549, "hei" ],
+[ 5550, "hej" ],
+[ 5551, "hek" ],
+[ 5552, "hel" ],
+[ 5553, "hem" ],
+[ 5554, "hen" ],
+[ 5555, "heo" ],
+[ 5556, "hep" ],
+[ 5557, "heq" ],
+[ 5558, "her" ],
+[ 5559, "hes" ],
+[ 5560, "het" ],
+[ 5561, "heu" ],
+[ 5562, "hev" ],
+[ 5563, "hew" ],
+[ 5564, "hex" ],
+[ 5565, "hey" ],
+[ 5566, "hez" ],
+[ 5567, "hfa" ],
+[ 5568, "hfb" ],
+[ 5569, "hfc" ],
+[ 5570, "hfd" ],
+[ 5571, "hfe" ],
+[ 5572, "hff" ],
+[ 5573, "hfg" ],
+[ 5574, "hfh" ],
+[ 5575, "hfi" ],
+[ 5576, "hfj" ],
+[ 5577, "hfk" ],
+[ 5578, "hfl" ],
+[ 5579, "hfm" ],
+[ 5580, "hfn" ],
+[ 5581, "hfo" ],
+[ 5582, "hfp" ],
+[ 5583, "hfq" ],
+[ 5584, "hfr" ],
+[ 5585, "hfs" ],
+[ 5586, "hft" ],
+[ 5587, "hfu" ],
+[ 5588, "hfv" ],
+[ 5589, "hfw" ],
+[ 5590, "hfx" ],
+[ 5591, "hfy" ],
+[ 5592, "hfz" ],
+[ 5593, "hga" ],
+[ 5594, "hgb" ],
+[ 5595, "hgc" ],
+[ 5596, "hgd" ],
+[ 5597, "hge" ],
+[ 5598, "hgf" ],
+[ 5599, "hgg" ],
+[ 5600, "hgh" ],
+[ 5601, "hgi" ],
+[ 5602, "hgj" ],
+[ 5603, "hgk" ],
+[ 5604, "hgl" ],
+[ 5605, "hgm" ],
+[ 5606, "hgn" ],
+[ 5607, "hgo" ],
+[ 5608, "hgp" ],
+[ 5609, "hgq" ],
+[ 5610, "hgr" ],
+[ 5611, "hgs" ],
+[ 5612, "hgt" ],
+[ 5613, "hgu" ],
+[ 5614, "hgv" ],
+[ 5615, "hgw" ],
+[ 5616, "hgx" ],
+[ 5617, "hgy" ],
+[ 5618, "hgz" ],
+[ 5619, "hha" ],
+[ 5620, "hhb" ],
+[ 5621, "hhc" ],
+[ 5622, "hhd" ],
+[ 5623, "hhe" ],
+[ 5624, "hhf" ],
+[ 5625, "hhg" ],
+[ 5626, "hhh" ],
+[ 5627, "hhi" ],
+[ 5628, "hhj" ],
+[ 5629, "hhk" ],
+[ 5630, "hhl" ],
+[ 5631, "hhm" ],
+[ 5632, "hhn" ],
+[ 5633, "hho" ],
+[ 5634, "hhp" ],
+[ 5635, "hhq" ],
+[ 5636, "hhr" ],
+[ 5637, "hhs" ],
+[ 5638, "hht" ],
+[ 5639, "hhu" ],
+[ 5640, "hhv" ],
+[ 5641, "hhw" ],
+[ 5642, "hhx" ],
+[ 5643, "hhy" ],
+[ 5644, "hhz" ],
+[ 5645, "hia" ],
+[ 5646, "hib" ],
+[ 5647, "hic" ],
+[ 5648, "hid" ],
+[ 5649, "hie" ],
+[ 5650, "hif" ],
+[ 5651, "hig" ],
+[ 5652, "hih" ],
+[ 5653, "hii" ],
+[ 5654, "hij" ],
+[ 5655, "hik" ],
+[ 5656, "hil" ],
+[ 5657, "him" ],
+[ 5658, "hin" ],
+[ 5659, "hio" ],
+[ 5660, "hip" ],
+[ 5661, "hiq" ],
+[ 5662, "hir" ],
+[ 5663, "his" ],
+[ 5664, "hit" ],
+[ 5665, "hiu" ],
+[ 5666, "hiv" ],
+[ 5667, "hiw" ],
+[ 5668, "hix" ],
+[ 5669, "hiy" ],
+[ 5670, "hiz" ],
+[ 5671, "hja" ],
+[ 5672, "hjb" ],
+[ 5673, "hjc" ],
+[ 5674, "hjd" ],
+[ 5675, "hje" ],
+[ 5676, "hjf" ],
+[ 5677, "hjg" ],
+[ 5678, "hjh" ],
+[ 5679, "hji" ],
+[ 5680, "hjj" ],
+[ 5681, "hjk" ],
+[ 5682, "hjl" ],
+[ 5683, "hjm" ],
+[ 5684, "hjn" ],
+[ 5685, "hjo" ],
+[ 5686, "hjp" ],
+[ 5687, "hjq" ],
+[ 5688, "hjr" ],
+[ 5689, "hjs" ],
+[ 5690, "hjt" ],
+[ 5691, "hju" ],
+[ 5692, "hjv" ],
+[ 5693, "hjw" ],
+[ 5694, "hjx" ],
+[ 5695, "hjy" ],
+[ 5696, "hjz" ],
+[ 5697, "hka" ],
+[ 5698, "hkb" ],
+[ 5699, "hkc" ],
+[ 5700, "hkd" ],
+[ 5701, "hke" ],
+[ 5702, "hkf" ],
+[ 5703, "hkg" ],
+[ 5704, "hkh" ],
+[ 5705, "hki" ],
+[ 5706, "hkj" ],
+[ 5707, "hkk" ],
+[ 5708, "hkl" ],
+[ 5709, "hkm" ],
+[ 5710, "hkn" ],
+[ 5711, "hko" ],
+[ 5712, "hkp" ],
+[ 5713, "hkq" ],
+[ 5714, "hkr" ],
+[ 5715, "hks" ],
+[ 5716, "hkt" ],
+[ 5717, "hku" ],
+[ 5718, "hkv" ],
+[ 5719, "hkw" ],
+[ 5720, "hkx" ],
+[ 5721, "hky" ],
+[ 5722, "hkz" ],
+[ 5723, "hla" ],
+[ 5724, "hlb" ],
+[ 5725, "hlc" ],
+[ 5726, "hld" ],
+[ 5727, "hle" ],
+[ 5728, "hlf" ],
+[ 5729, "hlg" ],
+[ 5730, "hlh" ],
+[ 5731, "hli" ],
+[ 5732, "hlj" ],
+[ 5733, "hlk" ],
+[ 5734, "hll" ],
+[ 5735, "hlm" ],
+[ 5736, "hln" ],
+[ 5737, "hlo" ],
+[ 5738, "hlp" ],
+[ 5739, "hlq" ],
+[ 5740, "hlr" ],
+[ 5741, "hls" ],
+[ 5742, "hlt" ],
+[ 5743, "hlu" ],
+[ 5744, "hlv" ],
+[ 5745, "hlw" ],
+[ 5746, "hlx" ],
+[ 5747, "hly" ],
+[ 5748, "hlz" ],
+[ 5749, "hma" ],
+[ 5750, "hmb" ],
+[ 5751, "hmc" ],
+[ 5752, "hmd" ],
+[ 5753, "hme" ],
+[ 5754, "hmf" ],
+[ 5755, "hmg" ],
+[ 5756, "hmh" ],
+[ 5757, "hmi" ],
+[ 5758, "hmj" ],
+[ 5759, "hmk" ],
+[ 5760, "hml" ],
+[ 5761, "hmm" ],
+[ 5762, "hmn" ],
+[ 5763, "hmo" ],
+[ 5764, "hmp" ],
+[ 5765, "hmq" ],
+[ 5766, "hmr" ],
+[ 5767, "hms" ],
+[ 5768, "hmt" ],
+[ 5769, "hmu" ],
+[ 5770, "hmv" ],
+[ 5771, "hmw" ],
+[ 5772, "hmx" ],
+[ 5773, "hmy" ],
+[ 5774, "hmz" ],
+[ 5775, "hna" ],
+[ 5776, "hnb" ],
+[ 5777, "hnc" ],
+[ 5778, "hnd" ],
+[ 5779, "hne" ],
+[ 5780, "hnf" ],
+[ 5781, "hng" ],
+[ 5782, "hnh" ],
+[ 5783, "hni" ],
+[ 5784, "hnj" ],
+[ 5785, "hnk" ],
+[ 5786, "hnl" ],
+[ 5787, "hnm" ],
+[ 5788, "hnn" ],
+[ 5789, "hno" ],
+[ 5790, "hnp" ],
+[ 5791, "hnq" ],
+[ 5792, "hnr" ],
+[ 5793, "hns" ],
+[ 5794, "hnt" ],
+[ 5795, "hnu" ],
+[ 5796, "hnv" ],
+[ 5797, "hnw" ],
+[ 5798, "hnx" ],
+[ 5799, "hny" ],
+[ 5800, "hnz" ],
+[ 5801, "hoa" ],
+[ 5802, "hob" ],
+[ 5803, "hoc" ],
+[ 5804, "hod" ],
+[ 5805, "hoe" ],
+[ 5806, "hof" ],
+[ 5807, "hog" ],
+[ 5808, "hoh" ],
+[ 5809, "hoi" ],
+[ 5810, "hoj" ],
+[ 5811, "hok" ],
+[ 5812, "hol" ],
+[ 5813, "hom" ],
+[ 5814, "hon" ],
+[ 5815, "hoo" ],
+[ 5816, "hop" ],
+[ 5817, "hoq" ],
+[ 5818, "hor" ],
+[ 5819, "hos" ],
+[ 5820, "hot" ],
+[ 5821, "hou" ],
+[ 5822, "hov" ],
+[ 5823, "how" ],
+[ 5824, "hox" ],
+[ 5825, "hoy" ],
+[ 5826, "hoz" ],
+[ 5827, "hpa" ],
+[ 5828, "hpb" ],
+[ 5829, "hpc" ],
+[ 5830, "hpd" ],
+[ 5831, "hpe" ],
+[ 5832, "hpf" ],
+[ 5833, "hpg" ],
+[ 5834, "hph" ],
+[ 5835, "hpi" ],
+[ 5836, "hpj" ],
+[ 5837, "hpk" ],
+[ 5838, "hpl" ],
+[ 5839, "hpm" ],
+[ 5840, "hpn" ],
+[ 5841, "hpo" ],
+[ 5842, "hpp" ],
+[ 5843, "hpq" ],
+[ 5844, "hpr" ],
+[ 5845, "hps" ],
+[ 5846, "hpt" ],
+[ 5847, "hpu" ],
+[ 5848, "hpv" ],
+[ 5849, "hpw" ],
+[ 5850, "hpx" ],
+[ 5851, "hpy" ],
+[ 5852, "hpz" ],
+[ 5853, "hqa" ],
+[ 5854, "hqb" ],
+[ 5855, "hqc" ],
+[ 5856, "hqd" ],
+[ 5857, "hqe" ],
+[ 5858, "hqf" ],
+[ 5859, "hqg" ],
+[ 5860, "hqh" ],
+[ 5861, "hqi" ],
+[ 5862, "hqj" ],
+[ 5863, "hqk" ],
+[ 5864, "hql" ],
+[ 5865, "hqm" ],
+[ 5866, "hqn" ],
+[ 5867, "hqo" ],
+[ 5868, "hqp" ],
+[ 5869, "hqq" ],
+[ 5870, "hqr" ],
+[ 5871, "hqs" ],
+[ 5872, "hqt" ],
+[ 5873, "hqu" ],
+[ 5874, "hqv" ],
+[ 5875, "hqw" ],
+[ 5876, "hqx" ],
+[ 5877, "hqy" ],
+[ 5878, "hqz" ],
+[ 5879, "hra" ],
+[ 5880, "hrb" ],
+[ 5881, "hrc" ],
+[ 5882, "hrd" ],
+[ 5883, "hre" ],
+[ 5884, "hrf" ],
+[ 5885, "hrg" ],
+[ 5886, "hrh" ],
+[ 5887, "hri" ],
+[ 5888, "hrj" ],
+[ 5889, "hrk" ],
+[ 5890, "hrl" ],
+[ 5891, "hrm" ],
+[ 5892, "hrn" ],
+[ 5893, "hro" ],
+[ 5894, "hrp" ],
+[ 5895, "hrq" ],
+[ 5896, "hrr" ],
+[ 5897, "hrs" ],
+[ 5898, "hrt" ],
+[ 5899, "hru" ],
+[ 5900, "hrv" ],
+[ 5901, "hrw" ],
+[ 5902, "hrx" ],
+[ 5903, "hry" ],
+[ 5904, "hrz" ],
+[ 5905, "hsa" ],
+[ 5906, "hsb" ],
+[ 5907, "hsc" ],
+[ 5908, "hsd" ],
+[ 5909, "hse" ],
+[ 5910, "hsf" ],
+[ 5911, "hsg" ],
+[ 5912, "hsh" ],
+[ 5913, "hsi" ],
+[ 5914, "hsj" ],
+[ 5915, "hsk" ],
+[ 5916, "hsl" ],
+[ 5917, "hsm" ],
+[ 5918, "hsn" ],
+[ 5919, "hso" ],
+[ 5920, "hsp" ],
+[ 5921, "hsq" ],
+[ 5922, "hsr" ],
+[ 5923, "hss" ],
+[ 5924, "hst" ],
+[ 5925, "hsu" ],
+[ 5926, "hsv" ],
+[ 5927, "hsw" ],
+[ 5928, "hsx" ],
+[ 5929, "hsy" ],
+[ 5930, "hsz" ],
+[ 5931, "hta" ],
+[ 5932, "htb" ],
+[ 5933, "htc" ],
+[ 5934, "htd" ],
+[ 5935, "hte" ],
+[ 5936, "htf" ],
+[ 5937, "htg" ],
+[ 5938, "hth" ],
+[ 5939, "hti" ],
+[ 5940, "htj" ],
+[ 5941, "htk" ],
+[ 5942, "htl" ],
+[ 5943, "htm" ],
+[ 5944, "htn" ],
+[ 5945, "hto" ],
+[ 5946, "htp" ],
+[ 5947, "htq" ],
+[ 5948, "htr" ],
+[ 5949, "hts" ],
+[ 5950, "htt" ],
+[ 5951, "htu" ],
+[ 5952, "htv" ],
+[ 5953, "htw" ],
+[ 5954, "htx" ],
+[ 5955, "hty" ],
+[ 5956, "htz" ],
+[ 5957, "hua" ],
+[ 5958, "hub" ],
+[ 5959, "huc" ],
+[ 5960, "hud" ],
+[ 5961, "hue" ],
+[ 5962, "huf" ],
+[ 5963, "hug" ],
+[ 5964, "huh" ],
+[ 5965, "hui" ],
+[ 5966, "huj" ],
+[ 5967, "huk" ],
+[ 5968, "hul" ],
+[ 5969, "hum" ],
+[ 5970, "hun" ],
+[ 5971, "huo" ],
+[ 5972, "hup" ],
+[ 5973, "huq" ],
+[ 5974, "hur" ],
+[ 5975, "hus" ],
+[ 5976, "hut" ],
+[ 5977, "huu" ],
+[ 5978, "huv" ],
+[ 5979, "huw" ],
+[ 5980, "hux" ],
+[ 5981, "huy" ],
+[ 5982, "huz" ],
+[ 5983, "hva" ],
+[ 5984, "hvb" ],
+[ 5985, "hvc" ],
+[ 5986, "hvd" ],
+[ 5987, "hve" ],
+[ 5988, "hvf" ],
+[ 5989, "hvg" ],
+[ 5990, "hvh" ],
+[ 5991, "hvi" ],
+[ 5992, "hvj" ],
+[ 5993, "hvk" ],
+[ 5994, "hvl" ],
+[ 5995, "hvm" ],
+[ 5996, "hvn" ],
+[ 5997, "hvo" ],
+[ 5998, "hvp" ],
+[ 5999, "hvq" ],
+[ 6000, "hvr" ],
+[ 6001, "hvs" ],
+[ 6002, "hvt" ],
+[ 6003, "hvu" ],
+[ 6004, "hvv" ],
+[ 6005, "hvw" ],
+[ 6006, "hvx" ],
+[ 6007, "hvy" ],
+[ 6008, "hvz" ],
+[ 6009, "hwa" ],
+[ 6010, "hwb" ],
+[ 6011, "hwc" ],
+[ 6012, "hwd" ],
+[ 6013, "hwe" ],
+[ 6014, "hwf" ],
+[ 6015, "hwg" ],
+[ 6016, "hwh" ],
+[ 6017, "hwi" ],
+[ 6018, "hwj" ],
+[ 6019, "hwk" ],
+[ 6020, "hwl" ],
+[ 6021, "hwm" ],
+[ 6022, "hwn" ],
+[ 6023, "hwo" ],
+[ 6024, "hwp" ],
+[ 6025, "hwq" ],
+[ 6026, "hwr" ],
+[ 6027, "hws" ],
+[ 6028, "hwt" ],
+[ 6029, "hwu" ],
+[ 6030, "hwv" ],
+[ 6031, "hww" ],
+[ 6032, "hwx" ],
+[ 6033, "hwy" ],
+[ 6034, "hwz" ],
+[ 6035, "hxa" ],
+[ 6036, "hxb" ],
+[ 6037, "hxc" ],
+[ 6038, "hxd" ],
+[ 6039, "hxe" ],
+[ 6040, "hxf" ],
+[ 6041, "hxg" ],
+[ 6042, "hxh" ],
+[ 6043, "hxi" ],
+[ 6044, "hxj" ],
+[ 6045, "hxk" ],
+[ 6046, "hxl" ],
+[ 6047, "hxm" ],
+[ 6048, "hxn" ],
+[ 6049, "hxo" ],
+[ 6050, "hxp" ],
+[ 6051, "hxq" ],
+[ 6052, "hxr" ],
+[ 6053, "hxs" ],
+[ 6054, "hxt" ],
+[ 6055, "hxu" ],
+[ 6056, "hxv" ],
+[ 6057, "hxw" ],
+[ 6058, "hxx" ],
+[ 6059, "hxy" ],
+[ 6060, "hxz" ],
+[ 6061, "hya" ],
+[ 6062, "hyb" ],
+[ 6063, "hyc" ],
+[ 6064, "hyd" ],
+[ 6065, "hye" ],
+[ 6066, "hyf" ],
+[ 6067, "hyg" ],
+[ 6068, "hyh" ],
+[ 6069, "hyi" ],
+[ 6070, "hyj" ],
+[ 6071, "hyk" ],
+[ 6072, "hyl" ],
+[ 6073, "hym" ],
+[ 6074, "hyn" ],
+[ 6075, "hyo" ],
+[ 6076, "hyp" ],
+[ 6077, "hyq" ],
+[ 6078, "hyr" ],
+[ 6079, "hys" ],
+[ 6080, "hyt" ],
+[ 6081, "hyu" ],
+[ 6082, "hyv" ],
+[ 6083, "hyw" ],
+[ 6084, "hyx" ],
+[ 6085, "hyy" ],
+[ 6086, "hyz" ],
+[ 6087, "hza" ],
+[ 6088, "hzb" ],
+[ 6089, "hzc" ],
+[ 6090, "hzd" ],
+[ 6091, "hze" ],
+[ 6092, "hzf" ],
+[ 6093, "hzg" ],
+[ 6094, "hzh" ],
+[ 6095, "hzi" ],
+[ 6096, "hzj" ],
+[ 6097, "hzk" ],
+[ 6098, "hzl" ],
+[ 6099, "hzm" ],
+[ 6100, "hzn" ],
+[ 6101, "hzo" ],
+[ 6102, "hzp" ],
+[ 6103, "hzq" ],
+[ 6104, "hzr" ],
+[ 6105, "hzs" ],
+[ 6106, "hzt" ],
+[ 6107, "hzu" ],
+[ 6108, "hzv" ],
+[ 6109, "hzw" ],
+[ 6110, "hzx" ],
+[ 6111, "hzy" ],
+[ 6112, "hzz" ],
+[ 6113, "iaa" ],
+[ 6114, "iab" ],
+[ 6115, "iac" ],
+[ 6116, "iad" ],
+[ 6117, "iae" ],
+[ 6118, "iaf" ],
+[ 6119, "iag" ],
+[ 6120, "iah" ],
+[ 6121, "iai" ],
+[ 6122, "iaj" ],
+[ 6123, "iak" ],
+[ 6124, "ial" ],
+[ 6125, "iam" ],
+[ 6126, "ian" ],
+[ 6127, "iao" ],
+[ 6128, "iap" ],
+[ 6129, "iaq" ],
+[ 6130, "iar" ],
+[ 6131, "ias" ],
+[ 6132, "iat" ],
+[ 6133, "iau" ],
+[ 6134, "iav" ],
+[ 6135, "iaw" ],
+[ 6136, "iax" ],
+[ 6137, "iay" ],
+[ 6138, "iaz" ],
+[ 6139, "iba" ],
+[ 6140, "ibb" ],
+[ 6141, "ibc" ],
+[ 6142, "ibd" ],
+[ 6143, "ibe" ],
+[ 6144, "ibf" ],
+[ 6145, "ibg" ],
+[ 6146, "ibh" ],
+[ 6147, "ibi" ],
+[ 6148, "ibj" ],
+[ 6149, "ibk" ],
+[ 6150, "ibl" ],
+[ 6151, "ibm" ],
+[ 6152, "ibn" ],
+[ 6153, "ibo" ],
+[ 6154, "ibp" ],
+[ 6155, "ibq" ],
+[ 6156, "ibr" ],
+[ 6157, "ibs" ],
+[ 6158, "ibt" ],
+[ 6159, "ibu" ],
+[ 6160, "ibv" ],
+[ 6161, "ibw" ],
+[ 6162, "ibx" ],
+[ 6163, "iby" ],
+[ 6164, "ibz" ],
+[ 6165, "ica" ],
+[ 6166, "icb" ],
+[ 6167, "icc" ],
+[ 6168, "icd" ],
+[ 6169, "ice" ],
+[ 6170, "icf" ],
+[ 6171, "icg" ],
+[ 6172, "ich" ],
+[ 6173, "ici" ],
+[ 6174, "icj" ],
+[ 6175, "ick" ],
+[ 6176, "icl" ],
+[ 6177, "icm" ],
+[ 6178, "icn" ],
+[ 6179, "ico" ],
+[ 6180, "icp" ],
+[ 6181, "icq" ],
+[ 6182, "icr" ],
+[ 6183, "ics" ],
+[ 6184, "ict" ],
+[ 6185, "icu" ],
+[ 6186, "icv" ],
+[ 6187, "icw" ],
+[ 6188, "icx" ],
+[ 6189, "icy" ],
+[ 6190, "icz" ],
+[ 6191, "ida" ],
+[ 6192, "idb" ],
+[ 6193, "idc" ],
+[ 6194, "idd" ],
+[ 6195, "ide" ],
+[ 6196, "idf" ],
+[ 6197, "idg" ],
+[ 6198, "idh" ],
+[ 6199, "idi" ],
+[ 6200, "idj" ],
+[ 6201, "idk" ],
+[ 6202, "idl" ],
+[ 6203, "idm" ],
+[ 6204, "idn" ],
+[ 6205, "ido" ],
+[ 6206, "idp" ],
+[ 6207, "idq" ],
+[ 6208, "idr" ],
+[ 6209, "ids" ],
+[ 6210, "idt" ],
+[ 6211, "idu" ],
+[ 6212, "idv" ],
+[ 6213, "idw" ],
+[ 6214, "idx" ],
+[ 6215, "idy" ],
+[ 6216, "idz" ],
+[ 6217, "iea" ],
+[ 6218, "ieb" ],
+[ 6219, "iec" ],
+[ 6220, "ied" ],
+[ 6221, "iee" ],
+[ 6222, "ief" ],
+[ 6223, "ieg" ],
+[ 6224, "ieh" ],
+[ 6225, "iei" ],
+[ 6226, "iej" ],
+[ 6227, "iek" ],
+[ 6228, "iel" ],
+[ 6229, "iem" ],
+[ 6230, "ien" ],
+[ 6231, "ieo" ],
+[ 6232, "iep" ],
+[ 6233, "ieq" ],
+[ 6234, "ier" ],
+[ 6235, "ies" ],
+[ 6236, "iet" ],
+[ 6237, "ieu" ],
+[ 6238, "iev" ],
+[ 6239, "iew" ],
+[ 6240, "iex" ],
+[ 6241, "iey" ],
+[ 6242, "iez" ],
+[ 6243, "ifa" ],
+[ 6244, "ifb" ],
+[ 6245, "ifc" ],
+[ 6246, "ifd" ],
+[ 6247, "ife" ],
+[ 6248, "iff" ],
+[ 6249, "ifg" ],
+[ 6250, "ifh" ],
+[ 6251, "ifi" ],
+[ 6252, "ifj" ],
+[ 6253, "ifk" ],
+[ 6254, "ifl" ],
+[ 6255, "ifm" ],
+[ 6256, "ifn" ],
+[ 6257, "ifo" ],
+[ 6258, "ifp" ],
+[ 6259, "ifq" ],
+[ 6260, "ifr" ],
+[ 6261, "ifs" ],
+[ 6262, "ift" ],
+[ 6263, "ifu" ],
+[ 6264, "ifv" ],
+[ 6265, "ifw" ],
+[ 6266, "ifx" ],
+[ 6267, "ify" ],
+[ 6268, "ifz" ],
+[ 6269, "iga" ],
+[ 6270, "igb" ],
+[ 6271, "igc" ],
+[ 6272, "igd" ],
+[ 6273, "ige" ],
+[ 6274, "igf" ],
+[ 6275, "igg" ],
+[ 6276, "igh" ],
+[ 6277, "igi" ],
+[ 6278, "igj" ],
+[ 6279, "igk" ],
+[ 6280, "igl" ],
+[ 6281, "igm" ],
+[ 6282, "ign" ],
+[ 6283, "igo" ],
+[ 6284, "igp" ],
+[ 6285, "igq" ],
+[ 6286, "igr" ],
+[ 6287, "igs" ],
+[ 6288, "igt" ],
+[ 6289, "igu" ],
+[ 6290, "igv" ],
+[ 6291, "igw" ],
+[ 6292, "igx" ],
+[ 6293, "igy" ],
+[ 6294, "igz" ],
+[ 6295, "iha" ],
+[ 6296, "ihb" ],
+[ 6297, "ihc" ],
+[ 6298, "ihd" ],
+[ 6299, "ihe" ],
+[ 6300, "ihf" ],
+[ 6301, "ihg" ],
+[ 6302, "ihh" ],
+[ 6303, "ihi" ],
+[ 6304, "ihj" ],
+[ 6305, "ihk" ],
+[ 6306, "ihl" ],
+[ 6307, "ihm" ],
+[ 6308, "ihn" ],
+[ 6309, "iho" ],
+[ 6310, "ihp" ],
+[ 6311, "ihq" ],
+[ 6312, "ihr" ],
+[ 6313, "ihs" ],
+[ 6314, "iht" ],
+[ 6315, "ihu" ],
+[ 6316, "ihv" ],
+[ 6317, "ihw" ],
+[ 6318, "ihx" ],
+[ 6319, "ihy" ],
+[ 6320, "ihz" ],
+[ 6321, "iia" ],
+[ 6322, "iib" ],
+[ 6323, "iic" ],
+[ 6324, "iid" ],
+[ 6325, "iie" ],
+[ 6326, "iif" ],
+[ 6327, "iig" ],
+[ 6328, "iih" ],
+[ 6329, "iii" ],
+[ 6330, "iij" ],
+[ 6331, "iik" ],
+[ 6332, "iil" ],
+[ 6333, "iim" ],
+[ 6334, "iin" ],
+[ 6335, "iio" ],
+[ 6336, "iip" ],
+[ 6337, "iiq" ],
+[ 6338, "iir" ],
+[ 6339, "iis" ],
+[ 6340, "iit" ],
+[ 6341, "iiu" ],
+[ 6342, "iiv" ],
+[ 6343, "iiw" ],
+[ 6344, "iix" ],
+[ 6345, "iiy" ],
+[ 6346, "iiz" ],
+[ 6347, "ija" ],
+[ 6348, "ijb" ],
+[ 6349, "ijc" ],
+[ 6350, "ijd" ],
+[ 6351, "ije" ],
+[ 6352, "ijf" ],
+[ 6353, "ijg" ],
+[ 6354, "ijh" ],
+[ 6355, "iji" ],
+[ 6356, "ijj" ],
+[ 6357, "ijk" ],
+[ 6358, "ijl" ],
+[ 6359, "ijm" ],
+[ 6360, "ijn" ],
+[ 6361, "ijo" ],
+[ 6362, "ijp" ],
+[ 6363, "ijq" ],
+[ 6364, "ijr" ],
+[ 6365, "ijs" ],
+[ 6366, "ijt" ],
+[ 6367, "iju" ],
+[ 6368, "ijv" ],
+[ 6369, "ijw" ],
+[ 6370, "ijx" ],
+[ 6371, "ijy" ],
+[ 6372, "ijz" ],
+[ 6373, "ika" ],
+[ 6374, "ikb" ],
+[ 6375, "ikc" ],
+[ 6376, "ikd" ],
+[ 6377, "ike" ],
+[ 6378, "ikf" ],
+[ 6379, "ikg" ],
+[ 6380, "ikh" ],
+[ 6381, "iki" ],
+[ 6382, "ikj" ],
+[ 6383, "ikk" ],
+[ 6384, "ikl" ],
+[ 6385, "ikm" ],
+[ 6386, "ikn" ],
+[ 6387, "iko" ],
+[ 6388, "ikp" ],
+[ 6389, "ikq" ],
+[ 6390, "ikr" ],
+[ 6391, "iks" ],
+[ 6392, "ikt" ],
+[ 6393, "iku" ],
+[ 6394, "ikv" ],
+[ 6395, "ikw" ],
+[ 6396, "ikx" ],
+[ 6397, "iky" ],
+[ 6398, "ikz" ],
+[ 6399, "ila" ],
+[ 6400, "ilb" ],
+[ 6401, "ilc" ],
+[ 6402, "ild" ],
+[ 6403, "ile" ],
+[ 6404, "ilf" ],
+[ 6405, "ilg" ],
+[ 6406, "ilh" ],
+[ 6407, "ili" ],
+[ 6408, "ilj" ],
+[ 6409, "ilk" ],
+[ 6410, "ill" ],
+[ 6411, "ilm" ],
+[ 6412, "iln" ],
+[ 6413, "ilo" ],
+[ 6414, "ilp" ],
+[ 6415, "ilq" ],
+[ 6416, "ilr" ],
+[ 6417, "ils" ],
+[ 6418, "ilt" ],
+[ 6419, "ilu" ],
+[ 6420, "ilv" ],
+[ 6421, "ilw" ],
+[ 6422, "ilx" ],
+[ 6423, "ily" ],
+[ 6424, "ilz" ],
+[ 6425, "ima" ],
+[ 6426, "imb" ],
+[ 6427, "imc" ],
+[ 6428, "imd" ],
+[ 6429, "ime" ],
+[ 6430, "imf" ],
+[ 6431, "img" ],
+[ 6432, "imh" ],
+[ 6433, "imi" ],
+[ 6434, "imj" ],
+[ 6435, "imk" ],
+[ 6436, "iml" ],
+[ 6437, "imm" ],
+[ 6438, "imn" ],
+[ 6439, "imo" ],
+[ 6440, "imp" ],
+[ 6441, "imq" ],
+[ 6442, "imr" ],
+[ 6443, "ims" ],
+[ 6444, "imt" ],
+[ 6445, "imu" ],
+[ 6446, "imv" ],
+[ 6447, "imw" ],
+[ 6448, "imx" ],
+[ 6449, "imy" ],
+[ 6450, "imz" ],
+[ 6451, "ina" ],
+[ 6452, "inb" ],
+[ 6453, "inc" ],
+[ 6454, "ind" ],
+[ 6455, "ine" ],
+[ 6456, "inf" ],
+[ 6457, "ing" ],
+[ 6458, "inh" ],
+[ 6459, "ini" ],
+[ 6460, "inj" ],
+[ 6461, "ink" ],
+[ 6462, "inl" ],
+[ 6463, "inm" ],
+[ 6464, "inn" ],
+[ 6465, "ino" ],
+[ 6466, "inp" ],
+[ 6467, "inq" ],
+[ 6468, "inr" ],
+[ 6469, "ins" ],
+[ 6470, "int" ],
+[ 6471, "inu" ],
+[ 6472, "inv" ],
+[ 6473, "inw" ],
+[ 6474, "inx" ],
+[ 6475, "iny" ],
+[ 6476, "inz" ],
+[ 6477, "ioa" ],
+[ 6478, "iob" ],
+[ 6479, "ioc" ],
+[ 6480, "iod" ],
+[ 6481, "ioe" ],
+[ 6482, "iof" ],
+[ 6483, "iog" ],
+[ 6484, "ioh" ],
+[ 6485, "ioi" ],
+[ 6486, "ioj" ],
+[ 6487, "iok" ],
+[ 6488, "iol" ],
+[ 6489, "iom" ],
+[ 6490, "ion" ],
+[ 6491, "ioo" ],
+[ 6492, "iop" ],
+[ 6493, "ioq" ],
+[ 6494, "ior" ],
+[ 6495, "ios" ],
+[ 6496, "iot" ],
+[ 6497, "iou" ],
+[ 6498, "iov" ],
+[ 6499, "iow" ],
+[ 6500, "iox" ],
+[ 6501, "ioy" ],
+[ 6502, "ioz" ],
+[ 6503, "ipa" ],
+[ 6504, "ipb" ],
+[ 6505, "ipc" ],
+[ 6506, "ipd" ],
+[ 6507, "ipe" ],
+[ 6508, "ipf" ],
+[ 6509, "ipg" ],
+[ 6510, "iph" ],
+[ 6511, "ipi" ],
+[ 6512, "ipj" ],
+[ 6513, "ipk" ],
+[ 6514, "ipl" ],
+[ 6515, "ipm" ],
+[ 6516, "ipn" ],
+[ 6517, "ipo" ],
+[ 6518, "ipp" ],
+[ 6519, "ipq" ],
+[ 6520, "ipr" ],
+[ 6521, "ips" ],
+[ 6522, "ipt" ],
+[ 6523, "ipu" ],
+[ 6524, "ipv" ],
+[ 6525, "ipw" ],
+[ 6526, "ipx" ],
+[ 6527, "ipy" ],
+[ 6528, "ipz" ],
+[ 6529, "iqa" ],
+[ 6530, "iqb" ],
+[ 6531, "iqc" ],
+[ 6532, "iqd" ],
+[ 6533, "iqe" ],
+[ 6534, "iqf" ],
+[ 6535, "iqg" ],
+[ 6536, "iqh" ],
+[ 6537, "iqi" ],
+[ 6538, "iqj" ],
+[ 6539, "iqk" ],
+[ 6540, "iql" ],
+[ 6541, "iqm" ],
+[ 6542, "iqn" ],
+[ 6543, "iqo" ],
+[ 6544, "iqp" ],
+[ 6545, "iqq" ],
+[ 6546, "iqr" ],
+[ 6547, "iqs" ],
+[ 6548, "iqt" ],
+[ 6549, "iqu" ],
+[ 6550, "iqv" ],
+[ 6551, "iqw" ],
+[ 6552, "iqx" ],
+[ 6553, "iqy" ],
+[ 6554, "iqz" ],
+[ 6555, "ira" ],
+[ 6556, "irb" ],
+[ 6557, "irc" ],
+[ 6558, "ird" ],
+[ 6559, "ire" ],
+[ 6560, "irf" ],
+[ 6561, "irg" ],
+[ 6562, "irh" ],
+[ 6563, "iri" ],
+[ 6564, "irj" ],
+[ 6565, "irk" ],
+[ 6566, "irl" ],
+[ 6567, "irm" ],
+[ 6568, "irn" ],
+[ 6569, "iro" ],
+[ 6570, "irp" ],
+[ 6571, "irq" ],
+[ 6572, "irr" ],
+[ 6573, "irs" ],
+[ 6574, "irt" ],
+[ 6575, "iru" ],
+[ 6576, "irv" ],
+[ 6577, "irw" ],
+[ 6578, "irx" ],
+[ 6579, "iry" ],
+[ 6580, "irz" ],
+[ 6581, "isa" ],
+[ 6582, "isb" ],
+[ 6583, "isc" ],
+[ 6584, "isd" ],
+[ 6585, "ise" ],
+[ 6586, "isf" ],
+[ 6587, "isg" ],
+[ 6588, "ish" ],
+[ 6589, "isi" ],
+[ 6590, "isj" ],
+[ 6591, "isk" ],
+[ 6592, "isl" ],
+[ 6593, "ism" ],
+[ 6594, "isn" ],
+[ 6595, "iso" ],
+[ 6596, "isp" ],
+[ 6597, "isq" ],
+[ 6598, "isr" ],
+[ 6599, "iss" ],
+[ 6600, "ist" ],
+[ 6601, "isu" ],
+[ 6602, "isv" ],
+[ 6603, "isw" ],
+[ 6604, "isx" ],
+[ 6605, "isy" ],
+[ 6606, "isz" ],
+[ 6607, "ita" ],
+[ 6608, "itb" ],
+[ 6609, "itc" ],
+[ 6610, "itd" ],
+[ 6611, "ite" ],
+[ 6612, "itf" ],
+[ 6613, "itg" ],
+[ 6614, "ith" ],
+[ 6615, "iti" ],
+[ 6616, "itj" ],
+[ 6617, "itk" ],
+[ 6618, "itl" ],
+[ 6619, "itm" ],
+[ 6620, "itn" ],
+[ 6621, "ito" ],
+[ 6622, "itp" ],
+[ 6623, "itq" ],
+[ 6624, "itr" ],
+[ 6625, "its" ],
+[ 6626, "itt" ],
+[ 6627, "itu" ],
+[ 6628, "itv" ],
+[ 6629, "itw" ],
+[ 6630, "itx" ],
+[ 6631, "ity" ],
+[ 6632, "itz" ],
+[ 6633, "iua" ],
+[ 6634, "iub" ],
+[ 6635, "iuc" ],
+[ 6636, "iud" ],
+[ 6637, "iue" ],
+[ 6638, "iuf" ],
+[ 6639, "iug" ],
+[ 6640, "iuh" ],
+[ 6641, "iui" ],
+[ 6642, "iuj" ],
+[ 6643, "iuk" ],
+[ 6644, "iul" ],
+[ 6645, "ium" ],
+[ 6646, "iun" ],
+[ 6647, "iuo" ],
+[ 6648, "iup" ],
+[ 6649, "iuq" ],
+[ 6650, "iur" ],
+[ 6651, "ius" ],
+[ 6652, "iut" ],
+[ 6653, "iuu" ],
+[ 6654, "iuv" ],
+[ 6655, "iuw" ],
+[ 6656, "iux" ],
+[ 6657, "iuy" ],
+[ 6658, "iuz" ],
+[ 6659, "iva" ],
+[ 6660, "ivb" ],
+[ 6661, "ivc" ],
+[ 6662, "ivd" ],
+[ 6663, "ive" ],
+[ 6664, "ivf" ],
+[ 6665, "ivg" ],
+[ 6666, "ivh" ],
+[ 6667, "ivi" ],
+[ 6668, "ivj" ],
+[ 6669, "ivk" ],
+[ 6670, "ivl" ],
+[ 6671, "ivm" ],
+[ 6672, "ivn" ],
+[ 6673, "ivo" ],
+[ 6674, "ivp" ],
+[ 6675, "ivq" ],
+[ 6676, "ivr" ],
+[ 6677, "ivs" ],
+[ 6678, "ivt" ],
+[ 6679, "ivu" ],
+[ 6680, "ivv" ],
+[ 6681, "ivw" ],
+[ 6682, "ivx" ],
+[ 6683, "ivy" ],
+[ 6684, "ivz" ],
+[ 6685, "iwa" ],
+[ 6686, "iwb" ],
+[ 6687, "iwc" ],
+[ 6688, "iwd" ],
+[ 6689, "iwe" ],
+[ 6690, "iwf" ],
+[ 6691, "iwg" ],
+[ 6692, "iwh" ],
+[ 6693, "iwi" ],
+[ 6694, "iwj" ],
+[ 6695, "iwk" ],
+[ 6696, "iwl" ],
+[ 6697, "iwm" ],
+[ 6698, "iwn" ],
+[ 6699, "iwo" ],
+[ 6700, "iwp" ],
+[ 6701, "iwq" ],
+[ 6702, "iwr" ],
+[ 6703, "iws" ],
+[ 6704, "iwt" ],
+[ 6705, "iwu" ],
+[ 6706, "iwv" ],
+[ 6707, "iww" ],
+[ 6708, "iwx" ],
+[ 6709, "iwy" ],
+[ 6710, "iwz" ],
+[ 6711, "ixa" ],
+[ 6712, "ixb" ],
+[ 6713, "ixc" ],
+[ 6714, "ixd" ],
+[ 6715, "ixe" ],
+[ 6716, "ixf" ],
+[ 6717, "ixg" ],
+[ 6718, "ixh" ],
+[ 6719, "ixi" ],
+[ 6720, "ixj" ],
+[ 6721, "ixk" ],
+[ 6722, "ixl" ],
+[ 6723, "ixm" ],
+[ 6724, "ixn" ],
+[ 6725, "ixo" ],
+[ 6726, "ixp" ],
+[ 6727, "ixq" ],
+[ 6728, "ixr" ],
+[ 6729, "ixs" ],
+[ 6730, "ixt" ],
+[ 6731, "ixu" ],
+[ 6732, "ixv" ],
+[ 6733, "ixw" ],
+[ 6734, "ixx" ],
+[ 6735, "ixy" ],
+[ 6736, "ixz" ],
+[ 6737, "iya" ],
+[ 6738, "iyb" ],
+[ 6739, "iyc" ],
+[ 6740, "iyd" ],
+[ 6741, "iye" ],
+[ 6742, "iyf" ],
+[ 6743, "iyg" ],
+[ 6744, "iyh" ],
+[ 6745, "iyi" ],
+[ 6746, "iyj" ],
+[ 6747, "iyk" ],
+[ 6748, "iyl" ],
+[ 6749, "iym" ],
+[ 6750, "iyn" ],
+[ 6751, "iyo" ],
+[ 6752, "iyp" ],
+[ 6753, "iyq" ],
+[ 6754, "iyr" ],
+[ 6755, "iys" ],
+[ 6756, "iyt" ],
+[ 6757, "iyu" ],
+[ 6758, "iyv" ],
+[ 6759, "iyw" ],
+[ 6760, "iyx" ],
+[ 6761, "iyy" ],
+[ 6762, "iyz" ],
+[ 6763, "iza" ],
+[ 6764, "izb" ],
+[ 6765, "izc" ],
+[ 6766, "izd" ],
+[ 6767, "ize" ],
+[ 6768, "izf" ],
+[ 6769, "izg" ],
+[ 6770, "izh" ],
+[ 6771, "izi" ],
+[ 6772, "izj" ],
+[ 6773, "izk" ],
+[ 6774, "izl" ],
+[ 6775, "izm" ],
+[ 6776, "izn" ],
+[ 6777, "izo" ],
+[ 6778, "izp" ],
+[ 6779, "izq" ],
+[ 6780, "izr" ],
+[ 6781, "izs" ],
+[ 6782, "izt" ],
+[ 6783, "izu" ],
+[ 6784, "izv" ],
+[ 6785, "izw" ],
+[ 6786, "izx" ],
+[ 6787, "izy" ],
+[ 6788, "izz" ],
+[ 6789, "jaa" ],
+[ 6790, "jab" ],
+[ 6791, "jac" ],
+[ 6792, "jad" ],
+[ 6793, "jae" ],
+[ 6794, "jaf" ],
+[ 6795, "jag" ],
+[ 6796, "jah" ],
+[ 6797, "jai" ],
+[ 6798, "jaj" ],
+[ 6799, "jak" ],
+[ 6800, "jal" ],
+[ 6801, "jam" ],
+[ 6802, "jan" ],
+[ 6803, "jao" ],
+[ 6804, "jap" ],
+[ 6805, "jaq" ],
+[ 6806, "jar" ],
+[ 6807, "jas" ],
+[ 6808, "jat" ],
+[ 6809, "jau" ],
+[ 6810, "jav" ],
+[ 6811, "jaw" ],
+[ 6812, "jax" ],
+[ 6813, "jay" ],
+[ 6814, "jaz" ],
+[ 6815, "jba" ],
+[ 6816, "jbb" ],
+[ 6817, "jbc" ],
+[ 6818, "jbd" ],
+[ 6819, "jbe" ],
+[ 6820, "jbf" ],
+[ 6821, "jbg" ],
+[ 6822, "jbh" ],
+[ 6823, "jbi" ],
+[ 6824, "jbj" ],
+[ 6825, "jbk" ],
+[ 6826, "jbl" ],
+[ 6827, "jbm" ],
+[ 6828, "jbn" ],
+[ 6829, "jbo" ],
+[ 6830, "jbp" ],
+[ 6831, "jbq" ],
+[ 6832, "jbr" ],
+[ 6833, "jbs" ],
+[ 6834, "jbt" ],
+[ 6835, "jbu" ],
+[ 6836, "jbv" ],
+[ 6837, "jbw" ],
+[ 6838, "jbx" ],
+[ 6839, "jby" ],
+[ 6840, "jbz" ],
+[ 6841, "jca" ],
+[ 6842, "jcb" ],
+[ 6843, "jcc" ],
+[ 6844, "jcd" ],
+[ 6845, "jce" ],
+[ 6846, "jcf" ],
+[ 6847, "jcg" ],
+[ 6848, "jch" ],
+[ 6849, "jci" ],
+[ 6850, "jcj" ],
+[ 6851, "jck" ],
+[ 6852, "jcl" ],
+[ 6853, "jcm" ],
+[ 6854, "jcn" ],
+[ 6855, "jco" ],
+[ 6856, "jcp" ],
+[ 6857, "jcq" ],
+[ 6858, "jcr" ],
+[ 6859, "jcs" ],
+[ 6860, "jct" ],
+[ 6861, "jcu" ],
+[ 6862, "jcv" ],
+[ 6863, "jcw" ],
+[ 6864, "jcx" ],
+[ 6865, "jcy" ],
+[ 6866, "jcz" ],
+[ 6867, "jda" ],
+[ 6868, "jdb" ],
+[ 6869, "jdc" ],
+[ 6870, "jdd" ],
+[ 6871, "jde" ],
+[ 6872, "jdf" ],
+[ 6873, "jdg" ],
+[ 6874, "jdh" ],
+[ 6875, "jdi" ],
+[ 6876, "jdj" ],
+[ 6877, "jdk" ],
+[ 6878, "jdl" ],
+[ 6879, "jdm" ],
+[ 6880, "jdn" ],
+[ 6881, "jdo" ],
+[ 6882, "jdp" ],
+[ 6883, "jdq" ],
+[ 6884, "jdr" ],
+[ 6885, "jds" ],
+[ 6886, "jdt" ],
+[ 6887, "jdu" ],
+[ 6888, "jdv" ],
+[ 6889, "jdw" ],
+[ 6890, "jdx" ],
+[ 6891, "jdy" ],
+[ 6892, "jdz" ],
+[ 6893, "jea" ],
+[ 6894, "jeb" ],
+[ 6895, "jec" ],
+[ 6896, "jed" ],
+[ 6897, "jee" ],
+[ 6898, "jef" ],
+[ 6899, "jeg" ],
+[ 6900, "jeh" ],
+[ 6901, "jei" ],
+[ 6902, "jej" ],
+[ 6903, "jek" ],
+[ 6904, "jel" ],
+[ 6905, "jem" ],
+[ 6906, "jen" ],
+[ 6907, "jeo" ],
+[ 6908, "jep" ],
+[ 6909, "jeq" ],
+[ 6910, "jer" ],
+[ 6911, "jes" ],
+[ 6912, "jet" ],
+[ 6913, "jeu" ],
+[ 6914, "jev" ],
+[ 6915, "jew" ],
+[ 6916, "jex" ],
+[ 6917, "jey" ],
+[ 6918, "jez" ],
+[ 6919, "jfa" ],
+[ 6920, "jfb" ],
+[ 6921, "jfc" ],
+[ 6922, "jfd" ],
+[ 6923, "jfe" ],
+[ 6924, "jff" ],
+[ 6925, "jfg" ],
+[ 6926, "jfh" ],
+[ 6927, "jfi" ],
+[ 6928, "jfj" ],
+[ 6929, "jfk" ],
+[ 6930, "jfl" ],
+[ 6931, "jfm" ],
+[ 6932, "jfn" ],
+[ 6933, "jfo" ],
+[ 6934, "jfp" ],
+[ 6935, "jfq" ],
+[ 6936, "jfr" ],
+[ 6937, "jfs" ],
+[ 6938, "jft" ],
+[ 6939, "jfu" ],
+[ 6940, "jfv" ],
+[ 6941, "jfw" ],
+[ 6942, "jfx" ],
+[ 6943, "jfy" ],
+[ 6944, "jfz" ],
+[ 6945, "jga" ],
+[ 6946, "jgb" ],
+[ 6947, "jgc" ],
+[ 6948, "jgd" ],
+[ 6949, "jge" ],
+[ 6950, "jgf" ],
+[ 6951, "jgg" ],
+[ 6952, "jgh" ],
+[ 6953, "jgi" ],
+[ 6954, "jgj" ],
+[ 6955, "jgk" ],
+[ 6956, "jgl" ],
+[ 6957, "jgm" ],
+[ 6958, "jgn" ],
+[ 6959, "jgo" ],
+[ 6960, "jgp" ],
+[ 6961, "jgq" ],
+[ 6962, "jgr" ],
+[ 6963, "jgs" ],
+[ 6964, "jgt" ],
+[ 6965, "jgu" ],
+[ 6966, "jgv" ],
+[ 6967, "jgw" ],
+[ 6968, "jgx" ],
+[ 6969, "jgy" ],
+[ 6970, "jgz" ],
+[ 6971, "jha" ],
+[ 6972, "jhb" ],
+[ 6973, "jhc" ],
+[ 6974, "jhd" ],
+[ 6975, "jhe" ],
+[ 6976, "jhf" ],
+[ 6977, "jhg" ],
+[ 6978, "jhh" ],
+[ 6979, "jhi" ],
+[ 6980, "jhj" ],
+[ 6981, "jhk" ],
+[ 6982, "jhl" ],
+[ 6983, "jhm" ],
+[ 6984, "jhn" ],
+[ 6985, "jho" ],
+[ 6986, "jhp" ],
+[ 6987, "jhq" ],
+[ 6988, "jhr" ],
+[ 6989, "jhs" ],
+[ 6990, "jht" ],
+[ 6991, "jhu" ],
+[ 6992, "jhv" ],
+[ 6993, "jhw" ],
+[ 6994, "jhx" ],
+[ 6995, "jhy" ],
+[ 6996, "jhz" ],
+[ 6997, "jia" ],
+[ 6998, "jib" ],
+[ 6999, "jic" ],
+[ 7000, "jid" ],
+[ 7001, "jie" ],
+[ 7002, "jif" ],
+[ 7003, "jig" ],
+[ 7004, "jih" ],
+[ 7005, "jii" ],
+[ 7006, "jij" ],
+[ 7007, "jik" ],
+[ 7008, "jil" ],
+[ 7009, "jim" ],
+[ 7010, "jin" ],
+[ 7011, "jio" ],
+[ 7012, "jip" ],
+[ 7013, "jiq" ],
+[ 7014, "jir" ],
+[ 7015, "jis" ],
+[ 7016, "jit" ],
+[ 7017, "jiu" ],
+[ 7018, "jiv" ],
+[ 7019, "jiw" ],
+[ 7020, "jix" ],
+[ 7021, "jiy" ],
+[ 7022, "jiz" ],
+[ 7023, "jja" ],
+[ 7024, "jjb" ],
+[ 7025, "jjc" ],
+[ 7026, "jjd" ],
+[ 7027, "jje" ],
+[ 7028, "jjf" ],
+[ 7029, "jjg" ],
+[ 7030, "jjh" ],
+[ 7031, "jji" ],
+[ 7032, "jjj" ],
+[ 7033, "jjk" ],
+[ 7034, "jjl" ],
+[ 7035, "jjm" ],
+[ 7036, "jjn" ],
+[ 7037, "jjo" ],
+[ 7038, "jjp" ],
+[ 7039, "jjq" ],
+[ 7040, "jjr" ],
+[ 7041, "jjs" ],
+[ 7042, "jjt" ],
+[ 7043, "jju" ],
+[ 7044, "jjv" ],
+[ 7045, "jjw" ],
+[ 7046, "jjx" ],
+[ 7047, "jjy" ],
+[ 7048, "jjz" ],
+[ 7049, "jka" ],
+[ 7050, "jkb" ],
+[ 7051, "jkc" ],
+[ 7052, "jkd" ],
+[ 7053, "jke" ],
+[ 7054, "jkf" ],
+[ 7055, "jkg" ],
+[ 7056, "jkh" ],
+[ 7057, "jki" ],
+[ 7058, "jkj" ],
+[ 7059, "jkk" ],
+[ 7060, "jkl" ],
+[ 7061, "jkm" ],
+[ 7062, "jkn" ],
+[ 7063, "jko" ],
+[ 7064, "jkp" ],
+[ 7065, "jkq" ],
+[ 7066, "jkr" ],
+[ 7067, "jks" ],
+[ 7068, "jkt" ],
+[ 7069, "jku" ],
+[ 7070, "jkv" ],
+[ 7071, "jkw" ],
+[ 7072, "jkx" ],
+[ 7073, "jky" ],
+[ 7074, "jkz" ],
+[ 7075, "jla" ],
+[ 7076, "jlb" ],
+[ 7077, "jlc" ],
+[ 7078, "jld" ],
+[ 7079, "jle" ],
+[ 7080, "jlf" ],
+[ 7081, "jlg" ],
+[ 7082, "jlh" ],
+[ 7083, "jli" ],
+[ 7084, "jlj" ],
+[ 7085, "jlk" ],
+[ 7086, "jll" ],
+[ 7087, "jlm" ],
+[ 7088, "jln" ],
+[ 7089, "jlo" ],
+[ 7090, "jlp" ],
+[ 7091, "jlq" ],
+[ 7092, "jlr" ],
+[ 7093, "jls" ],
+[ 7094, "jlt" ],
+[ 7095, "jlu" ],
+[ 7096, "jlv" ],
+[ 7097, "jlw" ],
+[ 7098, "jlx" ],
+[ 7099, "jly" ],
+[ 7100, "jlz" ],
+[ 7101, "jma" ],
+[ 7102, "jmb" ],
+[ 7103, "jmc" ],
+[ 7104, "jmd" ],
+[ 7105, "jme" ],
+[ 7106, "jmf" ],
+[ 7107, "jmg" ],
+[ 7108, "jmh" ],
+[ 7109, "jmi" ],
+[ 7110, "jmj" ],
+[ 7111, "jmk" ],
+[ 7112, "jml" ],
+[ 7113, "jmm" ],
+[ 7114, "jmn" ],
+[ 7115, "jmo" ],
+[ 7116, "jmp" ],
+[ 7117, "jmq" ],
+[ 7118, "jmr" ],
+[ 7119, "jms" ],
+[ 7120, "jmt" ],
+[ 7121, "jmu" ],
+[ 7122, "jmv" ],
+[ 7123, "jmw" ],
+[ 7124, "jmx" ],
+[ 7125, "jmy" ],
+[ 7126, "jmz" ],
+[ 7127, "jna" ],
+[ 7128, "jnb" ],
+[ 7129, "jnc" ],
+[ 7130, "jnd" ],
+[ 7131, "jne" ],
+[ 7132, "jnf" ],
+[ 7133, "jng" ],
+[ 7134, "jnh" ],
+[ 7135, "jni" ],
+[ 7136, "jnj" ],
+[ 7137, "jnk" ],
+[ 7138, "jnl" ],
+[ 7139, "jnm" ],
+[ 7140, "jnn" ],
+[ 7141, "jno" ],
+[ 7142, "jnp" ],
+[ 7143, "jnq" ],
+[ 7144, "jnr" ],
+[ 7145, "jns" ],
+[ 7146, "jnt" ],
+[ 7147, "jnu" ],
+[ 7148, "jnv" ],
+[ 7149, "jnw" ],
+[ 7150, "jnx" ],
+[ 7151, "jny" ],
+[ 7152, "jnz" ],
+[ 7153, "joa" ],
+[ 7154, "job" ],
+[ 7155, "joc" ],
+[ 7156, "jod" ],
+[ 7157, "joe" ],
+[ 7158, "jof" ],
+[ 7159, "jog" ],
+[ 7160, "joh" ],
+[ 7161, "joi" ],
+[ 7162, "joj" ],
+[ 7163, "jok" ],
+[ 7164, "jol" ],
+[ 7165, "jom" ],
+[ 7166, "jon" ],
+[ 7167, "joo" ],
+[ 7168, "jop" ],
+[ 7169, "joq" ],
+[ 7170, "jor" ],
+[ 7171, "jos" ],
+[ 7172, "jot" ],
+[ 7173, "jou" ],
+[ 7174, "jov" ],
+[ 7175, "jow" ],
+[ 7176, "jox" ],
+[ 7177, "joy" ],
+[ 7178, "joz" ],
+[ 7179, "jpa" ],
+[ 7180, "jpb" ],
+[ 7181, "jpc" ],
+[ 7182, "jpd" ],
+[ 7183, "jpe" ],
+[ 7184, "jpf" ],
+[ 7185, "jpg" ],
+[ 7186, "jph" ],
+[ 7187, "jpi" ],
+[ 7188, "jpj" ],
+[ 7189, "jpk" ],
+[ 7190, "jpl" ],
+[ 7191, "jpm" ],
+[ 7192, "jpn" ],
+[ 7193, "jpo" ],
+[ 7194, "jpp" ],
+[ 7195, "jpq" ],
+[ 7196, "jpr" ],
+[ 7197, "jps" ],
+[ 7198, "jpt" ],
+[ 7199, "jpu" ],
+[ 7200, "jpv" ],
+[ 7201, "jpw" ],
+[ 7202, "jpx" ],
+[ 7203, "jpy" ],
+[ 7204, "jpz" ],
+[ 7205, "jqa" ],
+[ 7206, "jqb" ],
+[ 7207, "jqc" ],
+[ 7208, "jqd" ],
+[ 7209, "jqe" ],
+[ 7210, "jqf" ],
+[ 7211, "jqg" ],
+[ 7212, "jqh" ],
+[ 7213, "jqi" ],
+[ 7214, "jqj" ],
+[ 7215, "jqk" ],
+[ 7216, "jql" ],
+[ 7217, "jqm" ],
+[ 7218, "jqn" ],
+[ 7219, "jqo" ],
+[ 7220, "jqp" ],
+[ 7221, "jqq" ],
+[ 7222, "jqr" ],
+[ 7223, "jqs" ],
+[ 7224, "jqt" ],
+[ 7225, "jqu" ],
+[ 7226, "jqv" ],
+[ 7227, "jqw" ],
+[ 7228, "jqx" ],
+[ 7229, "jqy" ],
+[ 7230, "jqz" ],
+[ 7231, "jra" ],
+[ 7232, "jrb" ],
+[ 7233, "jrc" ],
+[ 7234, "jrd" ],
+[ 7235, "jre" ],
+[ 7236, "jrf" ],
+[ 7237, "jrg" ],
+[ 7238, "jrh" ],
+[ 7239, "jri" ],
+[ 7240, "jrj" ],
+[ 7241, "jrk" ],
+[ 7242, "jrl" ],
+[ 7243, "jrm" ],
+[ 7244, "jrn" ],
+[ 7245, "jro" ],
+[ 7246, "jrp" ],
+[ 7247, "jrq" ],
+[ 7248, "jrr" ],
+[ 7249, "jrs" ],
+[ 7250, "jrt" ],
+[ 7251, "jru" ],
+[ 7252, "jrv" ],
+[ 7253, "jrw" ],
+[ 7254, "jrx" ],
+[ 7255, "jry" ],
+[ 7256, "jrz" ],
+[ 7257, "jsa" ],
+[ 7258, "jsb" ],
+[ 7259, "jsc" ],
+[ 7260, "jsd" ],
+[ 7261, "jse" ],
+[ 7262, "jsf" ],
+[ 7263, "jsg" ],
+[ 7264, "jsh" ],
+[ 7265, "jsi" ],
+[ 7266, "jsj" ],
+[ 7267, "jsk" ],
+[ 7268, "jsl" ],
+[ 7269, "jsm" ],
+[ 7270, "jsn" ],
+[ 7271, "jso" ],
+[ 7272, "jsp" ],
+[ 7273, "jsq" ],
+[ 7274, "jsr" ],
+[ 7275, "jss" ],
+[ 7276, "jst" ],
+[ 7277, "jsu" ],
+[ 7278, "jsv" ],
+[ 7279, "jsw" ],
+[ 7280, "jsx" ],
+[ 7281, "jsy" ],
+[ 7282, "jsz" ],
+[ 7283, "jta" ],
+[ 7284, "jtb" ],
+[ 7285, "jtc" ],
+[ 7286, "jtd" ],
+[ 7287, "jte" ],
+[ 7288, "jtf" ],
+[ 7289, "jtg" ],
+[ 7290, "jth" ],
+[ 7291, "jti" ],
+[ 7292, "jtj" ],
+[ 7293, "jtk" ],
+[ 7294, "jtl" ],
+[ 7295, "jtm" ],
+[ 7296, "jtn" ],
+[ 7297, "jto" ],
+[ 7298, "jtp" ],
+[ 7299, "jtq" ],
+[ 7300, "jtr" ],
+[ 7301, "jts" ],
+[ 7302, "jtt" ],
+[ 7303, "jtu" ],
+[ 7304, "jtv" ],
+[ 7305, "jtw" ],
+[ 7306, "jtx" ],
+[ 7307, "jty" ],
+[ 7308, "jtz" ],
+[ 7309, "jua" ],
+[ 7310, "jub" ],
+[ 7311, "juc" ],
+[ 7312, "jud" ],
+[ 7313, "jue" ],
+[ 7314, "juf" ],
+[ 7315, "jug" ],
+[ 7316, "juh" ],
+[ 7317, "jui" ],
+[ 7318, "juj" ],
+[ 7319, "juk" ],
+[ 7320, "jul" ],
+[ 7321, "jum" ],
+[ 7322, "jun" ],
+[ 7323, "juo" ],
+[ 7324, "jup" ],
+[ 7325, "juq" ],
+[ 7326, "jur" ],
+[ 7327, "jus" ],
+[ 7328, "jut" ],
+[ 7329, "juu" ],
+[ 7330, "juv" ],
+[ 7331, "juw" ],
+[ 7332, "jux" ],
+[ 7333, "juy" ],
+[ 7334, "juz" ],
+[ 7335, "jva" ],
+[ 7336, "jvb" ],
+[ 7337, "jvc" ],
+[ 7338, "jvd" ],
+[ 7339, "jve" ],
+[ 7340, "jvf" ],
+[ 7341, "jvg" ],
+[ 7342, "jvh" ],
+[ 7343, "jvi" ],
+[ 7344, "jvj" ],
+[ 7345, "jvk" ],
+[ 7346, "jvl" ],
+[ 7347, "jvm" ],
+[ 7348, "jvn" ],
+[ 7349, "jvo" ],
+[ 7350, "jvp" ],
+[ 7351, "jvq" ],
+[ 7352, "jvr" ],
+[ 7353, "jvs" ],
+[ 7354, "jvt" ],
+[ 7355, "jvu" ],
+[ 7356, "jvv" ],
+[ 7357, "jvw" ],
+[ 7358, "jvx" ],
+[ 7359, "jvy" ],
+[ 7360, "jvz" ],
+[ 7361, "jwa" ],
+[ 7362, "jwb" ],
+[ 7363, "jwc" ],
+[ 7364, "jwd" ],
+[ 7365, "jwe" ],
+[ 7366, "jwf" ],
+[ 7367, "jwg" ],
+[ 7368, "jwh" ],
+[ 7369, "jwi" ],
+[ 7370, "jwj" ],
+[ 7371, "jwk" ],
+[ 7372, "jwl" ],
+[ 7373, "jwm" ],
+[ 7374, "jwn" ],
+[ 7375, "jwo" ],
+[ 7376, "jwp" ],
+[ 7377, "jwq" ],
+[ 7378, "jwr" ],
+[ 7379, "jws" ],
+[ 7380, "jwt" ],
+[ 7381, "jwu" ],
+[ 7382, "jwv" ],
+[ 7383, "jww" ],
+[ 7384, "jwx" ],
+[ 7385, "jwy" ],
+[ 7386, "jwz" ],
+[ 7387, "jxa" ],
+[ 7388, "jxb" ],
+[ 7389, "jxc" ],
+[ 7390, "jxd" ],
+[ 7391, "jxe" ],
+[ 7392, "jxf" ],
+[ 7393, "jxg" ],
+[ 7394, "jxh" ],
+[ 7395, "jxi" ],
+[ 7396, "jxj" ],
+[ 7397, "jxk" ],
+[ 7398, "jxl" ],
+[ 7399, "jxm" ],
+[ 7400, "jxn" ],
+[ 7401, "jxo" ],
+[ 7402, "jxp" ],
+[ 7403, "jxq" ],
+[ 7404, "jxr" ],
+[ 7405, "jxs" ],
+[ 7406, "jxt" ],
+[ 7407, "jxu" ],
+[ 7408, "jxv" ],
+[ 7409, "jxw" ],
+[ 7410, "jxx" ],
+[ 7411, "jxy" ],
+[ 7412, "jxz" ],
+[ 7413, "jya" ],
+[ 7414, "jyb" ],
+[ 7415, "jyc" ],
+[ 7416, "jyd" ],
+[ 7417, "jye" ],
+[ 7418, "jyf" ],
+[ 7419, "jyg" ],
+[ 7420, "jyh" ],
+[ 7421, "jyi" ],
+[ 7422, "jyj" ],
+[ 7423, "jyk" ],
+[ 7424, "jyl" ],
+[ 7425, "jym" ],
+[ 7426, "jyn" ],
+[ 7427, "jyo" ],
+[ 7428, "jyp" ],
+[ 7429, "jyq" ],
+[ 7430, "jyr" ],
+[ 7431, "jys" ],
+[ 7432, "jyt" ],
+[ 7433, "jyu" ],
+[ 7434, "jyv" ],
+[ 7435, "jyw" ],
+[ 7436, "jyx" ],
+[ 7437, "jyy" ],
+[ 7438, "jyz" ],
+[ 7439, "jza" ],
+[ 7440, "jzb" ],
+[ 7441, "jzc" ],
+[ 7442, "jzd" ],
+[ 7443, "jze" ],
+[ 7444, "jzf" ],
+[ 7445, "jzg" ],
+[ 7446, "jzh" ],
+[ 7447, "jzi" ],
+[ 7448, "jzj" ],
+[ 7449, "jzk" ],
+[ 7450, "jzl" ],
+[ 7451, "jzm" ],
+[ 7452, "jzn" ],
+[ 7453, "jzo" ],
+[ 7454, "jzp" ],
+[ 7455, "jzq" ],
+[ 7456, "jzr" ],
+[ 7457, "jzs" ],
+[ 7458, "jzt" ],
+[ 7459, "jzu" ],
+[ 7460, "jzv" ],
+[ 7461, "jzw" ],
+[ 7462, "jzx" ],
+[ 7463, "jzy" ],
+[ 7464, "jzz" ],
+[ 7465, "kaa" ],
+[ 7466, "kab" ],
+[ 7467, "kac" ],
+[ 7468, "kad" ],
+[ 7469, "kae" ],
+[ 7470, "kaf" ],
+[ 7471, "kag" ],
+[ 7472, "kah" ],
+[ 7473, "kai" ],
+[ 7474, "kaj" ],
+[ 7475, "kak" ],
+[ 7476, "kal" ],
+[ 7477, "kam" ],
+[ 7478, "kan" ],
+[ 7479, "kao" ],
+[ 7480, "kap" ],
+[ 7481, "kaq" ],
+[ 7482, "kar" ],
+[ 7483, "kas" ],
+[ 7484, "kat" ],
+[ 7485, "kau" ],
+[ 7486, "kav" ],
+[ 7487, "kaw" ],
+[ 7488, "kax" ],
+[ 7489, "kay" ],
+[ 7490, "kaz" ],
+[ 7491, "kba" ],
+[ 7492, "kbb" ],
+[ 7493, "kbc" ],
+[ 7494, "kbd" ],
+[ 7495, "kbe" ],
+[ 7496, "kbf" ],
+[ 7497, "kbg" ],
+[ 7498, "kbh" ],
+[ 7499, "kbi" ],
+[ 7500, "kbj" ],
+[ 7501, "kbk" ],
+[ 7502, "kbl" ],
+[ 7503, "kbm" ],
+[ 7504, "kbn" ],
+[ 7505, "kbo" ],
+[ 7506, "kbp" ],
+[ 7507, "kbq" ],
+[ 7508, "kbr" ],
+[ 7509, "kbs" ],
+[ 7510, "kbt" ],
+[ 7511, "kbu" ],
+[ 7512, "kbv" ],
+[ 7513, "kbw" ],
+[ 7514, "kbx" ],
+[ 7515, "kby" ],
+[ 7516, "kbz" ],
+[ 7517, "kca" ],
+[ 7518, "kcb" ],
+[ 7519, "kcc" ],
+[ 7520, "kcd" ],
+[ 7521, "kce" ],
+[ 7522, "kcf" ],
+[ 7523, "kcg" ],
+[ 7524, "kch" ],
+[ 7525, "kci" ],
+[ 7526, "kcj" ],
+[ 7527, "kck" ],
+[ 7528, "kcl" ],
+[ 7529, "kcm" ],
+[ 7530, "kcn" ],
+[ 7531, "kco" ],
+[ 7532, "kcp" ],
+[ 7533, "kcq" ],
+[ 7534, "kcr" ],
+[ 7535, "kcs" ],
+[ 7536, "kct" ],
+[ 7537, "kcu" ],
+[ 7538, "kcv" ],
+[ 7539, "kcw" ],
+[ 7540, "kcx" ],
+[ 7541, "kcy" ],
+[ 7542, "kcz" ],
+[ 7543, "kda" ],
+[ 7544, "kdb" ],
+[ 7545, "kdc" ],
+[ 7546, "kdd" ],
+[ 7547, "kde" ],
+[ 7548, "kdf" ],
+[ 7549, "kdg" ],
+[ 7550, "kdh" ],
+[ 7551, "kdi" ],
+[ 7552, "kdj" ],
+[ 7553, "kdk" ],
+[ 7554, "kdl" ],
+[ 7555, "kdm" ],
+[ 7556, "kdn" ],
+[ 7557, "kdo" ],
+[ 7558, "kdp" ],
+[ 7559, "kdq" ],
+[ 7560, "kdr" ],
+[ 7561, "kds" ],
+[ 7562, "kdt" ],
+[ 7563, "kdu" ],
+[ 7564, "kdv" ],
+[ 7565, "kdw" ],
+[ 7566, "kdx" ],
+[ 7567, "kdy" ],
+[ 7568, "kdz" ],
+[ 7569, "kea" ],
+[ 7570, "keb" ],
+[ 7571, "kec" ],
+[ 7572, "ked" ],
+[ 7573, "kee" ],
+[ 7574, "kef" ],
+[ 7575, "keg" ],
+[ 7576, "keh" ],
+[ 7577, "kei" ],
+[ 7578, "kej" ],
+[ 7579, "kek" ],
+[ 7580, "kel" ],
+[ 7581, "kem" ],
+[ 7582, "ken" ],
+[ 7583, "keo" ],
+[ 7584, "kep" ],
+[ 7585, "keq" ],
+[ 7586, "ker" ],
+[ 7587, "kes" ],
+[ 7588, "ket" ],
+[ 7589, "keu" ],
+[ 7590, "kev" ],
+[ 7591, "kew" ],
+[ 7592, "kex" ],
+[ 7593, "key" ],
+[ 7594, "kez" ],
+[ 7595, "kfa" ],
+[ 7596, "kfb" ],
+[ 7597, "kfc" ],
+[ 7598, "kfd" ],
+[ 7599, "kfe" ],
+[ 7600, "kff" ],
+[ 7601, "kfg" ],
+[ 7602, "kfh" ],
+[ 7603, "kfi" ],
+[ 7604, "kfj" ],
+[ 7605, "kfk" ],
+[ 7606, "kfl" ],
+[ 7607, "kfm" ],
+[ 7608, "kfn" ],
+[ 7609, "kfo" ],
+[ 7610, "kfp" ],
+[ 7611, "kfq" ],
+[ 7612, "kfr" ],
+[ 7613, "kfs" ],
+[ 7614, "kft" ],
+[ 7615, "kfu" ],
+[ 7616, "kfv" ],
+[ 7617, "kfw" ],
+[ 7618, "kfx" ],
+[ 7619, "kfy" ],
+[ 7620, "kfz" ],
+[ 7621, "kga" ],
+[ 7622, "kgb" ],
+[ 7623, "kgc" ],
+[ 7624, "kgd" ],
+[ 7625, "kge" ],
+[ 7626, "kgf" ],
+[ 7627, "kgg" ],
+[ 7628, "kgh" ],
+[ 7629, "kgi" ],
+[ 7630, "kgj" ],
+[ 7631, "kgk" ],
+[ 7632, "kgl" ],
+[ 7633, "kgm" ],
+[ 7634, "kgn" ],
+[ 7635, "kgo" ],
+[ 7636, "kgp" ],
+[ 7637, "kgq" ],
+[ 7638, "kgr" ],
+[ 7639, "kgs" ],
+[ 7640, "kgt" ],
+[ 7641, "kgu" ],
+[ 7642, "kgv" ],
+[ 7643, "kgw" ],
+[ 7644, "kgx" ],
+[ 7645, "kgy" ],
+[ 7646, "kgz" ],
+[ 7647, "kha" ],
+[ 7648, "khb" ],
+[ 7649, "khc" ],
+[ 7650, "khd" ],
+[ 7651, "khe" ],
+[ 7652, "khf" ],
+[ 7653, "khg" ],
+[ 7654, "khh" ],
+[ 7655, "khi" ],
+[ 7656, "khj" ],
+[ 7657, "khk" ],
+[ 7658, "khl" ],
+[ 7659, "khm" ],
+[ 7660, "khn" ],
+[ 7661, "kho" ],
+[ 7662, "khp" ],
+[ 7663, "khq" ],
+[ 7664, "khr" ],
+[ 7665, "khs" ],
+[ 7666, "kht" ],
+[ 7667, "khu" ],
+[ 7668, "khv" ],
+[ 7669, "khw" ],
+[ 7670, "khx" ],
+[ 7671, "khy" ],
+[ 7672, "khz" ],
+[ 7673, "kia" ],
+[ 7674, "kib" ],
+[ 7675, "kic" ],
+[ 7676, "kid" ],
+[ 7677, "kie" ],
+[ 7678, "kif" ],
+[ 7679, "kig" ],
+[ 7680, "kih" ],
+[ 7681, "kii" ],
+[ 7682, "kij" ],
+[ 7683, "kik" ],
+[ 7684, "kil" ],
+[ 7685, "kim" ],
+[ 7686, "kin" ],
+[ 7687, "kio" ],
+[ 7688, "kip" ],
+[ 7689, "kiq" ],
+[ 7690, "kir" ],
+[ 7691, "kis" ],
+[ 7692, "kit" ],
+[ 7693, "kiu" ],
+[ 7694, "kiv" ],
+[ 7695, "kiw" ],
+[ 7696, "kix" ],
+[ 7697, "kiy" ],
+[ 7698, "kiz" ],
+[ 7699, "kja" ],
+[ 7700, "kjb" ],
+[ 7701, "kjc" ],
+[ 7702, "kjd" ],
+[ 7703, "kje" ],
+[ 7704, "kjf" ],
+[ 7705, "kjg" ],
+[ 7706, "kjh" ],
+[ 7707, "kji" ],
+[ 7708, "kjj" ],
+[ 7709, "kjk" ],
+[ 7710, "kjl" ],
+[ 7711, "kjm" ],
+[ 7712, "kjn" ],
+[ 7713, "kjo" ],
+[ 7714, "kjp" ],
+[ 7715, "kjq" ],
+[ 7716, "kjr" ],
+[ 7717, "kjs" ],
+[ 7718, "kjt" ],
+[ 7719, "kju" ],
+[ 7720, "kjv" ],
+[ 7721, "kjw" ],
+[ 7722, "kjx" ],
+[ 7723, "kjy" ],
+[ 7724, "kjz" ],
+[ 7725, "kka" ],
+[ 7726, "kkb" ],
+[ 7727, "kkc" ],
+[ 7728, "kkd" ],
+[ 7729, "kke" ],
+[ 7730, "kkf" ],
+[ 7731, "kkg" ],
+[ 7732, "kkh" ],
+[ 7733, "kki" ],
+[ 7734, "kkj" ],
+[ 7735, "kkk" ],
+[ 7736, "kkl" ],
+[ 7737, "kkm" ],
+[ 7738, "kkn" ],
+[ 7739, "kko" ],
+[ 7740, "kkp" ],
+[ 7741, "kkq" ],
+[ 7742, "kkr" ],
+[ 7743, "kks" ],
+[ 7744, "kkt" ],
+[ 7745, "kku" ],
+[ 7746, "kkv" ],
+[ 7747, "kkw" ],
+[ 7748, "kkx" ],
+[ 7749, "kky" ],
+[ 7750, "kkz" ],
+[ 7751, "kla" ],
+[ 7752, "klb" ],
+[ 7753, "klc" ],
+[ 7754, "kld" ],
+[ 7755, "kle" ],
+[ 7756, "klf" ],
+[ 7757, "klg" ],
+[ 7758, "klh" ],
+[ 7759, "kli" ],
+[ 7760, "klj" ],
+[ 7761, "klk" ],
+[ 7762, "kll" ],
+[ 7763, "klm" ],
+[ 7764, "kln" ],
+[ 7765, "klo" ],
+[ 7766, "klp" ],
+[ 7767, "klq" ],
+[ 7768, "klr" ],
+[ 7769, "kls" ],
+[ 7770, "klt" ],
+[ 7771, "klu" ],
+[ 7772, "klv" ],
+[ 7773, "klw" ],
+[ 7774, "klx" ],
+[ 7775, "kly" ],
+[ 7776, "klz" ],
+[ 7777, "kma" ],
+[ 7778, "kmb" ],
+[ 7779, "kmc" ],
+[ 7780, "kmd" ],
+[ 7781, "kme" ],
+[ 7782, "kmf" ],
+[ 7783, "kmg" ],
+[ 7784, "kmh" ],
+[ 7785, "kmi" ],
+[ 7786, "kmj" ],
+[ 7787, "kmk" ],
+[ 7788, "kml" ],
+[ 7789, "kmm" ],
+[ 7790, "kmn" ],
+[ 7791, "kmo" ],
+[ 7792, "kmp" ],
+[ 7793, "kmq" ],
+[ 7794, "kmr" ],
+[ 7795, "kms" ],
+[ 7796, "kmt" ],
+[ 7797, "kmu" ],
+[ 7798, "kmv" ],
+[ 7799, "kmw" ],
+[ 7800, "kmx" ],
+[ 7801, "kmy" ],
+[ 7802, "kmz" ],
+[ 7803, "kna" ],
+[ 7804, "knb" ],
+[ 7805, "knc" ],
+[ 7806, "knd" ],
+[ 7807, "kne" ],
+[ 7808, "knf" ],
+[ 7809, "kng" ],
+[ 7810, "knh" ],
+[ 7811, "kni" ],
+[ 7812, "knj" ],
+[ 7813, "knk" ],
+[ 7814, "knl" ],
+[ 7815, "knm" ],
+[ 7816, "knn" ],
+[ 7817, "kno" ],
+[ 7818, "knp" ],
+[ 7819, "knq" ],
+[ 7820, "knr" ],
+[ 7821, "kns" ],
+[ 7822, "knt" ],
+[ 7823, "knu" ],
+[ 7824, "knv" ],
+[ 7825, "knw" ],
+[ 7826, "knx" ],
+[ 7827, "kny" ],
+[ 7828, "knz" ],
+[ 7829, "koa" ],
+[ 7830, "kob" ],
+[ 7831, "koc" ],
+[ 7832, "kod" ],
+[ 7833, "koe" ],
+[ 7834, "kof" ],
+[ 7835, "kog" ],
+[ 7836, "koh" ],
+[ 7837, "koi" ],
+[ 7838, "koj" ],
+[ 7839, "kok" ],
+[ 7840, "kol" ],
+[ 7841, "kom" ],
+[ 7842, "kon" ],
+[ 7843, "koo" ],
+[ 7844, "kop" ],
+[ 7845, "koq" ],
+[ 7846, "kor" ],
+[ 7847, "kos" ],
+[ 7848, "kot" ],
+[ 7849, "kou" ],
+[ 7850, "kov" ],
+[ 7851, "kow" ],
+[ 7852, "kox" ],
+[ 7853, "koy" ],
+[ 7854, "koz" ],
+[ 7855, "kpa" ],
+[ 7856, "kpb" ],
+[ 7857, "kpc" ],
+[ 7858, "kpd" ],
+[ 7859, "kpe" ],
+[ 7860, "kpf" ],
+[ 7861, "kpg" ],
+[ 7862, "kph" ],
+[ 7863, "kpi" ],
+[ 7864, "kpj" ],
+[ 7865, "kpk" ],
+[ 7866, "kpl" ],
+[ 7867, "kpm" ],
+[ 7868, "kpn" ],
+[ 7869, "kpo" ],
+[ 7870, "kpp" ],
+[ 7871, "kpq" ],
+[ 7872, "kpr" ],
+[ 7873, "kps" ],
+[ 7874, "kpt" ],
+[ 7875, "kpu" ],
+[ 7876, "kpv" ],
+[ 7877, "kpw" ],
+[ 7878, "kpx" ],
+[ 7879, "kpy" ],
+[ 7880, "kpz" ],
+[ 7881, "kqa" ],
+[ 7882, "kqb" ],
+[ 7883, "kqc" ],
+[ 7884, "kqd" ],
+[ 7885, "kqe" ],
+[ 7886, "kqf" ],
+[ 7887, "kqg" ],
+[ 7888, "kqh" ],
+[ 7889, "kqi" ],
+[ 7890, "kqj" ],
+[ 7891, "kqk" ],
+[ 7892, "kql" ],
+[ 7893, "kqm" ],
+[ 7894, "kqn" ],
+[ 7895, "kqo" ],
+[ 7896, "kqp" ],
+[ 7897, "kqq" ],
+[ 7898, "kqr" ],
+[ 7899, "kqs" ],
+[ 7900, "kqt" ],
+[ 7901, "kqu" ],
+[ 7902, "kqv" ],
+[ 7903, "kqw" ],
+[ 7904, "kqx" ],
+[ 7905, "kqy" ],
+[ 7906, "kqz" ],
+[ 7907, "kra" ],
+[ 7908, "krb" ],
+[ 7909, "krc" ],
+[ 7910, "krd" ],
+[ 7911, "kre" ],
+[ 7912, "krf" ],
+[ 7913, "krg" ],
+[ 7914, "krh" ],
+[ 7915, "kri" ],
+[ 7916, "krj" ],
+[ 7917, "krk" ],
+[ 7918, "krl" ],
+[ 7919, "krm" ],
+[ 7920, "krn" ],
+[ 7921, "kro" ],
+[ 7922, "krp" ],
+[ 7923, "krq" ],
+[ 7924, "krr" ],
+[ 7925, "krs" ],
+[ 7926, "krt" ],
+[ 7927, "kru" ],
+[ 7928, "krv" ],
+[ 7929, "krw" ],
+[ 7930, "krx" ],
+[ 7931, "kry" ],
+[ 7932, "krz" ],
+[ 7933, "ksa" ],
+[ 7934, "ksb" ],
+[ 7935, "ksc" ],
+[ 7936, "ksd" ],
+[ 7937, "kse" ],
+[ 7938, "ksf" ],
+[ 7939, "ksg" ],
+[ 7940, "ksh" ],
+[ 7941, "ksi" ],
+[ 7942, "ksj" ],
+[ 7943, "ksk" ],
+[ 7944, "ksl" ],
+[ 7945, "ksm" ],
+[ 7946, "ksn" ],
+[ 7947, "kso" ],
+[ 7948, "ksp" ],
+[ 7949, "ksq" ],
+[ 7950, "ksr" ],
+[ 7951, "kss" ],
+[ 7952, "kst" ],
+[ 7953, "ksu" ],
+[ 7954, "ksv" ],
+[ 7955, "ksw" ],
+[ 7956, "ksx" ],
+[ 7957, "ksy" ],
+[ 7958, "ksz" ],
+[ 7959, "kta" ],
+[ 7960, "ktb" ],
+[ 7961, "ktc" ],
+[ 7962, "ktd" ],
+[ 7963, "kte" ],
+[ 7964, "ktf" ],
+[ 7965, "ktg" ],
+[ 7966, "kth" ],
+[ 7967, "kti" ],
+[ 7968, "ktj" ],
+[ 7969, "ktk" ],
+[ 7970, "ktl" ],
+[ 7971, "ktm" ],
+[ 7972, "ktn" ],
+[ 7973, "kto" ],
+[ 7974, "ktp" ],
+[ 7975, "ktq" ],
+[ 7976, "ktr" ],
+[ 7977, "kts" ],
+[ 7978, "ktt" ],
+[ 7979, "ktu" ],
+[ 7980, "ktv" ],
+[ 7981, "ktw" ],
+[ 7982, "ktx" ],
+[ 7983, "kty" ],
+[ 7984, "ktz" ],
+[ 7985, "kua" ],
+[ 7986, "kub" ],
+[ 7987, "kuc" ],
+[ 7988, "kud" ],
+[ 7989, "kue" ],
+[ 7990, "kuf" ],
+[ 7991, "kug" ],
+[ 7992, "kuh" ],
+[ 7993, "kui" ],
+[ 7994, "kuj" ],
+[ 7995, "kuk" ],
+[ 7996, "kul" ],
+[ 7997, "kum" ],
+[ 7998, "kun" ],
+[ 7999, "kuo" ],
+[ 8000, "kup" ],
+[ 8001, "kuq" ],
+[ 8002, "kur" ],
+[ 8003, "kus" ],
+[ 8004, "kut" ],
+[ 8005, "kuu" ],
+[ 8006, "kuv" ],
+[ 8007, "kuw" ],
+[ 8008, "kux" ],
+[ 8009, "kuy" ],
+[ 8010, "kuz" ],
+[ 8011, "kva" ],
+[ 8012, "kvb" ],
+[ 8013, "kvc" ],
+[ 8014, "kvd" ],
+[ 8015, "kve" ],
+[ 8016, "kvf" ],
+[ 8017, "kvg" ],
+[ 8018, "kvh" ],
+[ 8019, "kvi" ],
+[ 8020, "kvj" ],
+[ 8021, "kvk" ],
+[ 8022, "kvl" ],
+[ 8023, "kvm" ],
+[ 8024, "kvn" ],
+[ 8025, "kvo" ],
+[ 8026, "kvp" ],
+[ 8027, "kvq" ],
+[ 8028, "kvr" ],
+[ 8029, "kvs" ],
+[ 8030, "kvt" ],
+[ 8031, "kvu" ],
+[ 8032, "kvv" ],
+[ 8033, "kvw" ],
+[ 8034, "kvx" ],
+[ 8035, "kvy" ],
+[ 8036, "kvz" ],
+[ 8037, "kwa" ],
+[ 8038, "kwb" ],
+[ 8039, "kwc" ],
+[ 8040, "kwd" ],
+[ 8041, "kwe" ],
+[ 8042, "kwf" ],
+[ 8043, "kwg" ],
+[ 8044, "kwh" ],
+[ 8045, "kwi" ],
+[ 8046, "kwj" ],
+[ 8047, "kwk" ],
+[ 8048, "kwl" ],
+[ 8049, "kwm" ],
+[ 8050, "kwn" ],
+[ 8051, "kwo" ],
+[ 8052, "kwp" ],
+[ 8053, "kwq" ],
+[ 8054, "kwr" ],
+[ 8055, "kws" ],
+[ 8056, "kwt" ],
+[ 8057, "kwu" ],
+[ 8058, "kwv" ],
+[ 8059, "kww" ],
+[ 8060, "kwx" ],
+[ 8061, "kwy" ],
+[ 8062, "kwz" ],
+[ 8063, "kxa" ],
+[ 8064, "kxb" ],
+[ 8065, "kxc" ],
+[ 8066, "kxd" ],
+[ 8067, "kxe" ],
+[ 8068, "kxf" ],
+[ 8069, "kxg" ],
+[ 8070, "kxh" ],
+[ 8071, "kxi" ],
+[ 8072, "kxj" ],
+[ 8073, "kxk" ],
+[ 8074, "kxl" ],
+[ 8075, "kxm" ],
+[ 8076, "kxn" ],
+[ 8077, "kxo" ],
+[ 8078, "kxp" ],
+[ 8079, "kxq" ],
+[ 8080, "kxr" ],
+[ 8081, "kxs" ],
+[ 8082, "kxt" ],
+[ 8083, "kxu" ],
+[ 8084, "kxv" ],
+[ 8085, "kxw" ],
+[ 8086, "kxx" ],
+[ 8087, "kxy" ],
+[ 8088, "kxz" ],
+[ 8089, "kya" ],
+[ 8090, "kyb" ],
+[ 8091, "kyc" ],
+[ 8092, "kyd" ],
+[ 8093, "kye" ],
+[ 8094, "kyf" ],
+[ 8095, "kyg" ],
+[ 8096, "kyh" ],
+[ 8097, "kyi" ],
+[ 8098, "kyj" ],
+[ 8099, "kyk" ],
+[ 8100, "kyl" ],
+[ 8101, "kym" ],
+[ 8102, "kyn" ],
+[ 8103, "kyo" ],
+[ 8104, "kyp" ],
+[ 8105, "kyq" ],
+[ 8106, "kyr" ],
+[ 8107, "kys" ],
+[ 8108, "kyt" ],
+[ 8109, "kyu" ],
+[ 8110, "kyv" ],
+[ 8111, "kyw" ],
+[ 8112, "kyx" ],
+[ 8113, "kyy" ],
+[ 8114, "kyz" ],
+[ 8115, "kza" ],
+[ 8116, "kzb" ],
+[ 8117, "kzc" ],
+[ 8118, "kzd" ],
+[ 8119, "kze" ],
+[ 8120, "kzf" ],
+[ 8121, "kzg" ],
+[ 8122, "kzh" ],
+[ 8123, "kzi" ],
+[ 8124, "kzj" ],
+[ 8125, "kzk" ],
+[ 8126, "kzl" ],
+[ 8127, "kzm" ],
+[ 8128, "kzn" ],
+[ 8129, "kzo" ],
+[ 8130, "kzp" ],
+[ 8131, "kzq" ],
+[ 8132, "kzr" ],
+[ 8133, "kzs" ],
+[ 8134, "kzt" ],
+[ 8135, "kzu" ],
+[ 8136, "kzv" ],
+[ 8137, "kzw" ],
+[ 8138, "kzx" ],
+[ 8139, "kzy" ],
+[ 8140, "kzz" ],
+[ 8141, "laa" ],
+[ 8142, "lab" ],
+[ 8143, "lac" ],
+[ 8144, "lad" ],
+[ 8145, "lae" ],
+[ 8146, "laf" ],
+[ 8147, "lag" ],
+[ 8148, "lah" ],
+[ 8149, "lai" ],
+[ 8150, "laj" ],
+[ 8151, "lak" ],
+[ 8152, "lal" ],
+[ 8153, "lam" ],
+[ 8154, "lan" ],
+[ 8155, "lao" ],
+[ 8156, "lap" ],
+[ 8157, "laq" ],
+[ 8158, "lar" ],
+[ 8159, "las" ],
+[ 8160, "lat" ],
+[ 8161, "lau" ],
+[ 8162, "lav" ],
+[ 8163, "law" ],
+[ 8164, "lax" ],
+[ 8165, "lay" ],
+[ 8166, "laz" ],
+[ 8167, "lba" ],
+[ 8168, "lbb" ],
+[ 8169, "lbc" ],
+[ 8170, "lbd" ],
+[ 8171, "lbe" ],
+[ 8172, "lbf" ],
+[ 8173, "lbg" ],
+[ 8174, "lbh" ],
+[ 8175, "lbi" ],
+[ 8176, "lbj" ],
+[ 8177, "lbk" ],
+[ 8178, "lbl" ],
+[ 8179, "lbm" ],
+[ 8180, "lbn" ],
+[ 8181, "lbo" ],
+[ 8182, "lbp" ],
+[ 8183, "lbq" ],
+[ 8184, "lbr" ],
+[ 8185, "lbs" ],
+[ 8186, "lbt" ],
+[ 8187, "lbu" ],
+[ 8188, "lbv" ],
+[ 8189, "lbw" ],
+[ 8190, "lbx" ],
+[ 8191, "lby" ],
+[ 8192, "lbz" ],
+[ 8193, "lca" ],
+[ 8194, "lcb" ],
+[ 8195, "lcc" ],
+[ 8196, "lcd" ],
+[ 8197, "lce" ],
+[ 8198, "lcf" ],
+[ 8199, "lcg" ],
+[ 8200, "lch" ],
+[ 8201, "lci" ],
+[ 8202, "lcj" ],
+[ 8203, "lck" ],
+[ 8204, "lcl" ],
+[ 8205, "lcm" ],
+[ 8206, "lcn" ],
+[ 8207, "lco" ],
+[ 8208, "lcp" ],
+[ 8209, "lcq" ],
+[ 8210, "lcr" ],
+[ 8211, "lcs" ],
+[ 8212, "lct" ],
+[ 8213, "lcu" ],
+[ 8214, "lcv" ],
+[ 8215, "lcw" ],
+[ 8216, "lcx" ],
+[ 8217, "lcy" ],
+[ 8218, "lcz" ],
+[ 8219, "lda" ],
+[ 8220, "ldb" ],
+[ 8221, "ldc" ],
+[ 8222, "ldd" ],
+[ 8223, "lde" ],
+[ 8224, "ldf" ],
+[ 8225, "ldg" ],
+[ 8226, "ldh" ],
+[ 8227, "ldi" ],
+[ 8228, "ldj" ],
+[ 8229, "ldk" ],
+[ 8230, "ldl" ],
+[ 8231, "ldm" ],
+[ 8232, "ldn" ],
+[ 8233, "ldo" ],
+[ 8234, "ldp" ],
+[ 8235, "ldq" ],
+[ 8236, "ldr" ],
+[ 8237, "lds" ],
+[ 8238, "ldt" ],
+[ 8239, "ldu" ],
+[ 8240, "ldv" ],
+[ 8241, "ldw" ],
+[ 8242, "ldx" ],
+[ 8243, "ldy" ],
+[ 8244, "ldz" ],
+[ 8245, "lea" ],
+[ 8246, "leb" ],
+[ 8247, "lec" ],
+[ 8248, "led" ],
+[ 8249, "lee" ],
+[ 8250, "lef" ],
+[ 8251, "leg" ],
+[ 8252, "leh" ],
+[ 8253, "lei" ],
+[ 8254, "lej" ],
+[ 8255, "lek" ],
+[ 8256, "lel" ],
+[ 8257, "lem" ],
+[ 8258, "len" ],
+[ 8259, "leo" ],
+[ 8260, "lep" ],
+[ 8261, "leq" ],
+[ 8262, "ler" ],
+[ 8263, "les" ],
+[ 8264, "let" ],
+[ 8265, "leu" ],
+[ 8266, "lev" ],
+[ 8267, "lew" ],
+[ 8268, "lex" ],
+[ 8269, "ley" ],
+[ 8270, "lez" ],
+[ 8271, "lfa" ],
+[ 8272, "lfb" ],
+[ 8273, "lfc" ],
+[ 8274, "lfd" ],
+[ 8275, "lfe" ],
+[ 8276, "lff" ],
+[ 8277, "lfg" ],
+[ 8278, "lfh" ],
+[ 8279, "lfi" ],
+[ 8280, "lfj" ],
+[ 8281, "lfk" ],
+[ 8282, "lfl" ],
+[ 8283, "lfm" ],
+[ 8284, "lfn" ],
+[ 8285, "lfo" ],
+[ 8286, "lfp" ],
+[ 8287, "lfq" ],
+[ 8288, "lfr" ],
+[ 8289, "lfs" ],
+[ 8290, "lft" ],
+[ 8291, "lfu" ],
+[ 8292, "lfv" ],
+[ 8293, "lfw" ],
+[ 8294, "lfx" ],
+[ 8295, "lfy" ],
+[ 8296, "lfz" ],
+[ 8297, "lga" ],
+[ 8298, "lgb" ],
+[ 8299, "lgc" ],
+[ 8300, "lgd" ],
+[ 8301, "lge" ],
+[ 8302, "lgf" ],
+[ 8303, "lgg" ],
+[ 8304, "lgh" ],
+[ 8305, "lgi" ],
+[ 8306, "lgj" ],
+[ 8307, "lgk" ],
+[ 8308, "lgl" ],
+[ 8309, "lgm" ],
+[ 8310, "lgn" ],
+[ 8311, "lgo" ],
+[ 8312, "lgp" ],
+[ 8313, "lgq" ],
+[ 8314, "lgr" ],
+[ 8315, "lgs" ],
+[ 8316, "lgt" ],
+[ 8317, "lgu" ],
+[ 8318, "lgv" ],
+[ 8319, "lgw" ],
+[ 8320, "lgx" ],
+[ 8321, "lgy" ],
+[ 8322, "lgz" ],
+[ 8323, "lha" ],
+[ 8324, "lhb" ],
+[ 8325, "lhc" ],
+[ 8326, "lhd" ],
+[ 8327, "lhe" ],
+[ 8328, "lhf" ],
+[ 8329, "lhg" ],
+[ 8330, "lhh" ],
+[ 8331, "lhi" ],
+[ 8332, "lhj" ],
+[ 8333, "lhk" ],
+[ 8334, "lhl" ],
+[ 8335, "lhm" ],
+[ 8336, "lhn" ],
+[ 8337, "lho" ],
+[ 8338, "lhp" ],
+[ 8339, "lhq" ],
+[ 8340, "lhr" ],
+[ 8341, "lhs" ],
+[ 8342, "lht" ],
+[ 8343, "lhu" ],
+[ 8344, "lhv" ],
+[ 8345, "lhw" ],
+[ 8346, "lhx" ],
+[ 8347, "lhy" ],
+[ 8348, "lhz" ],
+[ 8349, "lia" ],
+[ 8350, "lib" ],
+[ 8351, "lic" ],
+[ 8352, "lid" ],
+[ 8353, "lie" ],
+[ 8354, "lif" ],
+[ 8355, "lig" ],
+[ 8356, "lih" ],
+[ 8357, "lii" ],
+[ 8358, "lij" ],
+[ 8359, "lik" ],
+[ 8360, "lil" ],
+[ 8361, "lim" ],
+[ 8362, "lin" ],
+[ 8363, "lio" ],
+[ 8364, "lip" ],
+[ 8365, "liq" ],
+[ 8366, "lir" ],
+[ 8367, "lis" ],
+[ 8368, "lit" ],
+[ 8369, "liu" ],
+[ 8370, "liv" ],
+[ 8371, "liw" ],
+[ 8372, "lix" ],
+[ 8373, "liy" ],
+[ 8374, "liz" ],
+[ 8375, "lja" ],
+[ 8376, "ljb" ],
+[ 8377, "ljc" ],
+[ 8378, "ljd" ],
+[ 8379, "lje" ],
+[ 8380, "ljf" ],
+[ 8381, "ljg" ],
+[ 8382, "ljh" ],
+[ 8383, "lji" ],
+[ 8384, "ljj" ],
+[ 8385, "ljk" ],
+[ 8386, "ljl" ],
+[ 8387, "ljm" ],
+[ 8388, "ljn" ],
+[ 8389, "ljo" ],
+[ 8390, "ljp" ],
+[ 8391, "ljq" ],
+[ 8392, "ljr" ],
+[ 8393, "ljs" ],
+[ 8394, "ljt" ],
+[ 8395, "lju" ],
+[ 8396, "ljv" ],
+[ 8397, "ljw" ],
+[ 8398, "ljx" ],
+[ 8399, "ljy" ],
+[ 8400, "ljz" ],
+[ 8401, "lka" ],
+[ 8402, "lkb" ],
+[ 8403, "lkc" ],
+[ 8404, "lkd" ],
+[ 8405, "lke" ],
+[ 8406, "lkf" ],
+[ 8407, "lkg" ],
+[ 8408, "lkh" ],
+[ 8409, "lki" ],
+[ 8410, "lkj" ],
+[ 8411, "lkk" ],
+[ 8412, "lkl" ],
+[ 8413, "lkm" ],
+[ 8414, "lkn" ],
+[ 8415, "lko" ],
+[ 8416, "lkp" ],
+[ 8417, "lkq" ],
+[ 8418, "lkr" ],
+[ 8419, "lks" ],
+[ 8420, "lkt" ],
+[ 8421, "lku" ],
+[ 8422, "lkv" ],
+[ 8423, "lkw" ],
+[ 8424, "lkx" ],
+[ 8425, "lky" ],
+[ 8426, "lkz" ],
+[ 8427, "lla" ],
+[ 8428, "llb" ],
+[ 8429, "llc" ],
+[ 8430, "lld" ],
+[ 8431, "lle" ],
+[ 8432, "llf" ],
+[ 8433, "llg" ],
+[ 8434, "llh" ],
+[ 8435, "lli" ],
+[ 8436, "llj" ],
+[ 8437, "llk" ],
+[ 8438, "lll" ],
+[ 8439, "llm" ],
+[ 8440, "lln" ],
+[ 8441, "llo" ],
+[ 8442, "llp" ],
+[ 8443, "llq" ],
+[ 8444, "llr" ],
+[ 8445, "lls" ],
+[ 8446, "llt" ],
+[ 8447, "llu" ],
+[ 8448, "llv" ],
+[ 8449, "llw" ],
+[ 8450, "llx" ],
+[ 8451, "lly" ],
+[ 8452, "llz" ],
+[ 8453, "lma" ],
+[ 8454, "lmb" ],
+[ 8455, "lmc" ],
+[ 8456, "lmd" ],
+[ 8457, "lme" ],
+[ 8458, "lmf" ],
+[ 8459, "lmg" ],
+[ 8460, "lmh" ],
+[ 8461, "lmi" ],
+[ 8462, "lmj" ],
+[ 8463, "lmk" ],
+[ 8464, "lml" ],
+[ 8465, "lmm" ],
+[ 8466, "lmn" ],
+[ 8467, "lmo" ],
+[ 8468, "lmp" ],
+[ 8469, "lmq" ],
+[ 8470, "lmr" ],
+[ 8471, "lms" ],
+[ 8472, "lmt" ],
+[ 8473, "lmu" ],
+[ 8474, "lmv" ],
+[ 8475, "lmw" ],
+[ 8476, "lmx" ],
+[ 8477, "lmy" ],
+[ 8478, "lmz" ],
+[ 8479, "lna" ],
+[ 8480, "lnb" ],
+[ 8481, "lnc" ],
+[ 8482, "lnd" ],
+[ 8483, "lne" ],
+[ 8484, "lnf" ],
+[ 8485, "lng" ],
+[ 8486, "lnh" ],
+[ 8487, "lni" ],
+[ 8488, "lnj" ],
+[ 8489, "lnk" ],
+[ 8490, "lnl" ],
+[ 8491, "lnm" ],
+[ 8492, "lnn" ],
+[ 8493, "lno" ],
+[ 8494, "lnp" ],
+[ 8495, "lnq" ],
+[ 8496, "lnr" ],
+[ 8497, "lns" ],
+[ 8498, "lnt" ],
+[ 8499, "lnu" ],
+[ 8500, "lnv" ],
+[ 8501, "lnw" ],
+[ 8502, "lnx" ],
+[ 8503, "lny" ],
+[ 8504, "lnz" ],
+[ 8505, "loa" ],
+[ 8506, "lob" ],
+[ 8507, "loc" ],
+[ 8508, "lod" ],
+[ 8509, "loe" ],
+[ 8510, "lof" ],
+[ 8511, "log" ],
+[ 8512, "loh" ],
+[ 8513, "loi" ],
+[ 8514, "loj" ],
+[ 8515, "lok" ],
+[ 8516, "lol" ],
+[ 8517, "lom" ],
+[ 8518, "lon" ],
+[ 8519, "loo" ],
+[ 8520, "lop" ],
+[ 8521, "loq" ],
+[ 8522, "lor" ],
+[ 8523, "los" ],
+[ 8524, "lot" ],
+[ 8525, "lou" ],
+[ 8526, "lov" ],
+[ 8527, "low" ],
+[ 8528, "lox" ],
+[ 8529, "loy" ],
+[ 8530, "loz" ],
+[ 8531, "lpa" ],
+[ 8532, "lpb" ],
+[ 8533, "lpc" ],
+[ 8534, "lpd" ],
+[ 8535, "lpe" ],
+[ 8536, "lpf" ],
+[ 8537, "lpg" ],
+[ 8538, "lph" ],
+[ 8539, "lpi" ],
+[ 8540, "lpj" ],
+[ 8541, "lpk" ],
+[ 8542, "lpl" ],
+[ 8543, "lpm" ],
+[ 8544, "lpn" ],
+[ 8545, "lpo" ],
+[ 8546, "lpp" ],
+[ 8547, "lpq" ],
+[ 8548, "lpr" ],
+[ 8549, "lps" ],
+[ 8550, "lpt" ],
+[ 8551, "lpu" ],
+[ 8552, "lpv" ],
+[ 8553, "lpw" ],
+[ 8554, "lpx" ],
+[ 8555, "lpy" ],
+[ 8556, "lpz" ],
+[ 8557, "lqa" ],
+[ 8558, "lqb" ],
+[ 8559, "lqc" ],
+[ 8560, "lqd" ],
+[ 8561, "lqe" ],
+[ 8562, "lqf" ],
+[ 8563, "lqg" ],
+[ 8564, "lqh" ],
+[ 8565, "lqi" ],
+[ 8566, "lqj" ],
+[ 8567, "lqk" ],
+[ 8568, "lql" ],
+[ 8569, "lqm" ],
+[ 8570, "lqn" ],
+[ 8571, "lqo" ],
+[ 8572, "lqp" ],
+[ 8573, "lqq" ],
+[ 8574, "lqr" ],
+[ 8575, "lqs" ],
+[ 8576, "lqt" ],
+[ 8577, "lqu" ],
+[ 8578, "lqv" ],
+[ 8579, "lqw" ],
+[ 8580, "lqx" ],
+[ 8581, "lqy" ],
+[ 8582, "lqz" ],
+[ 8583, "lra" ],
+[ 8584, "lrb" ],
+[ 8585, "lrc" ],
+[ 8586, "lrd" ],
+[ 8587, "lre" ],
+[ 8588, "lrf" ],
+[ 8589, "lrg" ],
+[ 8590, "lrh" ],
+[ 8591, "lri" ],
+[ 8592, "lrj" ],
+[ 8593, "lrk" ],
+[ 8594, "lrl" ],
+[ 8595, "lrm" ],
+[ 8596, "lrn" ],
+[ 8597, "lro" ],
+[ 8598, "lrp" ],
+[ 8599, "lrq" ],
+[ 8600, "lrr" ],
+[ 8601, "lrs" ],
+[ 8602, "lrt" ],
+[ 8603, "lru" ],
+[ 8604, "lrv" ],
+[ 8605, "lrw" ],
+[ 8606, "lrx" ],
+[ 8607, "lry" ],
+[ 8608, "lrz" ],
+[ 8609, "lsa" ],
+[ 8610, "lsb" ],
+[ 8611, "lsc" ],
+[ 8612, "lsd" ],
+[ 8613, "lse" ],
+[ 8614, "lsf" ],
+[ 8615, "lsg" ],
+[ 8616, "lsh" ],
+[ 8617, "lsi" ],
+[ 8618, "lsj" ],
+[ 8619, "lsk" ],
+[ 8620, "lsl" ],
+[ 8621, "lsm" ],
+[ 8622, "lsn" ],
+[ 8623, "lso" ],
+[ 8624, "lsp" ],
+[ 8625, "lsq" ],
+[ 8626, "lsr" ],
+[ 8627, "lss" ],
+[ 8628, "lst" ],
+[ 8629, "lsu" ],
+[ 8630, "lsv" ],
+[ 8631, "lsw" ],
+[ 8632, "lsx" ],
+[ 8633, "lsy" ],
+[ 8634, "lsz" ],
+[ 8635, "lta" ],
+[ 8636, "ltb" ],
+[ 8637, "ltc" ],
+[ 8638, "ltd" ],
+[ 8639, "lte" ],
+[ 8640, "ltf" ],
+[ 8641, "ltg" ],
+[ 8642, "lth" ],
+[ 8643, "lti" ],
+[ 8644, "ltj" ],
+[ 8645, "ltk" ],
+[ 8646, "ltl" ],
+[ 8647, "ltm" ],
+[ 8648, "ltn" ],
+[ 8649, "lto" ],
+[ 8650, "ltp" ],
+[ 8651, "ltq" ],
+[ 8652, "ltr" ],
+[ 8653, "lts" ],
+[ 8654, "ltt" ],
+[ 8655, "ltu" ],
+[ 8656, "ltv" ],
+[ 8657, "ltw" ],
+[ 8658, "ltx" ],
+[ 8659, "lty" ],
+[ 8660, "ltz" ],
+[ 8661, "lua" ],
+[ 8662, "lub" ],
+[ 8663, "luc" ],
+[ 8664, "lud" ],
+[ 8665, "lue" ],
+[ 8666, "luf" ],
+[ 8667, "lug" ],
+[ 8668, "luh" ],
+[ 8669, "lui" ],
+[ 8670, "luj" ],
+[ 8671, "luk" ],
+[ 8672, "lul" ],
+[ 8673, "lum" ],
+[ 8674, "lun" ],
+[ 8675, "luo" ],
+[ 8676, "lup" ],
+[ 8677, "luq" ],
+[ 8678, "lur" ],
+[ 8679, "lus" ],
+[ 8680, "lut" ],
+[ 8681, "luu" ],
+[ 8682, "luv" ],
+[ 8683, "luw" ],
+[ 8684, "lux" ],
+[ 8685, "luy" ],
+[ 8686, "luz" ],
+[ 8687, "lva" ],
+[ 8688, "lvb" ],
+[ 8689, "lvc" ],
+[ 8690, "lvd" ],
+[ 8691, "lve" ],
+[ 8692, "lvf" ],
+[ 8693, "lvg" ],
+[ 8694, "lvh" ],
+[ 8695, "lvi" ],
+[ 8696, "lvj" ],
+[ 8697, "lvk" ],
+[ 8698, "lvl" ],
+[ 8699, "lvm" ],
+[ 8700, "lvn" ],
+[ 8701, "lvo" ],
+[ 8702, "lvp" ],
+[ 8703, "lvq" ],
+[ 8704, "lvr" ],
+[ 8705, "lvs" ],
+[ 8706, "lvt" ],
+[ 8707, "lvu" ],
+[ 8708, "lvv" ],
+[ 8709, "lvw" ],
+[ 8710, "lvx" ],
+[ 8711, "lvy" ],
+[ 8712, "lvz" ],
+[ 8713, "lwa" ],
+[ 8714, "lwb" ],
+[ 8715, "lwc" ],
+[ 8716, "lwd" ],
+[ 8717, "lwe" ],
+[ 8718, "lwf" ],
+[ 8719, "lwg" ],
+[ 8720, "lwh" ],
+[ 8721, "lwi" ],
+[ 8722, "lwj" ],
+[ 8723, "lwk" ],
+[ 8724, "lwl" ],
+[ 8725, "lwm" ],
+[ 8726, "lwn" ],
+[ 8727, "lwo" ],
+[ 8728, "lwp" ],
+[ 8729, "lwq" ],
+[ 8730, "lwr" ],
+[ 8731, "lws" ],
+[ 8732, "lwt" ],
+[ 8733, "lwu" ],
+[ 8734, "lwv" ],
+[ 8735, "lww" ],
+[ 8736, "lwx" ],
+[ 8737, "lwy" ],
+[ 8738, "lwz" ],
+[ 8739, "lxa" ],
+[ 8740, "lxb" ],
+[ 8741, "lxc" ],
+[ 8742, "lxd" ],
+[ 8743, "lxe" ],
+[ 8744, "lxf" ],
+[ 8745, "lxg" ],
+[ 8746, "lxh" ],
+[ 8747, "lxi" ],
+[ 8748, "lxj" ],
+[ 8749, "lxk" ],
+[ 8750, "lxl" ],
+[ 8751, "lxm" ],
+[ 8752, "lxn" ],
+[ 8753, "lxo" ],
+[ 8754, "lxp" ],
+[ 8755, "lxq" ],
+[ 8756, "lxr" ],
+[ 8757, "lxs" ],
+[ 8758, "lxt" ],
+[ 8759, "lxu" ],
+[ 8760, "lxv" ],
+[ 8761, "lxw" ],
+[ 8762, "lxx" ],
+[ 8763, "lxy" ],
+[ 8764, "lxz" ],
+[ 8765, "lya" ],
+[ 8766, "lyb" ],
+[ 8767, "lyc" ],
+[ 8768, "lyd" ],
+[ 8769, "lye" ],
+[ 8770, "lyf" ],
+[ 8771, "lyg" ],
+[ 8772, "lyh" ],
+[ 8773, "lyi" ],
+[ 8774, "lyj" ],
+[ 8775, "lyk" ],
+[ 8776, "lyl" ],
+[ 8777, "lym" ],
+[ 8778, "lyn" ],
+[ 8779, "lyo" ],
+[ 8780, "lyp" ],
+[ 8781, "lyq" ],
+[ 8782, "lyr" ],
+[ 8783, "lys" ],
+[ 8784, "lyt" ],
+[ 8785, "lyu" ],
+[ 8786, "lyv" ],
+[ 8787, "lyw" ],
+[ 8788, "lyx" ],
+[ 8789, "lyy" ],
+[ 8790, "lyz" ],
+[ 8791, "lza" ],
+[ 8792, "lzb" ],
+[ 8793, "lzc" ],
+[ 8794, "lzd" ],
+[ 8795, "lze" ],
+[ 8796, "lzf" ],
+[ 8797, "lzg" ],
+[ 8798, "lzh" ],
+[ 8799, "lzi" ],
+[ 8800, "lzj" ],
+[ 8801, "lzk" ],
+[ 8802, "lzl" ],
+[ 8803, "lzm" ],
+[ 8804, "lzn" ],
+[ 8805, "lzo" ],
+[ 8806, "lzp" ],
+[ 8807, "lzq" ],
+[ 8808, "lzr" ],
+[ 8809, "lzs" ],
+[ 8810, "lzt" ],
+[ 8811, "lzu" ],
+[ 8812, "lzv" ],
+[ 8813, "lzw" ],
+[ 8814, "lzx" ],
+[ 8815, "lzy" ],
+[ 8816, "lzz" ],
+[ 8817, "maa" ],
+[ 8818, "mab" ],
+[ 8819, "mac" ],
+[ 8820, "mad" ],
+[ 8821, "mae" ],
+[ 8822, "maf" ],
+[ 8823, "mag" ],
+[ 8824, "mah" ],
+[ 8825, "mai" ],
+[ 8826, "maj" ],
+[ 8827, "mak" ],
+[ 8828, "mal" ],
+[ 8829, "mam" ],
+[ 8830, "man" ],
+[ 8831, "mao" ],
+[ 8832, "map" ],
+[ 8833, "maq" ],
+[ 8834, "mar" ],
+[ 8835, "mas" ],
+[ 8836, "mat" ],
+[ 8837, "mau" ],
+[ 8838, "mav" ],
+[ 8839, "maw" ],
+[ 8840, "max" ],
+[ 8841, "may" ],
+[ 8842, "maz" ],
+[ 8843, "mba" ],
+[ 8844, "mbb" ],
+[ 8845, "mbc" ],
+[ 8846, "mbd" ],
+[ 8847, "mbe" ],
+[ 8848, "mbf" ],
+[ 8849, "mbg" ],
+[ 8850, "mbh" ],
+[ 8851, "mbi" ],
+[ 8852, "mbj" ],
+[ 8853, "mbk" ],
+[ 8854, "mbl" ],
+[ 8855, "mbm" ],
+[ 8856, "mbn" ],
+[ 8857, "mbo" ],
+[ 8858, "mbp" ],
+[ 8859, "mbq" ],
+[ 8860, "mbr" ],
+[ 8861, "mbs" ],
+[ 8862, "mbt" ],
+[ 8863, "mbu" ],
+[ 8864, "mbv" ],
+[ 8865, "mbw" ],
+[ 8866, "mbx" ],
+[ 8867, "mby" ],
+[ 8868, "mbz" ],
+[ 8869, "mca" ],
+[ 8870, "mcb" ],
+[ 8871, "mcc" ],
+[ 8872, "mcd" ],
+[ 8873, "mce" ],
+[ 8874, "mcf" ],
+[ 8875, "mcg" ],
+[ 8876, "mch" ],
+[ 8877, "mci" ],
+[ 8878, "mcj" ],
+[ 8879, "mck" ],
+[ 8880, "mcl" ],
+[ 8881, "mcm" ],
+[ 8882, "mcn" ],
+[ 8883, "mco" ],
+[ 8884, "mcp" ],
+[ 8885, "mcq" ],
+[ 8886, "mcr" ],
+[ 8887, "mcs" ],
+[ 8888, "mct" ],
+[ 8889, "mcu" ],
+[ 8890, "mcv" ],
+[ 8891, "mcw" ],
+[ 8892, "mcx" ],
+[ 8893, "mcy" ],
+[ 8894, "mcz" ],
+[ 8895, "mda" ],
+[ 8896, "mdb" ],
+[ 8897, "mdc" ],
+[ 8898, "mdd" ],
+[ 8899, "mde" ],
+[ 8900, "mdf" ],
+[ 8901, "mdg" ],
+[ 8902, "mdh" ],
+[ 8903, "mdi" ],
+[ 8904, "mdj" ],
+[ 8905, "mdk" ],
+[ 8906, "mdl" ],
+[ 8907, "mdm" ],
+[ 8908, "mdn" ],
+[ 8909, "mdo" ],
+[ 8910, "mdp" ],
+[ 8911, "mdq" ],
+[ 8912, "mdr" ],
+[ 8913, "mds" ],
+[ 8914, "mdt" ],
+[ 8915, "mdu" ],
+[ 8916, "mdv" ],
+[ 8917, "mdw" ],
+[ 8918, "mdx" ],
+[ 8919, "mdy" ],
+[ 8920, "mdz" ],
+[ 8921, "mea" ],
+[ 8922, "meb" ],
+[ 8923, "mec" ],
+[ 8924, "med" ],
+[ 8925, "mee" ],
+[ 8926, "mef" ],
+[ 8927, "meg" ],
+[ 8928, "meh" ],
+[ 8929, "mei" ],
+[ 8930, "mej" ],
+[ 8931, "mek" ],
+[ 8932, "mel" ],
+[ 8933, "mem" ],
+[ 8934, "men" ],
+[ 8935, "meo" ],
+[ 8936, "mep" ],
+[ 8937, "meq" ],
+[ 8938, "mer" ],
+[ 8939, "mes" ],
+[ 8940, "met" ],
+[ 8941, "meu" ],
+[ 8942, "mev" ],
+[ 8943, "mew" ],
+[ 8944, "mex" ],
+[ 8945, "mey" ],
+[ 8946, "mez" ],
+[ 8947, "mfa" ],
+[ 8948, "mfb" ],
+[ 8949, "mfc" ],
+[ 8950, "mfd" ],
+[ 8951, "mfe" ],
+[ 8952, "mff" ],
+[ 8953, "mfg" ],
+[ 8954, "mfh" ],
+[ 8955, "mfi" ],
+[ 8956, "mfj" ],
+[ 8957, "mfk" ],
+[ 8958, "mfl" ],
+[ 8959, "mfm" ],
+[ 8960, "mfn" ],
+[ 8961, "mfo" ],
+[ 8962, "mfp" ],
+[ 8963, "mfq" ],
+[ 8964, "mfr" ],
+[ 8965, "mfs" ],
+[ 8966, "mft" ],
+[ 8967, "mfu" ],
+[ 8968, "mfv" ],
+[ 8969, "mfw" ],
+[ 8970, "mfx" ],
+[ 8971, "mfy" ],
+[ 8972, "mfz" ],
+[ 8973, "mga" ],
+[ 8974, "mgb" ],
+[ 8975, "mgc" ],
+[ 8976, "mgd" ],
+[ 8977, "mge" ],
+[ 8978, "mgf" ],
+[ 8979, "mgg" ],
+[ 8980, "mgh" ],
+[ 8981, "mgi" ],
+[ 8982, "mgj" ],
+[ 8983, "mgk" ],
+[ 8984, "mgl" ],
+[ 8985, "mgm" ],
+[ 8986, "mgn" ],
+[ 8987, "mgo" ],
+[ 8988, "mgp" ],
+[ 8989, "mgq" ],
+[ 8990, "mgr" ],
+[ 8991, "mgs" ],
+[ 8992, "mgt" ],
+[ 8993, "mgu" ],
+[ 8994, "mgv" ],
+[ 8995, "mgw" ],
+[ 8996, "mgx" ],
+[ 8997, "mgy" ],
+[ 8998, "mgz" ],
+[ 8999, "mha" ],
+[ 9000, "mhb" ],
+[ 9001, "mhc" ],
+[ 9002, "mhd" ],
+[ 9003, "mhe" ],
+[ 9004, "mhf" ],
+[ 9005, "mhg" ],
+[ 9006, "mhh" ],
+[ 9007, "mhi" ],
+[ 9008, "mhj" ],
+[ 9009, "mhk" ],
+[ 9010, "mhl" ],
+[ 9011, "mhm" ],
+[ 9012, "mhn" ],
+[ 9013, "mho" ],
+[ 9014, "mhp" ],
+[ 9015, "mhq" ],
+[ 9016, "mhr" ],
+[ 9017, "mhs" ],
+[ 9018, "mht" ],
+[ 9019, "mhu" ],
+[ 9020, "mhv" ],
+[ 9021, "mhw" ],
+[ 9022, "mhx" ],
+[ 9023, "mhy" ],
+[ 9024, "mhz" ],
+[ 9025, "mia" ],
+[ 9026, "mib" ],
+[ 9027, "mic" ],
+[ 9028, "mid" ],
+[ 9029, "mie" ],
+[ 9030, "mif" ],
+[ 9031, "mig" ],
+[ 9032, "mih" ],
+[ 9033, "mii" ],
+[ 9034, "mij" ],
+[ 9035, "mik" ],
+[ 9036, "mil" ],
+[ 9037, "mim" ],
+[ 9038, "min" ],
+[ 9039, "mio" ],
+[ 9040, "mip" ],
+[ 9041, "miq" ],
+[ 9042, "mir" ],
+[ 9043, "mis" ],
+[ 9044, "mit" ],
+[ 9045, "miu" ],
+[ 9046, "miv" ],
+[ 9047, "miw" ],
+[ 9048, "mix" ],
+[ 9049, "miy" ],
+[ 9050, "miz" ],
+[ 9051, "mja" ],
+[ 9052, "mjb" ],
+[ 9053, "mjc" ],
+[ 9054, "mjd" ],
+[ 9055, "mje" ],
+[ 9056, "mjf" ],
+[ 9057, "mjg" ],
+[ 9058, "mjh" ],
+[ 9059, "mji" ],
+[ 9060, "mjj" ],
+[ 9061, "mjk" ],
+[ 9062, "mjl" ],
+[ 9063, "mjm" ],
+[ 9064, "mjn" ],
+[ 9065, "mjo" ],
+[ 9066, "mjp" ],
+[ 9067, "mjq" ],
+[ 9068, "mjr" ],
+[ 9069, "mjs" ],
+[ 9070, "mjt" ],
+[ 9071, "mju" ],
+[ 9072, "mjv" ],
+[ 9073, "mjw" ],
+[ 9074, "mjx" ],
+[ 9075, "mjy" ],
+[ 9076, "mjz" ],
+[ 9077, "mka" ],
+[ 9078, "mkb" ],
+[ 9079, "mkc" ],
+[ 9080, "mkd" ],
+[ 9081, "mke" ],
+[ 9082, "mkf" ],
+[ 9083, "mkg" ],
+[ 9084, "mkh" ],
+[ 9085, "mki" ],
+[ 9086, "mkj" ],
+[ 9087, "mkk" ],
+[ 9088, "mkl" ],
+[ 9089, "mkm" ],
+[ 9090, "mkn" ],
+[ 9091, "mko" ],
+[ 9092, "mkp" ],
+[ 9093, "mkq" ],
+[ 9094, "mkr" ],
+[ 9095, "mks" ],
+[ 9096, "mkt" ],
+[ 9097, "mku" ],
+[ 9098, "mkv" ],
+[ 9099, "mkw" ],
+[ 9100, "mkx" ],
+[ 9101, "mky" ],
+[ 9102, "mkz" ],
+[ 9103, "mla" ],
+[ 9104, "mlb" ],
+[ 9105, "mlc" ],
+[ 9106, "mld" ],
+[ 9107, "mle" ],
+[ 9108, "mlf" ],
+[ 9109, "mlg" ],
+[ 9110, "mlh" ],
+[ 9111, "mli" ],
+[ 9112, "mlj" ],
+[ 9113, "mlk" ],
+[ 9114, "mll" ],
+[ 9115, "mlm" ],
+[ 9116, "mln" ],
+[ 9117, "mlo" ],
+[ 9118, "mlp" ],
+[ 9119, "mlq" ],
+[ 9120, "mlr" ],
+[ 9121, "mls" ],
+[ 9122, "mlt" ],
+[ 9123, "mlu" ],
+[ 9124, "mlv" ],
+[ 9125, "mlw" ],
+[ 9126, "mlx" ],
+[ 9127, "mly" ],
+[ 9128, "mlz" ],
+[ 9129, "mma" ],
+[ 9130, "mmb" ],
+[ 9131, "mmc" ],
+[ 9132, "mmd" ],
+[ 9133, "mme" ],
+[ 9134, "mmf" ],
+[ 9135, "mmg" ],
+[ 9136, "mmh" ],
+[ 9137, "mmi" ],
+[ 9138, "mmj" ],
+[ 9139, "mmk" ],
+[ 9140, "mml" ],
+[ 9141, "mmm" ],
+[ 9142, "mmn" ],
+[ 9143, "mmo" ],
+[ 9144, "mmp" ],
+[ 9145, "mmq" ],
+[ 9146, "mmr" ],
+[ 9147, "mms" ],
+[ 9148, "mmt" ],
+[ 9149, "mmu" ],
+[ 9150, "mmv" ],
+[ 9151, "mmw" ],
+[ 9152, "mmx" ],
+[ 9153, "mmy" ],
+[ 9154, "mmz" ],
+[ 9155, "mna" ],
+[ 9156, "mnb" ],
+[ 9157, "mnc" ],
+[ 9158, "mnd" ],
+[ 9159, "mne" ],
+[ 9160, "mnf" ],
+[ 9161, "mng" ],
+[ 9162, "mnh" ],
+[ 9163, "mni" ],
+[ 9164, "mnj" ],
+[ 9165, "mnk" ],
+[ 9166, "mnl" ],
+[ 9167, "mnm" ],
+[ 9168, "mnn" ],
+[ 9169, "mno" ],
+[ 9170, "mnp" ],
+[ 9171, "mnq" ],
+[ 9172, "mnr" ],
+[ 9173, "mns" ],
+[ 9174, "mnt" ],
+[ 9175, "mnu" ],
+[ 9176, "mnv" ],
+[ 9177, "mnw" ],
+[ 9178, "mnx" ],
+[ 9179, "mny" ],
+[ 9180, "mnz" ],
+[ 9181, "moa" ],
+[ 9182, "mob" ],
+[ 9183, "moc" ],
+[ 9184, "mod" ],
+[ 9185, "moe" ],
+[ 9186, "mof" ],
+[ 9187, "mog" ],
+[ 9188, "moh" ],
+[ 9189, "moi" ],
+[ 9190, "moj" ],
+[ 9191, "mok" ],
+[ 9192, "mol" ],
+[ 9193, "mom" ],
+[ 9194, "mon" ],
+[ 9195, "moo" ],
+[ 9196, "mop" ],
+[ 9197, "moq" ],
+[ 9198, "mor" ],
+[ 9199, "mos" ],
+[ 9200, "mot" ],
+[ 9201, "mou" ],
+[ 9202, "mov" ],
+[ 9203, "mow" ],
+[ 9204, "mox" ],
+[ 9205, "moy" ],
+[ 9206, "moz" ],
+[ 9207, "mpa" ],
+[ 9208, "mpb" ],
+[ 9209, "mpc" ],
+[ 9210, "mpd" ],
+[ 9211, "mpe" ],
+[ 9212, "mpf" ],
+[ 9213, "mpg" ],
+[ 9214, "mph" ],
+[ 9215, "mpi" ],
+[ 9216, "mpj" ],
+[ 9217, "mpk" ],
+[ 9218, "mpl" ],
+[ 9219, "mpm" ],
+[ 9220, "mpn" ],
+[ 9221, "mpo" ],
+[ 9222, "mpp" ],
+[ 9223, "mpq" ],
+[ 9224, "mpr" ],
+[ 9225, "mps" ],
+[ 9226, "mpt" ],
+[ 9227, "mpu" ],
+[ 9228, "mpv" ],
+[ 9229, "mpw" ],
+[ 9230, "mpx" ],
+[ 9231, "mpy" ],
+[ 9232, "mpz" ],
+[ 9233, "mqa" ],
+[ 9234, "mqb" ],
+[ 9235, "mqc" ],
+[ 9236, "mqd" ],
+[ 9237, "mqe" ],
+[ 9238, "mqf" ],
+[ 9239, "mqg" ],
+[ 9240, "mqh" ],
+[ 9241, "mqi" ],
+[ 9242, "mqj" ],
+[ 9243, "mqk" ],
+[ 9244, "mql" ],
+[ 9245, "mqm" ],
+[ 9246, "mqn" ],
+[ 9247, "mqo" ],
+[ 9248, "mqp" ],
+[ 9249, "mqq" ],
+[ 9250, "mqr" ],
+[ 9251, "mqs" ],
+[ 9252, "mqt" ],
+[ 9253, "mqu" ],
+[ 9254, "mqv" ],
+[ 9255, "mqw" ],
+[ 9256, "mqx" ],
+[ 9257, "mqy" ],
+[ 9258, "mqz" ],
+[ 9259, "mra" ],
+[ 9260, "mrb" ],
+[ 9261, "mrc" ],
+[ 9262, "mrd" ],
+[ 9263, "mre" ],
+[ 9264, "mrf" ],
+[ 9265, "mrg" ],
+[ 9266, "mrh" ],
+[ 9267, "mri" ],
+[ 9268, "mrj" ],
+[ 9269, "mrk" ],
+[ 9270, "mrl" ],
+[ 9271, "mrm" ],
+[ 9272, "mrn" ],
+[ 9273, "mro" ],
+[ 9274, "mrp" ],
+[ 9275, "mrq" ],
+[ 9276, "mrr" ],
+[ 9277, "mrs" ],
+[ 9278, "mrt" ],
+[ 9279, "mru" ],
+[ 9280, "mrv" ],
+[ 9281, "mrw" ],
+[ 9282, "mrx" ],
+[ 9283, "mry" ],
+[ 9284, "mrz" ],
+[ 9285, "msa" ],
+[ 9286, "msb" ],
+[ 9287, "msc" ],
+[ 9288, "msd" ],
+[ 9289, "mse" ],
+[ 9290, "msf" ],
+[ 9291, "msg" ],
+[ 9292, "msh" ],
+[ 9293, "msi" ],
+[ 9294, "msj" ],
+[ 9295, "msk" ],
+[ 9296, "msl" ],
+[ 9297, "msm" ],
+[ 9298, "msn" ],
+[ 9299, "mso" ],
+[ 9300, "msp" ],
+[ 9301, "msq" ],
+[ 9302, "msr" ],
+[ 9303, "mss" ],
+[ 9304, "mst" ],
+[ 9305, "msu" ],
+[ 9306, "msv" ],
+[ 9307, "msw" ],
+[ 9308, "msx" ],
+[ 9309, "msy" ],
+[ 9310, "msz" ],
+[ 9311, "mta" ],
+[ 9312, "mtb" ],
+[ 9313, "mtc" ],
+[ 9314, "mtd" ],
+[ 9315, "mte" ],
+[ 9316, "mtf" ],
+[ 9317, "mtg" ],
+[ 9318, "mth" ],
+[ 9319, "mti" ],
+[ 9320, "mtj" ],
+[ 9321, "mtk" ],
+[ 9322, "mtl" ],
+[ 9323, "mtm" ],
+[ 9324, "mtn" ],
+[ 9325, "mto" ],
+[ 9326, "mtp" ],
+[ 9327, "mtq" ],
+[ 9328, "mtr" ],
+[ 9329, "mts" ],
+[ 9330, "mtt" ],
+[ 9331, "mtu" ],
+[ 9332, "mtv" ],
+[ 9333, "mtw" ],
+[ 9334, "mtx" ],
+[ 9335, "mty" ],
+[ 9336, "mtz" ],
+[ 9337, "mua" ],
+[ 9338, "mub" ],
+[ 9339, "muc" ],
+[ 9340, "mud" ],
+[ 9341, "mue" ],
+[ 9342, "muf" ],
+[ 9343, "mug" ],
+[ 9344, "muh" ],
+[ 9345, "mui" ],
+[ 9346, "muj" ],
+[ 9347, "muk" ],
+[ 9348, "mul" ],
+[ 9349, "mum" ],
+[ 9350, "mun" ],
+[ 9351, "muo" ],
+[ 9352, "mup" ],
+[ 9353, "muq" ],
+[ 9354, "mur" ],
+[ 9355, "mus" ],
+[ 9356, "mut" ],
+[ 9357, "muu" ],
+[ 9358, "muv" ],
+[ 9359, "muw" ],
+[ 9360, "mux" ],
+[ 9361, "muy" ],
+[ 9362, "muz" ],
+[ 9363, "mva" ],
+[ 9364, "mvb" ],
+[ 9365, "mvc" ],
+[ 9366, "mvd" ],
+[ 9367, "mve" ],
+[ 9368, "mvf" ],
+[ 9369, "mvg" ],
+[ 9370, "mvh" ],
+[ 9371, "mvi" ],
+[ 9372, "mvj" ],
+[ 9373, "mvk" ],
+[ 9374, "mvl" ],
+[ 9375, "mvm" ],
+[ 9376, "mvn" ],
+[ 9377, "mvo" ],
+[ 9378, "mvp" ],
+[ 9379, "mvq" ],
+[ 9380, "mvr" ],
+[ 9381, "mvs" ],
+[ 9382, "mvt" ],
+[ 9383, "mvu" ],
+[ 9384, "mvv" ],
+[ 9385, "mvw" ],
+[ 9386, "mvx" ],
+[ 9387, "mvy" ],
+[ 9388, "mvz" ],
+[ 9389, "mwa" ],
+[ 9390, "mwb" ],
+[ 9391, "mwc" ],
+[ 9392, "mwd" ],
+[ 9393, "mwe" ],
+[ 9394, "mwf" ],
+[ 9395, "mwg" ],
+[ 9396, "mwh" ],
+[ 9397, "mwi" ],
+[ 9398, "mwj" ],
+[ 9399, "mwk" ],
+[ 9400, "mwl" ],
+[ 9401, "mwm" ],
+[ 9402, "mwn" ],
+[ 9403, "mwo" ],
+[ 9404, "mwp" ],
+[ 9405, "mwq" ],
+[ 9406, "mwr" ],
+[ 9407, "mws" ],
+[ 9408, "mwt" ],
+[ 9409, "mwu" ],
+[ 9410, "mwv" ],
+[ 9411, "mww" ],
+[ 9412, "mwx" ],
+[ 9413, "mwy" ],
+[ 9414, "mwz" ],
+[ 9415, "mxa" ],
+[ 9416, "mxb" ],
+[ 9417, "mxc" ],
+[ 9418, "mxd" ],
+[ 9419, "mxe" ],
+[ 9420, "mxf" ],
+[ 9421, "mxg" ],
+[ 9422, "mxh" ],
+[ 9423, "mxi" ],
+[ 9424, "mxj" ],
+[ 9425, "mxk" ],
+[ 9426, "mxl" ],
+[ 9427, "mxm" ],
+[ 9428, "mxn" ],
+[ 9429, "mxo" ],
+[ 9430, "mxp" ],
+[ 9431, "mxq" ],
+[ 9432, "mxr" ],
+[ 9433, "mxs" ],
+[ 9434, "mxt" ],
+[ 9435, "mxu" ],
+[ 9436, "mxv" ],
+[ 9437, "mxw" ],
+[ 9438, "mxx" ],
+[ 9439, "mxy" ],
+[ 9440, "mxz" ],
+[ 9441, "mya" ],
+[ 9442, "myb" ],
+[ 9443, "myc" ],
+[ 9444, "myd" ],
+[ 9445, "mye" ],
+[ 9446, "myf" ],
+[ 9447, "myg" ],
+[ 9448, "myh" ],
+[ 9449, "myi" ],
+[ 9450, "myj" ],
+[ 9451, "myk" ],
+[ 9452, "myl" ],
+[ 9453, "mym" ],
+[ 9454, "myn" ],
+[ 9455, "myo" ],
+[ 9456, "myp" ],
+[ 9457, "myq" ],
+[ 9458, "myr" ],
+[ 9459, "mys" ],
+[ 9460, "myt" ],
+[ 9461, "myu" ],
+[ 9462, "myv" ],
+[ 9463, "myw" ],
+[ 9464, "myx" ],
+[ 9465, "myy" ],
+[ 9466, "myz" ],
+[ 9467, "mza" ],
+[ 9468, "mzb" ],
+[ 9469, "mzc" ],
+[ 9470, "mzd" ],
+[ 9471, "mze" ],
+[ 9472, "mzf" ],
+[ 9473, "mzg" ],
+[ 9474, "mzh" ],
+[ 9475, "mzi" ],
+[ 9476, "mzj" ],
+[ 9477, "mzk" ],
+[ 9478, "mzl" ],
+[ 9479, "mzm" ],
+[ 9480, "mzn" ],
+[ 9481, "mzo" ],
+[ 9482, "mzp" ],
+[ 9483, "mzq" ],
+[ 9484, "mzr" ],
+[ 9485, "mzs" ],
+[ 9486, "mzt" ],
+[ 9487, "mzu" ],
+[ 9488, "mzv" ],
+[ 9489, "mzw" ],
+[ 9490, "mzx" ],
+[ 9491, "mzy" ],
+[ 9492, "mzz" ],
+[ 9493, "naa" ],
+[ 9494, "nab" ],
+[ 9495, "nac" ],
+[ 9496, "nad" ],
+[ 9497, "nae" ],
+[ 9498, "naf" ],
+[ 9499, "nag" ],
+[ 9500, "nah" ],
+[ 9501, "nai" ],
+[ 9502, "naj" ],
+[ 9503, "nak" ],
+[ 9504, "nal" ],
+[ 9505, "nam" ],
+[ 9506, "nan" ],
+[ 9507, "nao" ],
+[ 9508, "nap" ],
+[ 9509, "naq" ],
+[ 9510, "nar" ],
+[ 9511, "nas" ],
+[ 9512, "nat" ],
+[ 9513, "nau" ],
+[ 9514, "nav" ],
+[ 9515, "naw" ],
+[ 9516, "nax" ],
+[ 9517, "nay" ],
+[ 9518, "naz" ],
+[ 9519, "nba" ],
+[ 9520, "nbb" ],
+[ 9521, "nbc" ],
+[ 9522, "nbd" ],
+[ 9523, "nbe" ],
+[ 9524, "nbf" ],
+[ 9525, "nbg" ],
+[ 9526, "nbh" ],
+[ 9527, "nbi" ],
+[ 9528, "nbj" ],
+[ 9529, "nbk" ],
+[ 9530, "nbl" ],
+[ 9531, "nbm" ],
+[ 9532, "nbn" ],
+[ 9533, "nbo" ],
+[ 9534, "nbp" ],
+[ 9535, "nbq" ],
+[ 9536, "nbr" ],
+[ 9537, "nbs" ],
+[ 9538, "nbt" ],
+[ 9539, "nbu" ],
+[ 9540, "nbv" ],
+[ 9541, "nbw" ],
+[ 9542, "nbx" ],
+[ 9543, "nby" ],
+[ 9544, "nbz" ],
+[ 9545, "nca" ],
+[ 9546, "ncb" ],
+[ 9547, "ncc" ],
+[ 9548, "ncd" ],
+[ 9549, "nce" ],
+[ 9550, "ncf" ],
+[ 9551, "ncg" ],
+[ 9552, "nch" ],
+[ 9553, "nci" ],
+[ 9554, "ncj" ],
+[ 9555, "nck" ],
+[ 9556, "ncl" ],
+[ 9557, "ncm" ],
+[ 9558, "ncn" ],
+[ 9559, "nco" ],
+[ 9560, "ncp" ],
+[ 9561, "ncq" ],
+[ 9562, "ncr" ],
+[ 9563, "ncs" ],
+[ 9564, "nct" ],
+[ 9565, "ncu" ],
+[ 9566, "ncv" ],
+[ 9567, "ncw" ],
+[ 9568, "ncx" ],
+[ 9569, "ncy" ],
+[ 9570, "ncz" ],
+[ 9571, "nda" ],
+[ 9572, "ndb" ],
+[ 9573, "ndc" ],
+[ 9574, "ndd" ],
+[ 9575, "nde" ],
+[ 9576, "ndf" ],
+[ 9577, "ndg" ],
+[ 9578, "ndh" ],
+[ 9579, "ndi" ],
+[ 9580, "ndj" ],
+[ 9581, "ndk" ],
+[ 9582, "ndl" ],
+[ 9583, "ndm" ],
+[ 9584, "ndn" ],
+[ 9585, "ndo" ],
+[ 9586, "ndp" ],
+[ 9587, "ndq" ],
+[ 9588, "ndr" ],
+[ 9589, "nds" ],
+[ 9590, "ndt" ],
+[ 9591, "ndu" ],
+[ 9592, "ndv" ],
+[ 9593, "ndw" ],
+[ 9594, "ndx" ],
+[ 9595, "ndy" ],
+[ 9596, "ndz" ],
+[ 9597, "nea" ],
+[ 9598, "neb" ],
+[ 9599, "nec" ],
+[ 9600, "ned" ],
+[ 9601, "nee" ],
+[ 9602, "nef" ],
+[ 9603, "neg" ],
+[ 9604, "neh" ],
+[ 9605, "nei" ],
+[ 9606, "nej" ],
+[ 9607, "nek" ],
+[ 9608, "nel" ],
+[ 9609, "nem" ],
+[ 9610, "nen" ],
+[ 9611, "neo" ],
+[ 9612, "nep" ],
+[ 9613, "neq" ],
+[ 9614, "ner" ],
+[ 9615, "nes" ],
+[ 9616, "net" ],
+[ 9617, "neu" ],
+[ 9618, "nev" ],
+[ 9619, "new" ],
+[ 9620, "nex" ],
+[ 9621, "ney" ],
+[ 9622, "nez" ],
+[ 9623, "nfa" ],
+[ 9624, "nfb" ],
+[ 9625, "nfc" ],
+[ 9626, "nfd" ],
+[ 9627, "nfe" ],
+[ 9628, "nff" ],
+[ 9629, "nfg" ],
+[ 9630, "nfh" ],
+[ 9631, "nfi" ],
+[ 9632, "nfj" ],
+[ 9633, "nfk" ],
+[ 9634, "nfl" ],
+[ 9635, "nfm" ],
+[ 9636, "nfn" ],
+[ 9637, "nfo" ],
+[ 9638, "nfp" ],
+[ 9639, "nfq" ],
+[ 9640, "nfr" ],
+[ 9641, "nfs" ],
+[ 9642, "nft" ],
+[ 9643, "nfu" ],
+[ 9644, "nfv" ],
+[ 9645, "nfw" ],
+[ 9646, "nfx" ],
+[ 9647, "nfy" ],
+[ 9648, "nfz" ],
+[ 9649, "nga" ],
+[ 9650, "ngb" ],
+[ 9651, "ngc" ],
+[ 9652, "ngd" ],
+[ 9653, "nge" ],
+[ 9654, "ngf" ],
+[ 9655, "ngg" ],
+[ 9656, "ngh" ],
+[ 9657, "ngi" ],
+[ 9658, "ngj" ],
+[ 9659, "ngk" ],
+[ 9660, "ngl" ],
+[ 9661, "ngm" ],
+[ 9662, "ngn" ],
+[ 9663, "ngo" ],
+[ 9664, "ngp" ],
+[ 9665, "ngq" ],
+[ 9666, "ngr" ],
+[ 9667, "ngs" ],
+[ 9668, "ngt" ],
+[ 9669, "ngu" ],
+[ 9670, "ngv" ],
+[ 9671, "ngw" ],
+[ 9672, "ngx" ],
+[ 9673, "ngy" ],
+[ 9674, "ngz" ],
+[ 9675, "nha" ],
+[ 9676, "nhb" ],
+[ 9677, "nhc" ],
+[ 9678, "nhd" ],
+[ 9679, "nhe" ],
+[ 9680, "nhf" ],
+[ 9681, "nhg" ],
+[ 9682, "nhh" ],
+[ 9683, "nhi" ],
+[ 9684, "nhj" ],
+[ 9685, "nhk" ],
+[ 9686, "nhl" ],
+[ 9687, "nhm" ],
+[ 9688, "nhn" ],
+[ 9689, "nho" ],
+[ 9690, "nhp" ],
+[ 9691, "nhq" ],
+[ 9692, "nhr" ],
+[ 9693, "nhs" ],
+[ 9694, "nht" ],
+[ 9695, "nhu" ],
+[ 9696, "nhv" ],
+[ 9697, "nhw" ],
+[ 9698, "nhx" ],
+[ 9699, "nhy" ],
+[ 9700, "nhz" ],
+[ 9701, "nia" ],
+[ 9702, "nib" ],
+[ 9703, "nic" ],
+[ 9704, "nid" ],
+[ 9705, "nie" ],
+[ 9706, "nif" ],
+[ 9707, "nig" ],
+[ 9708, "nih" ],
+[ 9709, "nii" ],
+[ 9710, "nij" ],
+[ 9711, "nik" ],
+[ 9712, "nil" ],
+[ 9713, "nim" ],
+[ 9714, "nin" ],
+[ 9715, "nio" ],
+[ 9716, "nip" ],
+[ 9717, "niq" ],
+[ 9718, "nir" ],
+[ 9719, "nis" ],
+[ 9720, "nit" ],
+[ 9721, "niu" ],
+[ 9722, "niv" ],
+[ 9723, "niw" ],
+[ 9724, "nix" ],
+[ 9725, "niy" ],
+[ 9726, "niz" ],
+[ 9727, "nja" ],
+[ 9728, "njb" ],
+[ 9729, "njc" ],
+[ 9730, "njd" ],
+[ 9731, "nje" ],
+[ 9732, "njf" ],
+[ 9733, "njg" ],
+[ 9734, "njh" ],
+[ 9735, "nji" ],
+[ 9736, "njj" ],
+[ 9737, "njk" ],
+[ 9738, "njl" ],
+[ 9739, "njm" ],
+[ 9740, "njn" ],
+[ 9741, "njo" ],
+[ 9742, "njp" ],
+[ 9743, "njq" ],
+[ 9744, "njr" ],
+[ 9745, "njs" ],
+[ 9746, "njt" ],
+[ 9747, "nju" ],
+[ 9748, "njv" ],
+[ 9749, "njw" ],
+[ 9750, "njx" ],
+[ 9751, "njy" ],
+[ 9752, "njz" ],
+[ 9753, "nka" ],
+[ 9754, "nkb" ],
+[ 9755, "nkc" ],
+[ 9756, "nkd" ],
+[ 9757, "nke" ],
+[ 9758, "nkf" ],
+[ 9759, "nkg" ],
+[ 9760, "nkh" ],
+[ 9761, "nki" ],
+[ 9762, "nkj" ],
+[ 9763, "nkk" ],
+[ 9764, "nkl" ],
+[ 9765, "nkm" ],
+[ 9766, "nkn" ],
+[ 9767, "nko" ],
+[ 9768, "nkp" ],
+[ 9769, "nkq" ],
+[ 9770, "nkr" ],
+[ 9771, "nks" ],
+[ 9772, "nkt" ],
+[ 9773, "nku" ],
+[ 9774, "nkv" ],
+[ 9775, "nkw" ],
+[ 9776, "nkx" ],
+[ 9777, "nky" ],
+[ 9778, "nkz" ],
+[ 9779, "nla" ],
+[ 9780, "nlb" ],
+[ 9781, "nlc" ],
+[ 9782, "nld" ],
+[ 9783, "nle" ],
+[ 9784, "nlf" ],
+[ 9785, "nlg" ],
+[ 9786, "nlh" ],
+[ 9787, "nli" ],
+[ 9788, "nlj" ],
+[ 9789, "nlk" ],
+[ 9790, "nll" ],
+[ 9791, "nlm" ],
+[ 9792, "nln" ],
+[ 9793, "nlo" ],
+[ 9794, "nlp" ],
+[ 9795, "nlq" ],
+[ 9796, "nlr" ],
+[ 9797, "nls" ],
+[ 9798, "nlt" ],
+[ 9799, "nlu" ],
+[ 9800, "nlv" ],
+[ 9801, "nlw" ],
+[ 9802, "nlx" ],
+[ 9803, "nly" ],
+[ 9804, "nlz" ],
+[ 9805, "nma" ],
+[ 9806, "nmb" ],
+[ 9807, "nmc" ],
+[ 9808, "nmd" ],
+[ 9809, "nme" ],
+[ 9810, "nmf" ],
+[ 9811, "nmg" ],
+[ 9812, "nmh" ],
+[ 9813, "nmi" ],
+[ 9814, "nmj" ],
+[ 9815, "nmk" ],
+[ 9816, "nml" ],
+[ 9817, "nmm" ],
+[ 9818, "nmn" ],
+[ 9819, "nmo" ],
+[ 9820, "nmp" ],
+[ 9821, "nmq" ],
+[ 9822, "nmr" ],
+[ 9823, "nms" ],
+[ 9824, "nmt" ],
+[ 9825, "nmu" ],
+[ 9826, "nmv" ],
+[ 9827, "nmw" ],
+[ 9828, "nmx" ],
+[ 9829, "nmy" ],
+[ 9830, "nmz" ],
+[ 9831, "nna" ],
+[ 9832, "nnb" ],
+[ 9833, "nnc" ],
+[ 9834, "nnd" ],
+[ 9835, "nne" ],
+[ 9836, "nnf" ],
+[ 9837, "nng" ],
+[ 9838, "nnh" ],
+[ 9839, "nni" ],
+[ 9840, "nnj" ],
+[ 9841, "nnk" ],
+[ 9842, "nnl" ],
+[ 9843, "nnm" ],
+[ 9844, "nnn" ],
+[ 9845, "nno" ],
+[ 9846, "nnp" ],
+[ 9847, "nnq" ],
+[ 9848, "nnr" ],
+[ 9849, "nns" ],
+[ 9850, "nnt" ],
+[ 9851, "nnu" ],
+[ 9852, "nnv" ],
+[ 9853, "nnw" ],
+[ 9854, "nnx" ],
+[ 9855, "nny" ],
+[ 9856, "nnz" ],
+[ 9857, "noa" ],
+[ 9858, "nob" ],
+[ 9859, "noc" ],
+[ 9860, "nod" ],
+[ 9861, "noe" ],
+[ 9862, "nof" ],
+[ 9863, "nog" ],
+[ 9864, "noh" ],
+[ 9865, "noi" ],
+[ 9866, "noj" ],
+[ 9867, "nok" ],
+[ 9868, "nol" ],
+[ 9869, "nom" ],
+[ 9870, "non" ],
+[ 9871, "noo" ],
+[ 9872, "nop" ],
+[ 9873, "noq" ],
+[ 9874, "nor" ],
+[ 9875, "nos" ],
+[ 9876, "not" ],
+[ 9877, "nou" ],
+[ 9878, "nov" ],
+[ 9879, "now" ],
+[ 9880, "nox" ],
+[ 9881, "noy" ],
+[ 9882, "noz" ],
+[ 9883, "npa" ],
+[ 9884, "npb" ],
+[ 9885, "npc" ],
+[ 9886, "npd" ],
+[ 9887, "npe" ],
+[ 9888, "npf" ],
+[ 9889, "npg" ],
+[ 9890, "nph" ],
+[ 9891, "npi" ],
+[ 9892, "npj" ],
+[ 9893, "npk" ],
+[ 9894, "npl" ],
+[ 9895, "npm" ],
+[ 9896, "npn" ],
+[ 9897, "npo" ],
+[ 9898, "npp" ],
+[ 9899, "npq" ],
+[ 9900, "npr" ],
+[ 9901, "nps" ],
+[ 9902, "npt" ],
+[ 9903, "npu" ],
+[ 9904, "npv" ],
+[ 9905, "npw" ],
+[ 9906, "npx" ],
+[ 9907, "npy" ],
+[ 9908, "npz" ],
+[ 9909, "nqa" ],
+[ 9910, "nqb" ],
+[ 9911, "nqc" ],
+[ 9912, "nqd" ],
+[ 9913, "nqe" ],
+[ 9914, "nqf" ],
+[ 9915, "nqg" ],
+[ 9916, "nqh" ],
+[ 9917, "nqi" ],
+[ 9918, "nqj" ],
+[ 9919, "nqk" ],
+[ 9920, "nql" ],
+[ 9921, "nqm" ],
+[ 9922, "nqn" ],
+[ 9923, "nqo" ],
+[ 9924, "nqp" ],
+[ 9925, "nqq" ],
+[ 9926, "nqr" ],
+[ 9927, "nqs" ],
+[ 9928, "nqt" ],
+[ 9929, "nqu" ],
+[ 9930, "nqv" ],
+[ 9931, "nqw" ],
+[ 9932, "nqx" ],
+[ 9933, "nqy" ],
+[ 9934, "nqz" ],
+[ 9935, "nra" ],
+[ 9936, "nrb" ],
+[ 9937, "nrc" ],
+[ 9938, "nrd" ],
+[ 9939, "nre" ],
+[ 9940, "nrf" ],
+[ 9941, "nrg" ],
+[ 9942, "nrh" ],
+[ 9943, "nri" ],
+[ 9944, "nrj" ],
+[ 9945, "nrk" ],
+[ 9946, "nrl" ],
+[ 9947, "nrm" ],
+[ 9948, "nrn" ],
+[ 9949, "nro" ],
+[ 9950, "nrp" ],
+[ 9951, "nrq" ],
+[ 9952, "nrr" ],
+[ 9953, "nrs" ],
+[ 9954, "nrt" ],
+[ 9955, "nru" ],
+[ 9956, "nrv" ],
+[ 9957, "nrw" ],
+[ 9958, "nrx" ],
+[ 9959, "nry" ],
+[ 9960, "nrz" ],
+[ 9961, "nsa" ],
+[ 9962, "nsb" ],
+[ 9963, "nsc" ],
+[ 9964, "nsd" ],
+[ 9965, "nse" ],
+[ 9966, "nsf" ],
+[ 9967, "nsg" ],
+[ 9968, "nsh" ],
+[ 9969, "nsi" ],
+[ 9970, "nsj" ],
+[ 9971, "nsk" ],
+[ 9972, "nsl" ],
+[ 9973, "nsm" ],
+[ 9974, "nsn" ],
+[ 9975, "nso" ],
+[ 9976, "nsp" ],
+[ 9977, "nsq" ],
+[ 9978, "nsr" ],
+[ 9979, "nss" ],
+[ 9980, "nst" ],
+[ 9981, "nsu" ],
+[ 9982, "nsv" ],
+[ 9983, "nsw" ],
+[ 9984, "nsx" ],
+[ 9985, "nsy" ],
+[ 9986, "nsz" ],
+[ 9987, "nta" ],
+[ 9988, "ntb" ],
+[ 9989, "ntc" ],
+[ 9990, "ntd" ],
+[ 9991, "nte" ],
+[ 9992, "ntf" ],
+[ 9993, "ntg" ],
+[ 9994, "nth" ],
+[ 9995, "nti" ],
+[ 9996, "ntj" ],
+[ 9997, "ntk" ],
+[ 9998, "ntl" ],
+[ 9999, "ntm" ],
+[ 10000, "ntn" ],
+    ]);
+
+
+## make sure populate honors fields/orders in list context
+## schema order
+my @links = $schema->populate('Link', [
+[ qw/id url title/ ],
+[ qw/2 burl btitle/ ]
+]);
+is(scalar @links, 1);
+
+my $link2 = shift @links;
+is($link2->id, 2, 'Link 2 id');
+is($link2->url, 'burl', 'Link 2 url');
+is($link2->title, 'btitle', 'Link 2 title');
+
+## non-schema order
+@links = $schema->populate('Link', [
+[ qw/id title url/ ],
+[ qw/3 ctitle curl/ ]
+]);
+is(scalar @links, 1);
+
+my $link3 = shift @links;
+is($link3->id, 3, 'Link 3 id');
+is($link3->url, 'curl', 'Link 3 url');
+is($link3->title, 'ctitle', 'Link 3 title');
+
+## not all physical columns
+@links = $schema->populate('Link', [
+[ qw/id title/ ],
+[ qw/4 dtitle/ ]
+]);
+is(scalar @links, 1);
+
+my $link4 = shift @links;
+is($link4->id, 4, 'Link 4 id');
+is($link4->url, undef, 'Link 4 url');
+is($link4->title, 'dtitle', 'Link 4 title');
+
+
+## make sure populate -> insert_bulk honors fields/orders in void context
+## schema order
+$schema->populate('Link', [
+[ qw/id url title/ ],
+[ qw/5 eurl etitle/ ]
+]);
+my $link5 = $schema->resultset('Link')->find(5);
+is($link5->id, 5, 'Link 5 id');
+is($link5->url, 'eurl', 'Link 5 url');
+is($link5->title, 'etitle', 'Link 5 title');
+
+## non-schema order
+$schema->populate('Link', [
+[ qw/id title url/ ],
+[ qw/6 ftitle furl/ ]
+]);
+my $link6 = $schema->resultset('Link')->find(6);
+is($link6->id, 6, 'Link 6 id');
+is($link6->url, 'furl', 'Link 6 url');
+is($link6->title, 'ftitle', 'Link 6 title');
+
+## not all physical columns
+$schema->populate('Link', [
+[ qw/id title/ ],
+[ qw/7 gtitle/ ]
+]);
+my $link7 = $schema->resultset('Link')->find(7);
+is($link7->id, 7, 'Link 7 id');
+is($link7->url, undef, 'Link 7 url');
+is($link7->title, 'gtitle', 'Link 7 title');
+
+
+ok(-f "t/var/DBIxClass.db", 'Database created');
index 83fcf9d..646131b 100644 (file)
@@ -14,47 +14,58 @@ BEGIN {
 use lib qw(t/lib);
 
 use_ok('DBICTest');
-DBICTest->init_schema();
+my $schema = DBICTest->init_schema();
 
-DBICTest->schema->storage->sql_maker->quote_char('`');
-DBICTest->schema->storage->sql_maker->name_sep('.');
+my $orig_debugcb = $schema->storage->debugcb;
+my $orig_debug = $schema->storage->debug;
 
-my $rs = DBICTest::CD->search(
-           { 'me.year' => 2001, 'artist.name' => 'Caterwauler McCrae' },
-           { join => 'artist' });
+diag('Testing against ' . join(' ', map { $schema->storage->dbh->get_info($_) } qw/17 18/));
 
-cmp_ok( $rs->count, '==', 1, "join with fields quoted");
+$schema->storage->sql_maker->quote_char('`');
+$schema->storage->sql_maker->name_sep('.');
 
-$rs = DBICTest::CD->search({},
-            { 'order_by' => 'year DESC'});
-{
-       eval{ $rs->first() };
-       like( $@, qr/no such column: year DESC/, "Problem with ORDER BY quotes" );
-}
+my $sql = '';
+
+$schema->storage->debugcb(sub { $sql = $_[1] });
+$schema->storage->debug(1);
+
+my $rs;
+
+$rs = $schema->resultset('CD')->search(
+           { 'me.year' => 2001, 'artist.name' => 'Caterwauler McCrae' },
+           { join => 'artist' });
+eval { $rs->count };
+like($sql, qr/\QSELECT COUNT( * ) FROM `cd` `me`  JOIN `artist` `artist` ON ( `artist`.`artistid` = `me`.`artist` ) WHERE ( `artist`.`name` = ? AND `me`.`year` = ? )\E/, 'got correct SQL for count query with quoting');
 
 my $order = 'year DESC';
-$rs = DBICTest::CD->search({},
+$rs = $schema->resultset('CD')->search({},
+            { 'order_by' => $order });
+eval { $rs->first };
+like($sql, qr/ORDER BY `\Q${order}\E`/, 'quoted ORDER BY with DESC (should use a scalarref anyway)');
+
+$rs = $schema->resultset('CD')->search({},
             { 'order_by' => \$order });
-{
-       eval { $rs->first() };
-       ok(!$@, "No problem handling ORDER by scalaref" );
-}
+eval { $rs->first };
+like($sql, qr/ORDER BY \Q${order}\E/, 'did not quote ORDER BY with scalarref');
 
-DBICTest->schema->storage->sql_maker->quote_char([qw/[ ]/]);
-DBICTest->schema->storage->sql_maker->name_sep('.');
+$schema->storage->sql_maker->quote_char([qw/[ ]/]);
+$schema->storage->sql_maker->name_sep('.');
 
-$rs = DBICTest::CD->search(
+$rs = $schema->resultset('CD')->search(
            { 'me.year' => 2001, 'artist.name' => 'Caterwauler McCrae' },
            { join => 'artist' });
-cmp_ok($rs->count,'==', 1,"join quoted with brackets.");
+eval { $rs->count };
+like($sql, qr/\QSELECT COUNT( * ) FROM [cd] [me]  JOIN [artist] [artist] ON ( [artist].[artistid] = [me].[artist] ) WHERE ( [artist].[name] = ? AND [me].[year] = ? )\E/, 'got correct SQL for count query with bracket quoting');
 
 my %data = (
        name => 'Bill',
        order => '12'
 );
 
-DBICTest->schema->storage->sql_maker->quote_char('`');
-DBICTest->schema->storage->sql_maker->name_sep('.');
+$schema->storage->sql_maker->quote_char('`');
+$schema->storage->sql_maker->name_sep('.');
 
-cmp_ok(DBICTest->schema->storage->sql_maker->update('group', \%data), 'eq', 'UPDATE `group` SET `name` = ?, `order` = ?', "quoted table names for UPDATE");
+is($schema->storage->sql_maker->update('group', \%data), 'UPDATE `group` SET `name` = ?, `order` = ?', 'quoted table names for UPDATE');
 
+$schema->storage->debugcb($orig_debugcb);
+$schema->storage->debug($orig_debug);
index d2c40e0..b9d7411 100644 (file)
@@ -14,46 +14,57 @@ BEGIN {
 use lib qw(t/lib);
 
 use_ok('DBICTest');
-DBICTest->init_schema();
+my $schema = DBICTest->init_schema();
 
-my $dsn = DBICTest->schema->storage->connect_info->[0];
+my $orig_debugcb = $schema->storage->debugcb;
+my $orig_debug = $schema->storage->debug;
 
-DBICTest->schema->connection($dsn, { quote_char => '`', name_sep => '.' });
+diag('Testing against ' . join(' ', map { $schema->storage->dbh->get_info($_) } qw/17 18/));
 
-my $rs = DBICTest::CD->search(
-           { 'me.year' => 2001, 'artist.name' => 'Caterwauler McCrae' },
-           { join => 'artist' });
+my $dsn = $schema->storage->connect_info->[0];
+$schema->connection($dsn, { quote_char => '`', name_sep => '.' });
 
-cmp_ok( $rs->count, '==', 1, "join with fields quoted");
+my $sql = '';
+$schema->storage->debugcb(sub { $sql = $_[1] });
+$schema->storage->debug(1);
 
-$rs = DBICTest::CD->search({},
-            { 'order_by' => 'year DESC'});
-{
-       eval { $rs->first() };
-       like( $@, qr/no such column: year DESC/, "Problem with ORDER BY quotes" );
-}
+my $rs;
+
+$rs = $schema->resultset('CD')->search(
+           { 'me.year' => 2001, 'artist.name' => 'Caterwauler McCrae' },
+           { join => 'artist' });
+eval { $rs->count };
+like($sql, qr/\QSELECT COUNT( * ) FROM `cd` `me`  JOIN `artist` `artist` ON ( `artist`.`artistid` = `me`.`artist` ) WHERE ( `artist`.`name` = ? AND `me`.`year` = ? )\E/, 'got correct SQL for count query with quoting');
 
 my $order = 'year DESC';
-$rs = DBICTest::CD->search({},
+$rs = $schema->resultset('CD')->search({},
+            { 'order_by' => $order });
+eval { $rs->first };
+like($sql, qr/ORDER BY `\Q${order}\E`/, 'quoted ORDER BY with DESC (should use a scalarref anyway)');
+
+$rs = $schema->resultset('CD')->search({},
             { 'order_by' => \$order });
-{
-       eval { $rs->first() };
-       ok(!$@, "No problem handling ORDER by scalaref" );
-}
+eval { $rs->first };
+like($sql, qr/ORDER BY \Q${order}\E/, 'did not quote ORDER BY with scalarref');
 
-DBICTest->schema->connection($dsn, { quote_char => [qw/[ ]/], name_sep => '.' });
+$schema->connection($dsn, { quote_char => [qw/[ ]/], name_sep => '.' });
+$schema->storage->debugcb(sub { $sql = $_[1] });
+$schema->storage->debug(1);
 
-$rs = DBICTest::CD->search(
+$rs = $schema->resultset('CD')->search(
            { 'me.year' => 2001, 'artist.name' => 'Caterwauler McCrae' },
            { join => 'artist' });
-cmp_ok($rs->count,'==', 1,"join quoted with brackets.");
+eval { $rs->count };
+like($sql, qr/\QSELECT COUNT( * ) FROM [cd] [me]  JOIN [artist] [artist] ON ( [artist].[artistid] = [me].[artist] ) WHERE ( [artist].[name] = ? AND [me].[year] = ? )\E/, 'got correct SQL for count query with bracket quoting');
 
 my %data = (
        name => 'Bill',
        order => '12'
 );
 
-DBICTest->schema->connection($dsn, { quote_char => '`', name_sep => '.' });
+$schema->connection($dsn, { quote_char => '`', name_sep => '.' });
 
-cmp_ok(DBICTest->schema->storage->sql_maker->update('group', \%data), 'eq', 'UPDATE `group` SET `name` = ?, `order` = ?', "quoted table names for UPDATE");
+is($schema->storage->sql_maker->update('group', \%data), 'UPDATE `group` SET `name` = ?, `order` = ?', 'quoted table names for UPDATE');
 
+$schema->storage->debugcb($orig_debugcb);
+$schema->storage->debug($orig_debug);
index 59aeb9e..9f0da40 100644 (file)
@@ -14,23 +14,23 @@ BEGIN {
 use lib qw(t/lib);
 
 use_ok('DBICTest');
-DBICTest->init_schema();
+my $schema = DBICTest->init_schema();
 
 my $cbworks = 0;
 
-DBICTest->schema->storage->debugcb(sub { $cbworks = 1; });
-DBICTest->schema->storage->debug(0);
-my $rs = DBICTest::CD->search({});
+$schema->storage->debugcb(sub { $cbworks = 1; });
+$schema->storage->debug(0);
+my $rs = $schema->resultset('CD')->search({});
 $rs->count();
 ok(!$cbworks, 'Callback not called with debug disabled');
 
-DBICTest->schema->storage->debug(1);
+$schema->storage->debug(1);
 
 $rs->count();
 ok($cbworks, 'Debug callback worked.');
 
 my $prof = new DBIx::Test::Profiler();
-DBICTest->schema->storage->debugobj($prof);
+$schema->storage->debugobj($prof);
 
 # Test non-transaction calls.
 $rs->count();
@@ -42,27 +42,27 @@ ok(!$prof->{'txn_commit'}, 'txn_commit not called');
 $prof->reset();
 
 # Test transaction calls
-DBICTest->schema->txn_begin();
+$schema->txn_begin();
 ok($prof->{'txn_begin'}, 'txn_begin called');
 
-$rs = DBICTest::CD->search({});
+$rs = $schema->resultset('CD')->search({});
 $rs->count();
 ok($prof->{'query_start'}, 'query_start called');
 ok($prof->{'query_end'}, 'query_end called');
 
-DBICTest->schema->txn_commit();
+$schema->txn_commit();
 ok($prof->{'txn_commit'}, 'txn_commit called');
 
 $prof->reset();
 
 # Test a rollback
-DBICTest->schema->txn_begin();
-$rs = DBICTest::CD->search({});
+$schema->txn_begin();
+$rs = $schema->resultset('CD')->search({});
 $rs->count();
-DBICTest->schema->txn_rollback();
+$schema->txn_rollback();
 ok($prof->{'txn_rollback'}, 'txn_rollback called');
 
-DBICTest->schema->storage->debug(0);
+$schema->storage->debug(0);
 
 package DBIx::Test::Profiler;
 use strict;
index dd54be1..7fef551 100644 (file)
@@ -60,5 +60,5 @@ eval { throwex };
 like($@, qr/DBICTest::Exception is handling this: $ex_regex/);
 
 # While we're at it, lets throw a custom exception through Storage::DBI
-eval { DBICTest->schema->storage->throw_exception('floob') };
+eval { $schema->storage->throw_exception('floob') };
 like($@, qr/DBICTest::Exception is handling this: floob/);
diff --git a/t/35disable_sth_caching.t b/t/35disable_sth_caching.t
new file mode 100644 (file)
index 0000000..5ad4cca
--- /dev/null
@@ -0,0 +1,19 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+plan tests => 2;
+
+# Set up the "usual" sqlite for DBICTest
+my $schema = DBICTest->init_schema;
+
+my $sth_one = $schema->storage->sth('SELECT 42');
+my $sth_two = $schema->storage->sth('SELECT 42');
+$schema->storage->disable_sth_caching(1);
+my $sth_three = $schema->storage->sth('SELECT 42');
+
+ok($sth_one == $sth_two, "statement caching works");
+ok($sth_two != $sth_three, "disabling statement caching works");
index bdec159..8389291 100644 (file)
@@ -17,7 +17,7 @@ BEGIN {
 
 use DBICTest::ResultSetManager; # uses Class::Inspector
 
-my $schema = DBICTest::ResultSetManager->compose_connection('DB', 'foo');
+my $schema = DBICTest::ResultSetManager->compose_namespace('DB');
 my $rs = $schema->resultset('Foo');
 
 ok( !DB::Foo->can('bar'), 'Foo class does not have bar method' );
diff --git a/t/54taint.t b/t/54taint.t
new file mode 100644 (file)
index 0000000..8e93b48
--- /dev/null
@@ -0,0 +1,33 @@
+#!perl -T
+
+# the above line forces Test::Harness into taint-mode
+
+use strict;
+use warnings;
+
+our @plan;
+
+BEGIN {
+  eval "require Module::Find;";
+  @plan = $@ ? ( skip_all => 'Could not load Module::Find' )
+    : ( tests => 2 );
+}
+
+package DBICTest::Schema;
+
+# Use the default test class namespace to avoid the need for a
+# new test infrastructure. If invalid classes will be introduced to
+# 't/lib/DBICTest/Schema/' someday, this has to be reworked.
+
+use lib qw(t/lib);
+
+use Test::More @plan;
+
+use base qw/DBIx::Class::Schema/;
+
+eval{ __PACKAGE__->load_classes() };
+cmp_ok( $@, 'eq', '',
+        'Loading classes with Module::Find worked in taint mode' );
+ok( __PACKAGE__->sources(), 'At least on source has been registered' );
+
+1;
diff --git a/t/55storage_stress.t b/t/55storage_stress.t
new file mode 100644 (file)
index 0000000..f338302
--- /dev/null
@@ -0,0 +1,55 @@
+use strict;
+use warnings;
+use Test::More;
+
+# XXX obviously, the guts of this test haven't been written yet --blblack
+
+use lib qw(t/lib);
+
+plan skip_all => 'Set $ENV{DBICTEST_STORAGE_STRESS} to run this test'
+    . ' (it is very resource intensive!)'
+        unless $ENV{DBICTEST_STORAGE_STRESS};
+
+my $NKIDS = 20;
+my $CYCLES = 5;
+my @KILL_RATES = qw/0 0.001 0.01 0.1 0.2 0.5 0.75 1.0/;
+
+# Stress the storage with these parameters...
+sub stress_storage {
+    my ($connect_info, $num_kids, $cycles, $kill_rate) = @_;
+
+    foreach my $cycle (1..$cycles) {
+        my $schema = DBICTest::Schema->connection(@$connect_info, { AutoCommit => 1 });
+        foreach my $kidno (1..$num_kids) {
+            ok(1);
+        }
+    }
+}
+
+# Get a set of connection information -
+#  whatever the user has supplied for the vendor-specific tests
+sub get_connect_infos {
+    my @connect_infos;
+    foreach my $db_prefix (qw/PG MYSQL DB2 MSSQL ORA/) {
+        my @conn_info = @ENV{
+            map { "DBICTEST_${db_prefix}_${_}" } qw/DSN USER PASS/
+        };
+        push(@connect_infos, \@conn_info) if $conn_info[0];
+    }
+    \@connect_infos;
+}
+
+my $connect_infos = get_connect_infos();
+
+plan skip_all => 'This test needs some non-sqlite connect info!'
+    unless @$connect_infos;
+
+plan tests => (1 * @$connect_infos * $NKIDS * $CYCLES * @KILL_RATES) + 1;
+
+use_ok('DBICTest::Schema');
+
+foreach my $connect_info (@$connect_infos) {
+    foreach my $kill_rate (@KILL_RATES) {
+        stress_storage($connect_info, $NKIDS, $CYCLES, $kill_rate);
+    }
+}
index b0d7ec6..3eb80df 100644 (file)
@@ -255,7 +255,7 @@ ok($schema->storage(), 'Storage available');
   cmp_ok(@artsn, '==', 4, "Four artists returned");
   
   # make sure subclasses that don't set source_name are ok
-  ok($schema->source('ArtistSubclass', 'ArtistSubclass exists'));
+  ok($schema->source('ArtistSubclass'), 'ArtistSubclass exists');
 }
 
 my $newbook = $schema->resultset( 'Bookmark' )->find(1);
diff --git a/t/63register_class.t b/t/63register_class.t
new file mode 100644 (file)
index 0000000..2fdc07c
--- /dev/null
@@ -0,0 +1,17 @@
+use strict;
+use warnings;  
+
+use Test::More tests => 2;
+use lib qw(t/lib);
+use DBICTest;
+use DBICTest::Schema;
+use DBICTest::Schema::Artist;
+
+DBICTest::Schema::Artist->source_name('MyArtist');
+DBICTest::Schema->register_class('FooA', 'DBICTest::Schema::Artist');
+
+my $schema = DBICTest->init_schema();
+
+my $a = $schema->resultset('FooA')->search;
+is($a->count, 3, 'have 3 artists');
+is($schema->class('FooA'), 'DBICTest::FooA', 'Correct artist class');
index 084bb8e..45c9b2f 100644 (file)
@@ -9,7 +9,7 @@ my $schema = DBICTest->init_schema();
 
 plan tests => 5;
 
-my $artist = DBICTest::Artist->find(1);
+my $artist = $schema->resultset("Artist")->find(1);
 ok($artist->find_related('twokeys', {cd => 1}), "find multiple pks using relationships + args");
 
 ok($schema->resultset("FourKeys")->search({ foo => 1, bar => 2 })->find({ hello => 3, goodbye => 4 }), "search on partial key followed by a find");
index 0ce901c..ea917f8 100644 (file)
@@ -5,15 +5,16 @@ use Test::More;
 use lib qw(t/lib);
 use DBICTest;
 
-DBICTest::Schema::CD->add_column('year');
 my $schema = DBICTest->init_schema();
 
 eval { require DateTime };
 plan skip_all => "Need DateTime for inflation tests" if $@;
 
-plan tests => 4;
+plan tests => 20;
 
-DBICTest::Schema::CD->inflate_column( 'year',
+$schema->class('CD')
+#DBICTest::Schema::CD
+->inflate_column( 'year',
     { inflate => sub { DateTime->new( year => shift ) },
       deflate => sub { shift->year } }
 );
@@ -28,11 +29,80 @@ is( $cd->year->year, 1997, 'inflated year ok' );
 
 is( $cd->year->month, 1, 'inflated month ok' );
 
+eval { $cd->year(\'year +1'); };
+ok(!$@, 'updated year using a scalarref');
+$cd->update();
+$cd->discard_changes();
+
+is( ref($cd->year), 'DateTime', 'year is still a DateTime, ok' );
+
+is( $cd->year->year, 1998, 'updated year, bypassing inflation' );
+
+is( $cd->year->month, 1, 'month is still 1' );  
+
+# get_inflated_column test
+
+is( ref($cd->get_inflated_column('year')), 'DateTime', 'get_inflated_column produces a DateTime');
+
 # deflate test
 my $now = DateTime->now;
 $cd->year( $now );
 $cd->update;
 
-($cd) = $schema->resultset("CD")->search( year => $now->year );
+$cd = $schema->resultset("CD")->find(3);
 is( $cd->year->year, $now->year, 'deflate ok' );
 
+# set_inflated_column test
+eval { $cd->set_inflated_column('year', $now) };
+ok(!$@, 'set_inflated_column with DateTime object');
+$cd->update;
+
+$cd = $schema->resultset("CD")->find(3);                 
+is( $cd->year->year, $now->year, 'deflate ok' );
+
+$cd = $schema->resultset("CD")->find(3);                 
+my $before_year = $cd->year->year;
+eval { $cd->set_inflated_column('year', \'year + 1') };
+ok(!$@, 'set_inflated_column to "year + 1"');
+$cd->update;
+
+$cd = $schema->resultset("CD")->find(3);                 
+is( $cd->year->year, $before_year+1, 'deflate ok' );
+
+# store_inflated_column test
+$cd = $schema->resultset("CD")->find(3);                 
+eval { $cd->store_inflated_column('year', $now) };
+ok(!$@, 'store_inflated_column with DateTime object');
+$cd->update;
+
+is( $cd->year->year, $now->year, 'deflate ok' );
+
+# update tests
+$cd = $schema->resultset("CD")->find(3);                 
+eval { $cd->update({'year' => $now}) };
+ok(!$@, 'update using DateTime object ok');
+is($cd->year->year, $now->year, 'deflate ok');
+
+$cd = $schema->resultset("CD")->find(3);                 
+$before_year = $cd->year->year;
+eval { $cd->update({'year' => \'year + 1'}) };
+ok(!$@, 'update using scalarref ok');
+
+$cd = $schema->resultset("CD")->find(3);                 
+is($cd->year->year, $before_year + 1, 'deflate ok');
+
+# discard_changes test
+$cd = $schema->resultset("CD")->find(3);                 
+# inflate the year
+$before_year = $cd->year->year;
+$cd->update({ year => \'year + 1'});
+$cd->discard_changes;
+
+is($cd->year->year, $before_year + 1, 'discard_changes clears the inflated value');
+# eval { $cd->store_inflated_column('year', \'year + 1') };
+# print STDERR "ERROR: $@" if($@);
+# ok(!$@, 'store_inflated_column to "year + 1"');
+
+# is_deeply( $cd->year, \'year + 1', 'deflate ok' );
+
diff --git a/t/68inflate_resultclass_hashrefinflator.t b/t/68inflate_resultclass_hashrefinflator.t
new file mode 100644 (file)
index 0000000..221626a
--- /dev/null
@@ -0,0 +1,87 @@
+use strict;
+use warnings;  
+
+use Test::More qw(no_plan);
+use lib qw(t/lib);
+use DBICTest;
+use DBIx::Class::ResultClass::HashRefInflator;
+my $schema = DBICTest->init_schema();
+
+
+# Under some versions of SQLite if the $rs is left hanging around it will lock
+# So we create a scope here cos I'm lazy
+{
+    my $rs = $schema->resultset('CD');
+
+    # get the defined columns
+    my @dbic_cols = sort $rs->result_source->columns;
+
+    # use the hashref inflator class as result class
+    $rs->result_class('DBIx::Class::ResultClass::HashRefInflator');
+
+    # fetch first record
+    my $datahashref1 = $rs->first;
+
+    my @hashref_cols = sort keys %$datahashref1;
+
+    is_deeply( \@dbic_cols, \@hashref_cols, 'returned columns' );
+}
+
+
+sub check_cols_of {
+    my ($dbic_obj, $datahashref) = @_;
+    
+    foreach my $col (keys %$datahashref) {
+        # plain column
+        if (not ref ($datahashref->{$col}) ) {
+            is ($datahashref->{$col}, $dbic_obj->get_column($col), 'same value');
+        }
+        # related table entry (belongs_to)
+        elsif (ref ($datahashref->{$col}) eq 'HASH') {
+            check_cols_of($dbic_obj->$col, $datahashref->{$col});
+        }
+        # multiple related entries (has_many)
+        elsif (ref ($datahashref->{$col}) eq 'ARRAY') {
+            my @dbic_reltable = $dbic_obj->$col;
+            my @hashref_reltable = @{$datahashref->{$col}};
+  
+            is (scalar @hashref_reltable, scalar @dbic_reltable, 'number of related entries');
+
+            # for my $index (0..scalar @hashref_reltable) {
+            for my $index (0..scalar @dbic_reltable) {
+                my $dbic_reltable_obj       = $dbic_reltable[$index];
+                my $hashref_reltable_entry  = $hashref_reltable[$index];
+                
+                check_cols_of($dbic_reltable_obj, $hashref_reltable_entry);
+            }
+        }
+    }
+}
+
+# create a cd without tracks for testing empty has_many relationship
+$schema->resultset('CD')->create({ title => 'Silence is golden', artist => 3, year => 2006 });
+
+# order_by to ensure both resultsets have the rows in the same order
+my $rs_dbic = $schema->resultset('CD')->search(undef,
+    {
+        prefetch    => [ qw/ artist tracks / ],
+        order_by    => [ 'me.cdid', 'tracks.position' ],
+    }
+);
+my $rs_hashrefinf = $schema->resultset('CD')->search(undef,
+    {
+        prefetch    => [ qw/ artist tracks / ],
+        order_by    => [ 'me.cdid', 'tracks.position' ],
+    }
+);
+$rs_hashrefinf->result_class('DBIx::Class::ResultClass::HashRefInflator');
+
+my @dbic        = $rs_dbic->all;
+my @hashrefinf  = $rs_hashrefinf->all;
+
+for my $index (0..scalar @hashrefinf) {
+    my $dbic_obj    = $dbic[$index];
+    my $datahashref = $hashrefinf[$index];
+
+    check_cols_of($dbic_obj, $datahashref);
+}
index 5eed843..2efabbf 100644 (file)
@@ -32,7 +32,7 @@ foreach my $serializer (@serializers) {
 
 plan (skip_all => "No suitable serializer found") unless $selected;
 
-plan (tests => 6);
+plan (tests => 8);
 DBICTest::Schema::Serialized->inflate_column( 'serialized',
     { inflate => $selected->{inflater},
       deflate => $selected->{deflater},
@@ -69,6 +69,13 @@ ok($entry->update ({ %{$complex1} }), 'hashref deflation ok');
 ok($inflated = $entry->serialized, 'hashref inflation ok');
 is_deeply($inflated, $complex1->{serialized}, 'inflated hash matches original');
 
+my $entry2 = $rs->create({ id => 2, serialized => ''});
+
+eval { $entry2->set_inflated_column('serialized', $complex1->{serialized}) };
+ok(!$@, 'set_inflated_column to a hashref');
+$entry2->update;
+is_deeply($entry2->serialized, $complex1->{serialized}, 'inflated hash matches original');
+
 ok($entry->update ({ %{$complex2} }), 'arrayref deflation ok');
 ok($inflated = $entry->serialized, 'arrayref inflation ok');
 is_deeply($inflated, $complex2->{serialized}, 'inflated array matches original');
index 3372b4f..4686876 100644 (file)
@@ -9,7 +9,7 @@ my $schema = DBICTest->init_schema();
 
 BEGIN {
         eval "use DBD::SQLite";
-        plan $@ ? (skip_all => 'needs DBD::SQLite for testing') : (tests => 3);
+        plan $@ ? (skip_all => 'needs DBD::SQLite for testing') : (tests => 6);
 }                                                                               
 
 my $art = $schema->resultset("Artist")->find(1);
@@ -27,3 +27,10 @@ ok($art->name($name) eq $name, 'update');
 
 $art->discard_changes;
 
+ok($art->update({ artistid => 100 }), 'update allows pk mutation');
+
+is($art->artistid, 100, 'pk mutation applied');
+
+my $art_100 = $schema->resultset("Artist")->find(100);
+$art_100->artistid(101);
+ok($art_100->update(), 'update allows pk mutation via column accessor');
index aeb73ea..3bbdaa1 100644 (file)
@@ -15,7 +15,7 @@ plan skip_all => 'Set $ENV{DBICTEST_MYSQL_DSN}, _USER and _PASS to run this test
 
 plan tests => 5;
 
-DBICTest::Schema->compose_connection('MySQLTest' => $dsn, $user, $pass);
+DBICTest::Schema->compose_namespace('MySQLTest' => $dsn, $user, $pass);
 
 my $dbh = MySQLTest->schema->storage->dbh;
 
index ca67043..a3239ca 100644 (file)
--- a/t/72pg.t
+++ b/t/72pg.t
@@ -30,7 +30,7 @@ plan skip_all => 'Set $ENV{DBICTEST_PG_DSN}, _USER and _PASS to run this test'
 plan tests => 8;
 
 DBICTest::Schema->load_classes( 'Casecheck' );
-DBICTest::Schema->compose_connection('PgTest' => $dsn, $user, $pass);
+DBICTest::Schema->compose_namespace('PgTest' => $dsn, $user, $pass);
 
 my $dbh = PgTest->schema->storage->dbh;
 PgTest->schema->source("Artist")->name("testschema.artist");
index c0489ff..7ca5c41 100644 (file)
@@ -13,7 +13,7 @@ plan skip_all => 'Set $ENV{DBICTEST_ORA_DSN}, _USER and _PASS to run this test.
 
 plan tests => 6;
 
-DBICTest::Schema->compose_connection('OraTest' => $dsn, $user, $pass);
+DBICTest::Schema->compose_namespace('OraTest' => $dsn, $user, $pass);
 
 my $dbh = OraTest->schema->storage->dbh;
 
index ffb7a0b..82d3c2c 100644 (file)
@@ -14,7 +14,7 @@ plan skip_all => 'Set $ENV{DBICTEST_DB2_DSN}, _USER and _PASS to run this test'
 
 plan tests => 6;
 
-DBICTest::Schema->compose_connection('DB2Test' => $dsn, $user, $pass);
+DBICTest::Schema->compose_namespace('DB2Test' => $dsn, $user, $pass);
 
 my $dbh = DB2Test->schema->storage->dbh;
 
index 558ca62..745673b 100644 (file)
@@ -17,7 +17,7 @@ plan skip_all => 'Set $ENV{DBICTEST_DB2_400_DSN}, _USER and _PASS to run this te
 
 plan tests => 6;
 
-DBICTest::Schema->compose_connection('DB2Test' => $dsn, $user, $pass);
+DBICTest::Schema->compose_namespace('DB2Test' => $dsn, $user, $pass);
 
 my $dbh = DB2Test->schema->storage->dbh;
 
index 204a640..0bb43b6 100644 (file)
@@ -19,7 +19,7 @@ $storage_type = '::DBI::Sybase::MSSQL' if $dsn =~ /^dbi:Sybase:/;
 # Add more for others in the future when they exist (ODBC? ADO? JDBC?)
 
 DBICTest::Schema->storage_type($storage_type);
-DBICTest::Schema->compose_connection( 'MSSQLTest' => $dsn, $user, $pass );
+DBICTest::Schema->compose_namespace( 'MSSQLTest' => $dsn, $user, $pass );
 
 my $dbh = MSSQLTest->schema->storage->dbh;
 
index 1033b53..96836fb 100644 (file)
@@ -16,7 +16,7 @@ BEGIN {
     eval "use DBD::SQLite";
     plan $@
         ? ( skip_all => 'needs DBD::SQLite for testing' )
-        : ( tests => 49 );
+        : ( tests => 53 );
 }
 
 # figure out if we've got a version of sqlite that is older than 3.2.6, in
@@ -89,6 +89,26 @@ $match = 'person mother LEFT JOIN (person child RIGHT JOIN person father ON ('
        ;
 is( $sa->_recurse_from(@j4), $match, 'join 4 (nested joins + join types) ok');
 
+my @j5 = (
+    { child => 'person' },
+    [ { father => 'person' }, { 'father.person_id' => \'!= child.father_id' }, ],
+    [ { mother => 'person' }, { 'mother.person_id' => 'child.mother_id' } ],
+);
+$match = 'person child JOIN person father ON ( father.person_id != '
+          . 'child.father_id ) JOIN person mother ON ( mother.person_id '
+          . '= child.mother_id )'
+          ;
+is( $sa->_recurse_from(@j5), $match, 'join 5 (SCALAR reference for ON statement) ok' );
+
+my @j6 = (
+    { child => 'person' },
+    [ { father => 'person' }, { 'father.person_id' => { '!=', '42' } }, ],
+    [ { mother => 'person' }, { 'mother.person_id' => 'child.mother_id' } ],
+);
+$match = qr/^\QHASH reference arguments are not supported in JOINS - try using \"..." instead\E/;
+eval { $sa->_recurse_from(@j6) };
+like( $@, $match, 'join 6 (HASH reference for ON statement dies) ok' );
+
 my $rs = $schema->resultset("CD")->search(
            { 'year' => 2001, 'artist.name' => 'Caterwauler McCrae' },
            { from => [ { 'me' => 'cd' },
@@ -343,3 +363,50 @@ like( $sql, qr/^SELECT tracks_2\.trackid/, "join not collapsed for search_relate
 
 $schema->storage->debug($orig_debug);
 $schema->storage->debugobj->callback(undef);
+
+$rs = $schema->resultset('Artist');
+$rs->create({ artistid => 4, name => 'Unknown singer-songwriter' });
+$rs->create({ artistid => 5, name => 'Emo 4ever' });
+@artists = $rs->search(undef, { prefetch => 'cds', order_by => 'artistid' });
+is(scalar @artists, 5, 'has_many prefetch with adjacent empty rows ok');
+
+# -------------
+#
+# Tests for multilevel has_many prefetch
+
+# artist resultsets - with and without prefetch
+my $art_rs = $schema->resultset('Artist');
+my $art_rs_pr = $art_rs->search(
+    {},
+    {
+        join     => [ { cds => ['tracks'] } ],
+        prefetch => [ { cds => ['tracks'] } ]
+    }
+);
+
+# This test does the same operation twice - once on a
+# set of items fetched from the db with no prefetch of has_many rels
+# The second prefetches 2 levels of has_many
+# We check things are the same by comparing the name or title
+# we build everything into a hash structure and compare the one
+# from each rs to see what differs
+
+sub make_hash_struc {
+    my $rs = shift;
+
+    my $struc = {};
+    foreach my $art ( $rs->all ) {
+        foreach my $cd ( $art->cds ) {
+            foreach my $track ( $cd->tracks ) {
+                $struc->{ $art->name }{ $cd->title }{ $track->title }++;
+            }
+        }
+    }
+    return $struc;
+}
+
+my $prefetch_result = make_hash_struc($art_rs_pr);
+my $nonpre_result   = make_hash_struc($art_rs);
+
+is_deeply( $prefetch_result, $nonpre_result,
+    'Compare 2 level prefetch result to non-prefetch result' );
index 6e73f10..94ae02b 100644 (file)
@@ -7,12 +7,12 @@ use DBICTest;
 
 my $schema = DBICTest->init_schema();
 
-plan tests => 8;
-
-my $artist = $schema->resultset('Artist')->find(1);
+plan tests => 11;
 
 # Check that you can leave off the alias
 {
+  my $artist = $schema->resultset('Artist')->find(1);
+
   my $existing_cd = $artist->search_related('cds', undef, { prefetch => 'tracks' })->find_or_create({
     title => 'Ted',
     year  => 2006,
@@ -30,6 +30,8 @@ my $artist = $schema->resultset('Artist')->find(1);
 
 # Check that you can specify the alias
 {
+  my $artist = $schema->resultset('Artist')->find(1);
+
   my $existing_cd = $artist->search_related('cds', undef, { prefetch => 'tracks' })->find_or_create({
     'me.title' => 'Something Else',
     'me.year'  => 2006,
@@ -44,3 +46,13 @@ my $artist = $schema->resultset('Artist')->find(1);
   ok(! $new_cd->is_changed, 'find_or_create on prefetched has_many with same column names: row is clean');
   is($new_cd->title, 'Some New Guy', 'find_or_create on prefetched has_many with same column names: can be disambiguated with "me." for new entry');
 }
+
+# Don't pass column names with related alias to new_result
+{
+  my $cd_rs = $schema->resultset('CD')->search({ 'artist.name' => 'Caterwauler McCrae' }, { join => 'artist' });
+
+  my $cd = $cd_rs->find_or_new({ title => 'Huh?', year => 2006 });
+  ok(! $cd->in_storage, 'new CD not in storage yet');
+  is($cd->title, 'Huh?', 'new CD title is correct');
+  is($cd->year, 2006, 'new CD year is correct');
+}
index eebb66e..6108f28 100644 (file)
@@ -7,7 +7,7 @@ use DBICTest;
 
 my $schema = DBICTest->init_schema();
 
-plan tests => 43;
+plan tests => 45;
 
 # Check the defined unique constraints
 is_deeply(
@@ -126,8 +126,9 @@ is($cd8->get_column('artist'), $cd1->get_column('artist'), 'artist is correct');
 is($cd8->title, $cd1->title, 'title is correct');
 is($cd8->year, $cd1->year, 'year is correct');
 
-my $cd9 = $artist->update_or_create_related('cds',
+my $cd9 = $artist->cds->update_or_create(
   {
+    cdid   => $cd1->cdid,
     title  => $title,
     year   => 2021,
   },
@@ -161,7 +162,24 @@ my $row = $schema->resultset('NoPrimaryKey')->update_or_create(
   },
   { key => 'foo_bar' }
 );
+
 ok(! $row->is_changed, 'update_or_create on table without primary key: row is clean');
 is($row->foo, 1, 'foo is correct');
 is($row->bar, 2, 'bar is correct');
 is($row->baz, 3, 'baz is correct');
+
+# Test a unique condition with extra information in the where attr
+{
+  my $artist = $schema->resultset('Artist')->find({ artistid => 1 });
+  my $cd = $artist->cds->find_or_new(
+    {
+      cdid  => 1,
+      title => 'Not The Real Title',
+      year  => 3000,
+    },
+    { key => 'primary' }
+  );
+
+  ok($cd->in_storage, 'find correctly grepped the key across a relationship');
+  is($cd->cdid, 1, 'cdid is correct');
+}
index a18814d..8ef3bda 100644 (file)
@@ -7,8 +7,14 @@ use DBICTest;
 
 my $schema = DBICTest->init_schema();
 
-eval 'use utf8; 1'
-    or plan skip_all => 'Need utf8 run this test';
+if ($] <= 5.008000) {
+
+    eval 'use Encode; 1' or plan skip_all => 'Need Encode run this test';
+
+} else {
+
+    eval 'use utf8; 1' or plan skip_all => 'Need utf8 run this test';
+}
 
 plan tests => 3;
 
@@ -17,12 +23,23 @@ DBICTest::Schema::CD->utf8_columns('title');
 Class::C3->reinitialize();
 
 my $cd = $schema->resultset('CD')->create( { artist => 1, title => 'øni', year => 'foo' } );
-ok( utf8::is_utf8( $cd->title ), 'got title with utf8 flag' );
-ok( !utf8::is_utf8( $cd->year ), 'got year without utf8 flag' );
-
 my $utf8_char = 'uniuni';
-utf8::decode($utf8_char);
-$cd->title($utf8_char);
-ok( !utf8::is_utf8( $cd->{_column_data}{title} ),
-    'store utf8-less chars' );
 
+if ($] <= 5.008000) {
+
+    ok( Encode::is_utf8( $cd->title ), 'got title with utf8 flag' );
+    ok( !Encode::is_utf8( $cd->year ), 'got year without utf8 flag' );
+
+    Encode::_utf8_on($utf8_char);
+    $cd->title($utf8_char);
+    ok( !Encode::is_utf8( $cd->{_column_data}{title} ), 'store utf8-less chars' );
+
+} else {
+
+    ok( utf8::is_utf8( $cd->title ), 'got title with utf8 flag' );
+    ok( !utf8::is_utf8( $cd->year ), 'got year without utf8 flag' );
+
+    utf8::decode($utf8_char);
+    $cd->title($utf8_char);
+    ok( !utf8::is_utf8( $cd->{_column_data}{title} ), 'store utf8-less chars' );
+}
index 92d90f2..095a878 100644 (file)
@@ -10,7 +10,7 @@ plan skip_all => 'SQL::Translator required' if $@;
 
 my $schema = DBICTest->init_schema;
 
-plan tests => 53;
+plan tests => 54;
 
 my $translator = SQL::Translator->new( 
   parser_args => {
@@ -24,6 +24,10 @@ $translator->producer('SQLite');
 
 my $output = $translator->translate();
 
+
+ok($output, "SQLT produced someoutput")
+  or diag($translator->error);
+
 # Note that the constraints listed here are the only ones that are tested -- if
 # more exist in the Schema than are listed here and all listed constraints are
 # correct, the test will still pass. If you add a class with UNIQUE or FOREIGN
index b1d484c..7bc1bed 100644 (file)
@@ -6,9 +6,11 @@ use Test::More;
 use lib qw(t/lib);
 use DBICTest;
 
+use POSIX qw(ceil);
+
 my $schema = DBICTest->init_schema();
 
-plan tests => 321;
+plan tests => 879;
 
 my $employees = $schema->resultset('Employee');
 $employees->delete();
@@ -23,20 +25,168 @@ hammer_rs( $employees );
 
 DBICTest::Employee->grouping_column('group_id');
 $employees->delete();
-foreach my $group_id (1..3) {
+foreach my $group_id (1..4) {
     foreach (1..6) {
         $employees->create({ name=>'temp', group_id=>$group_id });
     }
 }
 $employees = $employees->search(undef,{order_by=>'group_id,position'});
 
-foreach my $group_id (1..3) {
+foreach my $group_id (1..4) {
     my $group_employees = $employees->search({group_id=>$group_id});
     $group_employees->all();
     ok( check_rs($group_employees), "group intial positions" );
     hammer_rs( $group_employees );
 }
 
+my $group_3 = $employees->search({group_id=>3});
+my $to_group = 1;
+my $to_pos = undef;
+while (my $employee = $group_3->next) {
+       $employee->move_to_group($to_group, $to_pos);
+       $to_pos++;
+       $to_group = $to_group==1 ? 2 : 1;
+}
+foreach my $group_id (1..4) {
+    my $group_employees = $employees->search({group_id=>$group_id});
+    $group_employees->all();
+    ok( check_rs($group_employees), "group positions after move_to_group" );
+}
+
+my $employee = $employees->search({group_id=>4})->first;
+$employee->position(2);
+$employee->update;
+ok( check_rs($employees->search_rs({group_id=>4})), "overloaded update 1" );
+$employee = $employees->search({group_id=>4})->first;
+$employee->update({position=>3});
+ok( check_rs($employees->search_rs({group_id=>4})), "overloaded update 2" );
+$employee = $employees->search({group_id=>4})->first;
+$employee->group_id(1);
+$employee->update;
+ok(
+       check_rs($employees->search_rs({group_id=>1})) && check_rs($employees->search_rs({group_id=>4})),
+       "overloaded update 3"
+);
+$employee = $employees->search({group_id=>4})->first;
+$employee->update({group_id=>2});
+ok(
+       check_rs($employees->search_rs({group_id=>2})) && check_rs($employees->search_rs({group_id=>4})),
+       "overloaded update 4"
+);
+$employee = $employees->search({group_id=>4})->first;
+$employee->group_id(1);
+$employee->position(3);
+$employee->update;
+ok(
+       check_rs($employees->search_rs({group_id=>1})) && check_rs($employees->search_rs({group_id=>4})),
+       "overloaded update 5"
+);
+$employee = $employees->search({group_id=>4})->first;
+$employee->group_id(2);
+$employee->position(undef);
+$employee->update;
+ok(
+       check_rs($employees->search_rs({group_id=>2})) && check_rs($employees->search_rs({group_id=>4})),
+       "overloaded update 6"
+);
+$employee = $employees->search({group_id=>4})->first;
+$employee->update({group_id=>1,position=>undef});
+ok(
+       check_rs($employees->search_rs({group_id=>1})) && check_rs($employees->search_rs({group_id=>4})),
+       "overloaded update 7"
+);
+
+# multicol tests begin here
+DBICTest::Employee->grouping_column(['group_id', 'group_id_2']);
+$employees->delete();
+foreach my $group_id (1..4) {
+    foreach my $group_id_2 (1..4) {
+        foreach (1..4) {
+            $employees->create({ name=>'temp', group_id=>$group_id, group_id_2=>$group_id_2 });
+        }
+    }
+}
+$employees = $employees->search(undef,{order_by=>'group_id,group_id_2,position'});
+
+foreach my $group_id (1..3) {
+    foreach my $group_id_2 (1..3) {
+        my $group_employees = $employees->search({group_id=>$group_id, group_id_2=>$group_id_2});
+        $group_employees->all();
+        ok( check_rs($group_employees), "group intial positions" );
+        hammer_rs( $group_employees );
+    }
+}
+
+# move_to_group, specifying group by hash
+my $group_4 = $employees->search({group_id=>4});
+$to_group = 1;
+my $to_group_2_base = 7;
+my $to_group_2 = 1;
+$to_pos = undef;
+while (my $employee = $group_4->next) {
+       $employee->move_to_group({group_id=>$to_group, group_id_2=>$to_group_2}, $to_pos);
+       $to_pos++;
+    $to_group = ($to_group % 3) + 1;
+    $to_group_2_base++;
+    $to_group_2 = (ceil($to_group_2_base/3.0) %3) +1
+}
+foreach my $group_id (1..4) {
+    foreach my $group_id_2 (1..4) {
+        my $group_employees = $employees->search({group_id=>$group_id,group_id_2=>$group_id_2});
+        $group_employees->all();
+        ok( check_rs($group_employees), "group positions after move_to_group" );
+    }
+}
+
+$employees->delete();
+foreach my $group_id (1..4) {
+    foreach my $group_id_2 (1..4) {
+        foreach (1..4) {
+            $employees->create({ name=>'temp', group_id=>$group_id, group_id_2=>$group_id_2 });
+        }
+    }
+}
+$employees = $employees->search(undef,{order_by=>'group_id,group_id_2,position'});
+
+$employee = $employees->search({group_id=>4, group_id_2=>1})->first;
+$employee->group_id(1);
+$employee->update;
+ok( 
+    check_rs($employees->search_rs({group_id=>4, group_id_2=>1}))
+    && check_rs($employees->search_rs({group_id=>1, group_id_2=>1})), 
+    "overloaded multicol update 1" 
+);
+
+$employee = $employees->search({group_id=>4, group_id_2=>1})->first;
+$employee->update({group_id=>2});
+ok( check_rs($employees->search_rs({group_id=>4, group_id_2=>1}))
+    && check_rs($employees->search_rs({group_id=>2, group_id_2=>1})), 
+    "overloaded multicol update 2" 
+);
+
+$employee = $employees->search({group_id=>3, group_id_2=>1})->first;
+$employee->group_id(1);
+$employee->group_id_2(3);
+$employee->update();
+ok( check_rs($employees->search_rs({group_id=>3, group_id_2=>1}))
+    && check_rs($employees->search_rs({group_id=>1, group_id_2=>3})),
+    "overloaded multicol update 3" 
+);
+
+$employee = $employees->search({group_id=>3, group_id_2=>1})->first;
+$employee->update({group_id=>2, group_id_2=>3});
+ok( check_rs($employees->search_rs({group_id=>3, group_id_2=>1}))
+    && check_rs($employees->search_rs({group_id=>2, group_id_2=>3})), 
+    "overloaded multicol update 4" 
+);
+
+$employee = $employees->search({group_id=>3, group_id_2=>2})->first;
+$employee->update({group_id=>2, group_id_2=>4, position=>2});
+ok( check_rs($employees->search_rs({group_id=>3, group_id_2=>2}))
+    && check_rs($employees->search_rs({group_id=>2, group_id_2=>4})), 
+    "overloaded multicol update 5" 
+);
+
 sub hammer_rs {
     my $rs = shift;
     my $employee;
index 7307c6f..b62d622 100644 (file)
@@ -23,7 +23,7 @@ plan tests => 5;
 # tests run on windows as well
 
 my $employees = $schema->resultset('Employee');
-my $cmd = qq|perl script/dbicadmin --schema=DBICTest::Schema --class=Employee --tlibs --connect="['dbi:SQLite:dbname=t/var/DBIxClass.db','','']" --force --tlibs|;
+my $cmd = qq|$^X script/dbicadmin --schema=DBICTest::Schema --class=Employee --tlibs --connect="['dbi:SQLite:dbname=t/var/DBIxClass.db','','']" --force --tlibs|;
 
 `$cmd --op=insert --set="{name:'Matt'}"`;
 ok( ($employees->count()==1), 'insert count' );
index a759a6c..b4e1adc 100644 (file)
@@ -30,7 +30,7 @@ plan tests => 4;
 
 DBICTest::Schema->storage(undef); # just in case?
 DBICTest::Schema->storage_type('::DBI::MySQLNoBindVars');
-DBICTest::Schema->compose_connection('MySQLTest' => $dsn, $user, $pass);
+DBICTest::Schema->compose_namespace('MySQLTest' => $dsn, $user, $pass);
 
 my $dbh = MySQLTest->schema->storage->dbh;
 
diff --git a/t/93single_accessor_object.t b/t/93single_accessor_object.t
new file mode 100644 (file)
index 0000000..8c2db94
--- /dev/null
@@ -0,0 +1,42 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+my $schema = DBICTest->init_schema();
+
+plan tests => 7;
+
+# Test various uses of passing an object to find, create, and update on a single
+# rel accessor
+{
+  my $artist = $schema->resultset("Artist")->find(1);
+
+  my $cd = $schema->resultset("CD")->find_or_create({
+    artist => $artist,
+    title  => "Object on a might_have",
+    year   => 2006,
+  });
+  ok(defined $cd, 'created a CD');
+  is($cd->get_column('artist'), $artist->id, 'artist matches CD');
+
+  my $liner_notes = $schema->resultset("LinerNotes")->find_or_create({
+    cd     => $cd,
+    notes  => "Creating using an object on a might_have is helpful.",
+  });
+  ok(defined $liner_notes, 'created liner notes');
+  is($liner_notes->liner_id, $cd->cdid, 'liner notes matches CD');
+  is($liner_notes->notes, "Creating using an object on a might_have is helpful.", 'liner notes are correct');
+
+  my $track = $cd->tracks->find_or_create({
+    position => 127,
+    title    => 'Single Accessor'
+  });
+  is($track->get_column('cd'), $cd->cdid, 'track matches CD before update');
+
+  my $another_cd = $schema->resultset("CD")->find(5);
+  $track->update({ disc => $another_cd });
+  is($track->get_column('cd'), $another_cd->cdid, 'track matches another CD after update');
+}
diff --git a/t/94pk_mutation.t b/t/94pk_mutation.t
new file mode 100644 (file)
index 0000000..133a27b
--- /dev/null
@@ -0,0 +1,62 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+my $schema = DBICTest->init_schema();
+
+plan tests => 10;
+
+my $old_artistid = 1;
+my $new_artistid = $schema->resultset("Artist")->get_column('artistid')->max + 1;
+
+# Update the PK
+{
+  my $artist = $schema->resultset("Artist")->find($old_artistid);
+  ok(defined $artist, 'found an artist with the new PK');
+
+  $artist->update({ artistid => $new_artistid });
+  is($artist->artistid, $new_artistid, 'artist ID matches');
+}
+
+# Look for the old PK
+{
+  my $artist = $schema->resultset("Artist")->find($old_artistid);
+  ok(!defined $artist, 'no artist found with the old PK');
+}
+
+# Look for the new PK
+{
+  my $artist = $schema->resultset("Artist")->find($new_artistid);
+  ok(defined $artist, 'found an artist with the new PK');
+  is($artist->artistid, $new_artistid, 'artist ID matches');
+}
+
+# Do it all over again, using a different methodology:
+$old_artistid = $new_artistid;
+$new_artistid++;
+
+# Update the PK
+{
+  my $artist = $schema->resultset("Artist")->find($old_artistid);
+  ok(defined $artist, 'found an artist with the new PK');
+
+  $artist->artistid($new_artistid);
+  $artist->update;
+  is($artist->artistid, $new_artistid, 'artist ID matches');
+}
+
+# Look for the old PK
+{
+  my $artist = $schema->resultset("Artist")->find($old_artistid);
+  ok(!defined $artist, 'no artist found with the old PK');
+}
+
+# Look for the new PK
+{
+  my $artist = $schema->resultset("Artist")->find($new_artistid);
+  ok(defined $artist, 'found an artist with the new PK');
+  is($artist->artistid, $new_artistid, 'artist ID matches');
+}
diff --git a/t/94versioning.t b/t/94versioning.t
new file mode 100644 (file)
index 0000000..852d4fc
--- /dev/null
@@ -0,0 +1,57 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use Test::More;
+
+BEGIN {
+    eval "use DBD::SQLite; use SQL::Translator;";
+    plan $@
+        ? ( skip_all => 'needs DBD::SQLite and SQL::Translator for testing' )
+        : ( tests => 6 );
+}
+
+use lib qw(t/lib);
+
+use_ok('DBICVersionOrig');
+
+my $db_file = "t/var/versioning.db";
+unlink($db_file) if -e $db_file;
+unlink($db_file . "-journal") if -e $db_file . "-journal";
+mkdir("t/var") unless -d "t/var";
+unlink('t/var/DBICVersion-Schema-1.0-SQLite.sql');
+
+my $schema_orig = DBICVersion::Schema->connect("dbi:SQLite:$db_file");
+# $schema->storage->ensure_connected();
+
+is($schema_orig->ddl_filename('SQLite', 't/var', '1.0'), 't/var/DBICVersion-Schema-1.0-SQLite.sql', 'Filename creation working');
+$schema_orig->create_ddl_dir('SQLite', undef, 't/var');
+
+ok(-f 't/var/DBICVersion-Schema-1.0-SQLite.sql', 'Created DDL file');
+## do this here or let Versioned.pm do it?
+# $schema->deploy();
+
+my $tvrs = $schema_orig->resultset('Table');
+is($schema_orig->exists($tvrs), 1, 'Created schema from DDL file');
+
+eval "use DBICVersionNew";
+my $schema_new = DBICVersion::Schema->connect("dbi:SQLite:$db_file");
+
+unlink('t/var/DBICVersion-Schema-2.0-SQLite.sql');
+unlink('t/var/DBICVersion-Schema-1.0-2.0-SQLite.sql');
+$schema_new->create_ddl_dir('SQLite', undef, 't/var', '1.0');
+ok(-f 't/var/DBICVersion-Schema-1.0-2.0-SQLite.sql', 'Created DDL upgrade file');
+
+## create new to pick up filedata for upgrade files we just made (on_connect)
+my $schema_upgrade = DBICVersion::Schema->connect("dbi:SQLite:$db_file");
+
+## do this here or let Versioned.pm do it?
+$schema_upgrade->upgrade();
+$tvrs = $schema_upgrade->resultset('Table');
+is($schema_upgrade->exists($tvrs), 1, 'Upgraded schema from DDL file');
+
+unlink($db_file) if -e $db_file;
+unlink($db_file . "-journal") if -e $db_file . "-journal";
+unlink('t/var/DBICVersion-Schema-1.0-SQLite.sql');
+unlink('t/var/DBICVersion-Schema-2.0-SQLite.sql');
+unlink('t/var/DBICVersion-Schema-1.0-2.0-SQLite.sql');
+unlink(<t/var/backup/*>);
diff --git a/t/95sql_maker_quote.t b/t/95sql_maker_quote.t
new file mode 100644 (file)
index 0000000..1f4cd90
--- /dev/null
@@ -0,0 +1,196 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+
+BEGIN {
+    eval "use DBD::SQLite";
+    plan $@
+        ? ( skip_all => 'needs DBD::SQLite for testing' )
+        : ( tests => 8 );
+}
+
+use lib qw(t/lib);
+
+use_ok('DBICTest');
+
+my $schema = DBICTest->init_schema();
+
+my $sql_maker = $schema->storage->sql_maker;
+
+$sql_maker->quote_char('`');
+$sql_maker->name_sep('.');
+
+my ($sql,) = $sql_maker->select(
+          [
+            {
+              'me' => 'cd'
+            },
+            [
+              {
+                'artist' => 'artist',
+                '-join_type' => ''
+              },
+              {
+                'artist.artistid' => 'me.artist'
+              }
+            ]
+          ],
+          [
+            {
+              'count' => '*'
+            }
+          ],
+          {
+            'artist.name' => 'Caterwauler McCrae',
+            'me.year' => 2001
+          },
+          [],
+          undef,
+          undef
+);
+
+is($sql, 
+   q/SELECT COUNT( * ) FROM `cd` `me`  JOIN `artist` `artist` ON ( `artist`.`artistid` = `me`.`artist` ) WHERE ( `artist`.`name` = ? AND `me`.`year` = ? )/, 
+   'got correct SQL for count query with quoting');
+
+($sql,) = $sql_maker->select(
+          [
+            {
+              'me' => 'cd'
+            }
+          ],
+          [
+            'me.cdid',
+            'me.artist',
+            'me.title',
+            'me.year'
+          ],
+          undef,
+          [
+            'year DESC'
+          ],
+          undef,
+          undef
+);
+
+TODO: {
+    local $TODO = "order_by with quoting needs fixing (ash/castaway)";
+
+    is($sql, 
+       q/SELECT `me`.`cdid`, `me`.`artist`, `me`.`title`, `me`.`year` FROM `cd` `me` ORDER BY `year` DESC/, 
+       'quoted ORDER BY with DESC okay');
+}
+
+TODO: {
+    local $TODO = "select attr with star needs fixing (mst/nate)";
+
+    ($sql,) = $sql_maker->select(
+          [
+            {
+              'me' => 'cd'
+            }
+          ],
+          [
+            'me.*'
+          ],
+          undef,
+          [],
+          undef,
+          undef    
+    );
+
+    is($sql, q/SELECT `me`.* FROM `cd` `me`/, 'select attr with me.* is right');
+}
+
+($sql,) = $sql_maker->select(
+          [
+            {
+              'me' => 'cd'
+            }
+          ],
+          [
+            'me.cdid',
+            'me.artist',
+            'me.title',
+            'me.year'
+          ],
+          undef,
+          [
+            \'year DESC'
+          ],
+          undef,
+          undef
+);
+
+is($sql, 
+   q/SELECT `me`.`cdid`, `me`.`artist`, `me`.`title`, `me`.`year` FROM `cd` `me` ORDER BY year DESC/,
+   'did not quote ORDER BY with scalarref');
+
+my %data = ( 
+    name => 'Bill',
+    order => 12
+);
+
+my @binds;
+
+($sql,@binds) = $sql_maker->update(
+          'group',
+          {
+            'order' => '12',
+            'name' => 'Bill'
+          }
+);
+
+is($sql,
+   q/UPDATE `group` SET `name` = ?, `order` = ?/,
+   'quoted table names for UPDATE');
+
+$sql_maker->quote_char([qw/[ ]/]);
+
+($sql,) = $sql_maker->select(
+          [
+            {
+              'me' => 'cd'
+            },
+            [
+              {
+                'artist' => 'artist',
+                '-join_type' => ''
+              },
+              {
+                'artist.artistid' => 'me.artist'
+              }
+            ]
+          ],
+          [
+            {
+              'count' => '*'
+            }
+          ],
+          {
+            'artist.name' => 'Caterwauler McCrae',
+            'me.year' => 2001
+          },
+          [],
+          undef,
+          undef
+);
+
+is($sql,
+   q/SELECT COUNT( * ) FROM [cd] [me]  JOIN [artist] [artist] ON ( [artist].[artistid] = [me].[artist] ) WHERE ( [artist].[name] = ? AND [me].[year] = ? )/,
+   'got correct SQL for count query with bracket quoting');
+
+
+($sql,@binds) = $sql_maker->update(
+          'group',
+          {
+            'order' => '12',
+            'name' => 'Bill'
+          }
+);
+
+is($sql,
+   q/UPDATE [group] SET [name] = ?, [order] = ?/,
+   'bracket quoted table names for UPDATE');
diff --git a/t/96file_column.pm b/t/96file_column.pm
new file mode 100644 (file)
index 0000000..25d9149
--- /dev/null
@@ -0,0 +1,18 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+use IO::File;
+
+my $schema = DBICTest->init_schema();
+
+plan tests => 2;
+
+
+eval { $schema->resultset('FileColumn')->create({file=>'wrong set'}) };
+ok($@, 'FileColumn checking for checks against bad sets');
+my $fh = new IO::File('t/96file_column.pm','r');
+eval { $schema->resultset('FileColumn')->create({file => {handle => $fh, filename =>'96file_column.pm'}})};
+ok(!$@,'FileColumn checking if file handled properly.');
diff --git a/t/bindtype_columns.t b/t/bindtype_columns.t
new file mode 100644 (file)
index 0000000..a32e24c
--- /dev/null
@@ -0,0 +1,64 @@
+use strict;
+use warnings;  
+
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+
+my ($dsn, $dbuser, $dbpass) = @ENV{map { "DBICTEST_PG_${_}" } qw/DSN USER PASS/};
+
+$dsn   = 'dbi:Pg:dbname=postgres;host=localhost' unless $dsn;
+$dbuser        = 'postgres' unless $dbuser;
+$dbpass        = 'postgres' unless $dbpass;
+
+plan skip_all => 'Set $ENV{DBICTEST_PG_DSN}, _USER and _PASS to run this test'
+  unless ($dsn && $dbuser);
+  
+plan tests => 3;
+
+DBICTest::Schema->compose_connection('PGTest' => $dsn, $dbuser, $dbpass);
+
+my $dbh = PGTest->schema->storage->dbh;
+
+$dbh->do(qq[
+
+       CREATE TABLE artist
+       (
+               artistid                serial  NOT NULL        PRIMARY KEY,
+               media                   bytea   NOT NULL,
+               name                    varchar NULL
+       );
+],{ RaiseError => 1, PrintError => 1 });
+
+
+PGTest::Artist->load_components(qw/ 
+
+       PK::Auto 
+       Core 
+/);
+
+PGTest::Artist->add_columns(
+       
+       "media", { 
+       
+               data_type => "bytea", 
+               is_nullable => 0,
+       },
+);
+
+# test primary key handling
+my $big_long_string    = 'abcd' x 250000;
+
+my $new = PGTest::Artist->create({ media => $big_long_string });
+
+ok($new->artistid, "Created a blob row");
+is($new->media,        $big_long_string, "Set the blob correctly.");
+
+my $rs = PGTest::Artist->find({artistid=>$new->artistid});
+
+is($rs->get_column('media'), $big_long_string, "Created the blob correctly.");
+
+$dbh->do("DROP TABLE artist");
+
+
+
index 71ccaed..8e94bd9 100644 (file)
@@ -16,9 +16,12 @@ BEGIN {
 use lib 't/lib';
 
 use_ok('DBICTest');
-DBICTest->init_schema();
 
-DBICTest::CD->load_components(qw/CDBICompat::Pager/);
+DBICTest::Schema::CD->load_components(qw/CDBICompat CDBICompat::Pager/);
+
+my $schema = DBICTest->init_schema();
+
+#DBICTest::CD->result_source_instance->schema->storage($schema->storage);
 
 my ( $pager, $it ) = DBICTest::CD->page(
     {},
index 97855cb..cb3ae57 100755 (executable)
@@ -55,7 +55,8 @@ sub init_schema {
     my $dbuser = $ENV{"DBICTEST_DBUSER"} || '';
     my $dbpass = $ENV{"DBICTEST_DBPASS"} || '';
 
-    my $schema = DBICTest::Schema->compose_connection('DBICTest' => $dsn, $dbuser, $dbpass);
+    my $schema = DBICTest::Schema->compose_namespace('DBICTest')
+                                 ->connect($dsn, $dbuser, $dbpass);
     $schema->storage->on_connect_do(['PRAGMA synchronous = OFF']);
     if ( !$args{no_deploy} ) {
         __PACKAGE__->deploy_schema( $schema );
@@ -225,8 +226,8 @@ sub populate_schema {
     ]);
 
     $schema->populate('Link', [
-        [ qw/id title/ ],
-        [ 1, 'aaa' ]
+        [ qw/id url title/ ],
+        [ 1, '', 'aaa' ]
     ]);
 
     $schema->populate('Bookmark', [
index f8b2cd9..7ebd040 100644 (file)
@@ -9,6 +9,7 @@ __PACKAGE__->load_classes(qw/
   Artist
   Employee
   CD
+  FileColumn
   Link
   Bookmark
   #dummy
index cf6eb3a..90eb7bf 100644 (file)
@@ -12,7 +12,7 @@ __PACKAGE__->source_info({
 __PACKAGE__->add_columns(
   'artistid' => {
     data_type => 'integer',
-    is_auto_increment => 1
+    is_auto_increment => 1,
   },
   'name' => {
     data_type => 'varchar',
index c4c8a8b..c59bbe5 100644 (file)
@@ -2,7 +2,7 @@ package # hide from PAUSE
     DBICTest::Schema::ArtistSourceName;
 
 use base 'DBICTest::Schema::Artist';
-
+__PACKAGE__->table(__PACKAGE__->table);
 __PACKAGE__->source_name('SourceNameArtists');
 
 1;
index 78b3d16..7beb833 100644 (file)
@@ -19,6 +19,10 @@ __PACKAGE__->add_columns(
         data_type => 'integer',
         is_nullable => 1,
     },
+    group_id_2 => {
+        data_type => 'integer',
+        is_nullable => 1,
+    },
     name => {
         data_type => 'varchar',
         size      => 100,
diff --git a/t/lib/DBICTest/Schema/FileColumn.pm b/t/lib/DBICTest/Schema/FileColumn.pm
new file mode 100644 (file)
index 0000000..22d3a1a
--- /dev/null
@@ -0,0 +1,19 @@
+package 
+DBICTest::Schema::FileColumn;
+
+use strict;
+use warnings;
+use base qw/DBIx::Class::Core/;
+
+__PACKAGE__->load_components(qw/FileColumn/);
+
+__PACKAGE__->table('file_columns');
+
+__PACKAGE__->add_columns(
+  id => { data_type => 'integer', is_auto_increment => 1 },
+  file => { data_type => 'varchar', is_file_column => 1, file_column_path => '/tmp', size=>255 }
+);
+
+__PACKAGE__->set_primary_key('id');
+
+1;
index cdffa2f..a1e23db 100644 (file)
@@ -3,17 +3,17 @@ package # hide from PAUSE
 
 use base 'DBIx::Class::Core';
 
-DBICTest::Schema::FourKeys->table('fourkeys');
-DBICTest::Schema::FourKeys->add_columns(
+__PACKAGE__->table('fourkeys');
+__PACKAGE__->add_columns(
   'foo' => { data_type => 'integer' },
   'bar' => { data_type => 'integer' },
   'hello' => { data_type => 'integer' },
   'goodbye' => { data_type => 'integer' },
   'sensors' => { data_type => 'character' },
 );
-DBICTest::Schema::FourKeys->set_primary_key(qw/foo bar hello goodbye/);
+__PACKAGE__->set_primary_key(qw/foo bar hello goodbye/);
 
-DBICTest::Schema::FourKeys->has_many(
+__PACKAGE__->has_many(
   'fourkeys_to_twokeys', 'DBICTest::Schema::FourKeys_to_TwoKeys', {
     'foreign.f_foo' => 'self.foo',
     'foreign.f_bar' => 'self.bar',
@@ -21,7 +21,7 @@ DBICTest::Schema::FourKeys->has_many(
     'foreign.f_goodbye' => 'self.goodbye',
 });
 
-DBICTest::Schema::FourKeys->many_to_many(
+__PACKAGE__->many_to_many(
   'twokeys', 'fourkeys_to_twokeys', 'twokeys',
 );
 
index 013cf91..0c82588 100644 (file)
@@ -3,8 +3,8 @@ package # hide from PAUSE
 
 use base qw/DBIx::Class::Core/;
 
-DBICTest::Schema::LinerNotes->table('liner_notes');
-DBICTest::Schema::LinerNotes->add_columns(
+__PACKAGE__->table('liner_notes');
+__PACKAGE__->add_columns(
   'liner_id' => {
     data_type => 'integer',
   },
@@ -13,6 +13,9 @@ DBICTest::Schema::LinerNotes->add_columns(
     size      => 100,
   },
 );
-DBICTest::Schema::LinerNotes->set_primary_key('liner_id');
+__PACKAGE__->set_primary_key('liner_id');
+__PACKAGE__->belongs_to(
+  'cd', 'DBICTest::Schema::CD', 'liner_id'
+);
 
 1;
index 1723390..1edda61 100644 (file)
@@ -3,13 +3,13 @@ package # hide from PAUSE
 
 use base 'DBIx::Class::Core';
 
-DBICTest::Schema::NoPrimaryKey->table('noprimarykey');
-DBICTest::Schema::NoPrimaryKey->add_columns(
+__PACKAGE__->table('noprimarykey');
+__PACKAGE__->add_columns(
   'foo' => { data_type => 'integer' },
   'bar' => { data_type => 'integer' },
   'baz' => { data_type => 'integer' },
 );
 
-DBICTest::Schema::NoPrimaryKey->add_unique_constraint(foo_bar => [ qw/foo bar/ ]);
+__PACKAGE__->add_unique_constraint(foo_bar => [ qw/foo bar/ ]);
 
 1;
index 4cc2918..63356ac 100644 (file)
@@ -3,8 +3,8 @@ package # hide from PAUSE
 
 use base 'DBIx::Class::Core';
 
-DBICTest::Schema::OneKey->table('onekey');
-DBICTest::Schema::OneKey->add_columns(
+__PACKAGE__->table('onekey');
+__PACKAGE__->add_columns(
   'id' => {
     data_type => 'integer',
     is_auto_increment => 1,
@@ -16,7 +16,7 @@ DBICTest::Schema::OneKey->add_columns(
     data_type => 'integer',
   },
 );
-DBICTest::Schema::OneKey->set_primary_key('id');
+__PACKAGE__->set_primary_key('id');
 
 
 1;
index 41610da..687dcd1 100644 (file)
@@ -3,11 +3,11 @@ package # hide from PAUSE
 
 use base 'DBIx::Class::Core';
 
-DBICTest::Schema::Serialized->table('serialized');
-DBICTest::Schema::Serialized->add_columns(
+__PACKAGE__->table('serialized');
+__PACKAGE__->add_columns(
   'id' => { data_type => 'integer' },
   'serialized' => { data_type => 'text' },
 );
-DBICTest::Schema::Serialized->set_primary_key('id');
+__PACKAGE__->set_primary_key('id');
 
 1;
diff --git a/t/lib/DBICVersionNew.pm b/t/lib/DBICVersionNew.pm
new file mode 100644 (file)
index 0000000..f92c3a5
--- /dev/null
@@ -0,0 +1,48 @@
+package DBICVersion::Table;
+
+use base 'DBIx::Class';
+use strict;
+use warnings;
+
+__PACKAGE__->load_components(qw/ Core/);
+__PACKAGE__->table('TestVersion');
+
+__PACKAGE__->add_columns
+    ( 'Version' => {
+        'data_type' => 'INTEGER',
+        'is_auto_increment' => 1,
+        'default_value' => undef,
+        'is_foreign_key' => 0,
+        'is_nullable' => 0,
+        'size' => ''
+        },
+      'VersionName' => {
+        'data_type' => 'VARCHAR',
+        'is_auto_increment' => 0,
+        'default_value' => undef,
+        'is_foreign_key' => 0,
+        'is_nullable' => 1,
+        'size' => '20'
+        },
+      );
+
+__PACKAGE__->set_primary_key('Version');
+
+package DBICVersion::Schema;
+use base 'DBIx::Class::Schema';
+use strict;
+use warnings;
+
+our $VERSION = '2.0';
+
+__PACKAGE__->register_class('Table', 'DBICVersion::Table');
+__PACKAGE__->load_components('+DBIx::Class::Schema::Versioned');
+__PACKAGE__->upgrade_directory('t/var/');
+__PACKAGE__->backup_directory('t/var/backup/');
+
+#sub upgrade_directory
+#{
+#    return 't/var/';
+#}
+
+1;
diff --git a/t/lib/DBICVersionOrig.pm b/t/lib/DBICVersionOrig.pm
new file mode 100644 (file)
index 0000000..5a12ce4
--- /dev/null
@@ -0,0 +1,46 @@
+package DBICVersion::Table;
+
+use base 'DBIx::Class';
+use strict;
+use warnings;
+
+__PACKAGE__->load_components(qw/ Core/);
+__PACKAGE__->table('TestVersion');
+
+__PACKAGE__->add_columns
+    ( 'Version' => {
+        'data_type' => 'INTEGER',
+        'is_auto_increment' => 1,
+        'default_value' => undef,
+        'is_foreign_key' => 0,
+        'is_nullable' => 0,
+        'size' => ''
+        },
+      'VersionName' => {
+        'data_type' => 'VARCHAR',
+        'is_auto_increment' => 0,
+        'default_value' => undef,
+        'is_foreign_key' => 0,
+        'is_nullable' => 0,
+        'size' => '10'
+        },
+      );
+
+__PACKAGE__->set_primary_key('Version');
+
+package DBICVersion::Schema;
+use base 'DBIx::Class::Schema';
+use strict;
+use warnings;
+
+our $VERSION = '1.0';
+
+__PACKAGE__->register_class('Table', 'DBICVersion::Table');
+__PACKAGE__->load_components('+DBIx::Class::Schema::Versioned');
+
+sub upgrade_directory
+{
+    return 't/var/';
+}
+
+1;
index 2ce5dad..c9de968 100644 (file)
@@ -11,6 +11,7 @@ CREATE TABLE employee (
   employee_id INTEGER PRIMARY KEY NOT NULL,
   position integer NOT NULL,
   group_id integer,
+  group_id_2 integer,  
   name varchar(100)
 );
 
@@ -128,6 +129,14 @@ CREATE TABLE link (
 );
 
 --
+-- Table: file_columns
+--
+CREATE TABLE file_columns (
+  id INTEGER PRIMARY KEY NOT NULL,
+  file varchar(255)
+);
+
+--
 -- Table: tags
 --
 CREATE TABLE tags (